Updating of the data in the RecyclerView - java

I have FirstscreenActivity, in which I use RecyclerView, (in this RecyclerView displays pictures of the projects which were created by a user), then user goes to the next Activity, where he creates new project and adds pictures there. When user comes back to the FirstScreenActivity, old project downloads one more time, and after that download new project.
How to make that old projects wouldn't download one more time after the changing the Activities (so there wouldn't be duplicates)?
public class FirstscreenActivity extends AppCompatActivity implements RecyclerItemClickListener.OnItemClickListener {
private MyAdapter mAdapter;
private LinearLayoutManager mLayoutManager;
public static String mCurrentProject = null;
RecyclerView list;
static File[] listFile;
static File[] listFolders;
static int newpressed = 0;
public static ArrayList<Folder> FOLDERS = new ArrayList<>();
public static LruCache<String, Bitmap> mMemoryCache;
public static File[] listFile2;
public void getFromSdcardFolders() {
File file = new File(Environment.getExternalStorageDirectory() +
"/Audio_Recorder_Picture", "Previews");
if (file.isDirectory()) {
listFolders = file.listFiles();
for (int i = 0; i < listFolders.length; i++) {
Folder folderobject = new Folder();
folderobject.setName(listFolders[i].getName());
Log.i("List of FOLDERS: ", String.valueOf(listFolders[i].getName()));
File picturelist = new File(Environment.getExternalStorageDirectory() +
"/Audio_Recorder_Picture/Previews", listFolders[i].getName());
if (picturelist.isDirectory()) {
listFile = picturelist.listFiles();
for (int j = 0; j < listFile.length; j++) {
folderobject.addFile(listFile[j].getAbsolutePath());
}
}
FOLDERS.add(folderobject);
Log.wtf("TAG", "Folders size inside the getFRom:" + FOLDERS.size());
}
}
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.front);
Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(myToolbar);
getSupportActionBar().setTitle("");
list = (RecyclerView) findViewById(R.id.list);
list.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getApplicationContext());
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
list.addOnItemTouchListener(new RecyclerItemClickListener(this, this));
getFromSdcardFolders();
list.setLayoutManager(mLayoutManager);
mAdapter = new MyAdapter(this, FOLDERS);
list.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory / 4;
mMemoryCache
= new LruCache<String, Bitmap>(cacheSize) {
#Override
protected int sizeOf(String key, Bitmap bitmap) {
// The cache size will be measured in kilobytes rather than
// number of items.
return bitmap.getByteCount() / 1024;
}
};
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.addItem:
SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_hh_mm_ss");
Date now = new Date();
mCurrentProject = String.valueOf(formatter.format(now));
Log.d("newpressed: ", String.valueOf(newpressed));
Intent nextScreen = new Intent(getApplicationContext(), AudioRecord.class);
startActivity(nextScreen);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onItemClick(View childView, int position) {
File picturelist2 = new File(Environment.getExternalStorageDirectory() +
"/Audio_Recorder_Picture/Pictures", listFolders[position].getName());
if (picturelist2.isDirectory()) {
listFile2 = picturelist2.listFiles();
for (int i = 0; i < listFile2.length; i++) {
Log.i("LIST OF PICTURES: ", String.valueOf(listFile2[i]));
}
}
Intent viewScreen = new Intent(getApplicationContext(), ViewActivity.class);
viewScreen.putExtra("FILE_TAG", listFile2);
startActivity(viewScreen);
}
#Override
public void onItemLongPress(View childView, int position) {
}
}
Code of the adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>` {
public final Activity context;
public final ArrayList<Folder> FOLDERS;
View view;
public long getItemId(int position) {
return position;
}
#Override
public int getItemCount() {
Log.wtf("TAG", "Folders size: " + FOLDERS.size());
return FOLDERS.size();
}
// optimisation of bitmap
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(String path,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
public void loadBitmap(String path, ImageView imageView, int position) {
final String imageKey = String.valueOf(path);
Bitmap bitmap = getBitmapFromMemCache(imageKey);
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
bitmap = decodeSampledBitmapFromResource(path, 100, 100);
imageView.setImageBitmap(bitmap);
// BitmapWorkerTask task = new BitmapWorkerTask(imageView, position);
// task.execute(path);
}
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public TextView title;
public ImageView image1;
ImageView image2;
ImageView image3;
ImageView image4;
ImageView image5;
TextView slides;
public ViewHolder(View v) {
super(v);
title = (TextView) v.findViewById(R.id.item);
image1 = (ImageView) v.findViewById(R.id.icon1);
image2 = (ImageView) v.findViewById(R.id.icon2);
image3 = (ImageView) v.findViewById(R.id.icon3);
image4 = (ImageView) v.findViewById(R.id.icon4);
image5 = (ImageView) v.findViewById(R.id.icon5);
slides = (TextView) v.findViewById(R.id.textView1);
}
}
public MyAdapter(Activity context, ArrayList<Folder> FOLDERS) {
this.context = context;
this.FOLDERS = FOLDERS;
getItemCount();
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
Log.wtf("TAG", "OnCreateViewHolder works!!!");
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.mylist, parent, false);
ViewHolder vh = new ViewHolder(view);
return vh;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Folder folder = FOLDERS.get(position);
holder.image1.setImageResource(R.drawable.placeholder);
holder.image2.setImageResource(R.drawable.placeholder);
holder.image3.setImageResource(R.drawable.placeholder);
holder.image4.setImageResource(R.drawable.placeholder);
holder.image5.setImageResource(R.drawable.placeholder);
ArrayList<String> imgs = folder.getPicturelist();
holder.title.setText(folder.getName());
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
options.inSampleSize = 10;
for (int i = 0; i < 5; i++) {
switch (i) {
case 0:
if (imgs.size() > i && imgs.size() != 0) {
loadBitmap(imgs.get(i), holder.image1, position);
} else {
holder.image1.setImageBitmap(null);
// holder.image1.setImageResource(R.drawable.placeholder);
}
break;
case 1:
if (imgs.size() > i && imgs.size() != 0) {
loadBitmap(imgs.get(i), holder.image2, position);
} else {
holder.image2.setImageBitmap(null);
// holder.image2.setImageResource(R.drawable.placeholder);
}
break;
case 2:
if (imgs.size() > i && imgs.size() != 0) {
loadBitmap(imgs.get(i), holder.image3, position);
} else {
holder.image3.setImageBitmap(null);
// holder.image3.setImageResource(R.drawable.placeholder);
}
break;
case 3:
if (imgs.size() > i && imgs.size() != 0) {
loadBitmap(imgs.get(i), holder.image4, position);
} else {
holder.image4.setImageBitmap(null);
// holder.image4.setImageResource(R.drawable.placeholder);
}
break;
case 4:
if (imgs.size() > i && imgs.size() != 0) {
loadBitmap(imgs.get(i), holder.image5, position);
} else {
holder.image5.setImageBitmap(null);
// holder.image5.setImageResource(R.drawable.placeholder);
}
break;
}
}
holder.slides.setText("Количество слайдов: " + imgs.size());
view.setTag(holder);
}
public Bitmap getBitmapFromMemCache(String key) {
return com.example.attracti.audiorecorderpicture.FirstscreenActivity.mMemoryCache.get(key);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myproject">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.camera" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.Light.NoActionBar"
android:name=".model.App"
>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<activity android:name=".activities.AudioRecord"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden">
</activity>
<activity android:name=".activities.FirstscreenActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".activities.ViewActivity">
</activity>
</application>
</manifest>

Solution
If you are going back to first activity with intent, it will create the activity again, as expected. To prevent this, you can add this to manifest:
<activity android:name=".activities.FirstscreenActivity"
android:launchMode= "singleInstance"
...
singleInstance will create activity only once.
Solution
Use finish() when you want to go back.

Related

SearchView widget with GridView. I type in the search field, but it doeasn't refresh the GridView

I'm new to coding. I'm trying to implement a SearchView Widget that should update a GridView, but it doesn't work. When I type something in the search field nothing happens. Nothing happens if I tap on the search button neither. Could you please help me?
This is the MainActivity:
public class MainActivity extends AppCompatActivity {
private static Context mainContext;
private FragmentDataSaver mDataSaver;
private static final String DATA_SAVER_TAG = "DATA_SAVER";
private View mDecorView;
public ArrayList<Movies> mMovies;
WallAdapter wallAdapter;
GridView gridView;
public static Context getContext(){
return mainContext;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDecorView = getWindow().getDecorView();
mainContext = getApplicationContext();
setContentView(R.layout.activity_main);
Toolbar myToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(myToolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
FragmentManager fm = getSupportFragmentManager();
mDataSaver = (FragmentDataSaver)fm.findFragmentByTag(DATA_SAVER_TAG);
if(mDataSaver == null){
mDataSaver = new FragmentDataSaver();
fm.beginTransaction().add(mDataSaver, DATA_SAVER_TAG).commit();
mMovies = DatabaseProva.creaDatabaseProva();
mDataSaver.setData(mMovies);
} else {
mMovies = mDataSaver.getData();
}
gridView = (GridView)findViewById(R.id.gridview_layout);
/*if(savedInstanceState == null){
mMovies = DatabaseProva.creaDatabaseProva();
} else {
mMovies = savedInstanceState.getParcelableArrayList("tempMovies");
}*/
wallAdapter = new WallAdapter(this, mMovies);
gridView.setAdapter(wallAdapter);
handleIntent(getIntent());
}
#Override
protected void onNewIntent(Intent intent) {
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
//use the query to search your data somehow
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.toolbar_menu, menu);
MenuItem searchMenu = menu.findItem(R.id.search_view);
// Get the SearchView and set the searchable configuration
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
android.widget.SearchView searchView = (android.widget.SearchView) searchMenu.getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default
searchView.setOnQueryTextListener(new android.widget.SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
wallAdapter.getFilter().filter(newText);
return false;
}
});
return super.onCreateOptionsMenu(menu);
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(hasFocus){
mDecorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
/*#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList("tempMovies", wallAdapter.getItems());
}*/
The adapter (WallAdapter):
public class WallAdapter extends ArrayAdapter<Movies> implements Filterable{
private ArrayList<Movies> tempMovies = new ArrayList<Movies>();
public WallAdapter(Context context, ArrayList movies) {
super(context, 0, movies);
setItems(movies);
}
public ArrayList<Movies> getMovies() {
return tempMovies;
}
public void setItems(ArrayList<Movies> movies) {
this.tempMovies = movies;
}
public ArrayList<Movies> getItems() {
return tempMovies;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_layout, parent, false);
holder = new ViewHolder();
holder.mImage = (ImageView) convertView.findViewById(R.id.item_view);
holder.mImage.setScaleType(ImageView.ScaleType.CENTER_CROP);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final Movies currentMovie = getItem(position);
holder.mImage.setImageBitmap(currentMovie.getImage());
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getContext(), SchedaFilm.class);
intent.putExtra("titolo", currentMovie.getTitolo());
intent.putExtra("locandina", currentMovie.getIdLocandina());
intent.putExtra("trama", currentMovie.getTrama());
intent.putExtra("regia", currentMovie.getRegia());
intent.putExtra("anno", currentMovie.getAnno());
intent.putExtra("genere", currentMovie.getGenere());
getContext().startActivity(intent);
}
});
return convertView;
}
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
ArrayList<Movies> tempList = new ArrayList<>();
//constraint is the result from text you want to filter against.
//objects is your data set you will filter from
if(constraint != null || constraint.length() == 0) {
// No filter implemented we return all the list
filterResults.values = tempMovies;
filterResults.count = tempMovies.size();
} else {
for(Movies m : tempMovies){
if(m.toString().toLowerCase().contains(constraint.toString().toLowerCase())){
tempList.add(m);
}
}
filterResults.values = tempList;
filterResults.count = tempList.size();
}
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if(results.count == 0){
notifyDataSetInvalidated();
} else {
tempMovies = (ArrayList<Movies>) results.values;
notifyDataSetChanged();
}
}
};
#NonNull
#Override
public Filter getFilter() {
return filter;
}
static class ViewHolder{
private ImageView mImage;
public Context getContext(){
return mImage.getContext();
}
}
My manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest package="arca.mitty.com.arcagridview"
xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.Light.NoActionBar">
<activity android:name=".MainActivity"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.SEARCH" />
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".SchedaFilm"
android:parentActivityName=".MainActivity">
</activity>
</application>
</manifest>
The Searchable xml file:
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/app_label"
android:hint="#string/search_hint" >
</searchable>
This is the Movie class:
public class Movies implements Parcelable{
private String mTitolo;
private String mGenere;
private Bitmap mLocandina;
private Bitmap mLocandinaBig;
private int mAnno;
private int mIdLocandina;
private String mTrama = "Seduto sulla panchina ad un bus-stop di Savannah, " +
"Forrest Gump ricorda la sua infanzia di bimbo con problemi mentali e fisici. " +
"Solo la mamma lo accetta per quello che è, e solo la piccola Jenny Curran lo fa sedere accanto a sé sull'autobus della scuola. " +
"Sarà lei a incitarlo, per fuggire a tre compagnetti violenti, a correre, liberando così le gambe dalla protesi. " +
"Attraverso trent'anni di storia americana vista con gli occhi della semplicità e dell'innocenza, Forrest diventa un campione universitario di football, " +
"mentre è sempre più innamorato di Jenny che però lo considera un fratello. Assiste ai disordini razziali in Alabama ed incontra Kennedy poco prima dell'assassinio. " +
"Si arruola quindi nell'esercito, dove fa amicizia con il nero Bubba, un pescatore di gamberi che gli comunica la sua passione. " +
"Dopo un fugace incontro con Jenny che canta a Memphis, Gump va a combattere in Vietnam.";
private String mRegia = "Bino Cicogna";
//Constructor
public Movies (String titolo, String genere, int locandina, int anno){
mTitolo = titolo;
mGenere = genere;
mIdLocandina = locandina;
mLocandina = decodeSampledBitmapFromResource(MainActivity.getContext().getResources(), locandina, 90, 135);
mAnno = anno;
}
protected Movies(Parcel in) {
mTitolo = in.readString();
mGenere = in.readString();
mLocandina = in.readParcelable(Bitmap.class.getClassLoader());
mAnno = in.readInt();
}
public static final Creator<Movies> CREATOR = new Creator<Movies>() {
#Override
public Movies createFromParcel(Parcel in) {
return new Movies(in);
}
#Override
public Movies[] newArray(int size) {
return new Movies[size];
}
};
public String getTitolo() {
return mTitolo;
}
public String getGenere() {
return mGenere;
}
public int getIdLocandina(){
return mIdLocandina;
}
public Bitmap getImage() {
return mLocandina;
}
public int getAnno() {
return mAnno;
}
public String getTrama(){
return mTrama;
}
public String getRegia(){
return mRegia;
}
public String toString(){
String s = "";
s = getTitolo() + " " + getGenere() + " " + getRegia() + " " + getAnno();
return s;
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mTitolo);
dest.writeString(mGenere);
dest.writeParcelable(mLocandina, flags);
dest.writeInt(mAnno);
}
}
In your filter, you are doing this:
if (m.toString().toLowerCase().contains(constraint.toString().toLowerCase())) {
tempList.add(m);
}
Make sure m.toString() returns value that actually contains movie's name, if it doesn't that condition will always be false and tempList empty, and next code will be executed:
if (results.count == 0) {
notifyDataSetInvalidated();
}
Ok, after a lot of attempts, I've found the solution.
There was, obviously, a logic error: in the "filter" I was updating the wrong ArrayList of movies. The one that the adapter uses for building up the GridView in my app is "tempMovies" ArrayList.
In the "filter" I was using "tempList" and then updating "filterResults", but never updating "tempMovies". Even in the "getFilter" method.
Furthermore, I've found an easier to understand and to apply "filter" method. I'm using it and it works perfectly.
Here you are the code:
public void filter(CharSequence text){
String query = text.toString().toLowerCase();
tempMovies.clear();
if(text.length() == 0){
tempMovies.addAll(originalMoviesList);
} else{
for(Movies m : originalMoviesList){
if(m.toString().toLowerCase().contains(query)){
tempMovies.add(m);
}
}
}
notifyDataSetChanged();
}
I found it at this site:
http://www.androidbegin.com/tutorial/android-search-listview-using-filter/
In the end, thank you again to all of you who tried to help. I hope my experience will be usefull to others.

How do I implement drag and drop in my game?

I have been looking all over SOF and online tutorials, but for some reason I still can't get it to work. I want to implement a drag and drop functionality in my game. Here is the activity:
I want to be able to drag and drop the 4 shapes in the bottom. If the correct shape fits, I want the shape with the "?" to change into the correct shape. Can someone show me how I can do this?
Here is my code:
public class SecondActivity extends AppCompatActivity {
int n;
ImageView shape1, shape2, shape3, shape4, guessShape;
ImageButton exit;
private android.widget.RelativeLayout.LayoutParams layoutParams;
Random rand = new Random();
ImageView[] shapes = new ImageView[4];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
//declare each imageview
shape1 = (ImageView) findViewById(R.id.shape1);
shape2 = (ImageView) findViewById(R.id.shape2);
shape3 = (ImageView) findViewById(R.id.shape3);
shape4 = (ImageView) findViewById(R.id.shape4);
guessShape = (ImageView) findViewById(R.id.guessShape);
exit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
System.exit(0);
}
});
//add each imageView to the shapes[] array
shapes[0] = shape1;
shapes[1] = shape2;
shapes[2] = shape3;
shapes[3] = shape4;
//store all the shapes in an array
int[] images = new int[]{R.drawable.img_0, R.drawable.img_1, R.drawable.img_2, R.drawable.img_3, R.drawable.img_4,
R.drawable.img_5, R.drawable.img_6, R.drawable.img_7, R.drawable.img_8, R.drawable.img_9, R.drawable.img_10,
R.drawable.img_11, R.drawable.img_12, R.drawable.img_13, R.drawable.img_14, R.drawable.img_15, R.drawable.img_16,
R.drawable.img_17};
//store all the guessShapes in an array
int[] outlines = new int[]{R.drawable.outline_0, R.drawable.outline_1, R.drawable.outline_2,
R.drawable.outline_3, R.drawable.outline_4, R.drawable.outline_5, R.drawable.outline_6,
R.drawable.outline_7, R.drawable.outline_8, R.drawable.outline_9, R.drawable.outline_10,
R.drawable.outline_11, R.drawable.outline_12, R.drawable.outline_13, R.drawable.outline_14,
R.drawable.outline_15, R.drawable.outline_16, R.drawable.outline_17};
//generate 4 random images from the array's and ensure that they don't match each other
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 18; i++) {
list.add(new Integer(i));
}
Collections.shuffle(list);
int whichImg = (int) Math.round((Math.random() * 4));
int img1 = list.get(0);
int img2 = list.get(1);
int img3 = list.get(2);
int img4 = list.get(3);
if (whichImg == 1) {
whichImg = img1;
} else if (whichImg == 2) {
whichImg = img2;
} else if (whichImg == 3) {
whichImg = img3;
} else {
whichImg = img4;
}
int outlineID = outlines[whichImg];
//set the shape in each imageview
guessShape.setBackgroundResource(outlineID);
shape1.setBackgroundResource(images[img1]);
shape2.setBackgroundResource(images[img2]);
shape3.setBackgroundResource(images[img3]);
shape4.setBackgroundResource(images[img4]);
//ensures that 1/4 shape has the guess shape correspondence
final Object currentBackground = guessShape.getBackground().getConstantState();
//for loop to have the guess shape and 1/4 shapes to match
for (int i = 0; i < 18; i++) {
if (currentBackground.equals(getResourceID("outline_" + i, "drawable", getApplicationContext()))) {
int random = new Random().nextInt(shapes.length);
shapes[random].setBackgroundResource(getResourceID("img_" + i, "drawable", getApplicationContext()));
}
//set tags for each view
guessShape.setTag("gShape");
shape1.setTag("S_1");
shape2.setTag("S_2");
shape3.setTag("S_3");
shape4.setTag("S_4");
}
}
//method to get the ID of an image in drawable folder
protected final static int getResourceID(final String resName, final String resType, final Context ctx)
{
final int ResourceID =
ctx.getResources().getIdentifier(resName, resType,
ctx.getApplicationInfo().packageName);
if (ResourceID == 0)
{
throw new IllegalArgumentException
(
"No resource string found with name " + resName
);
}
else
{
return ResourceID;
}
}
}
Although you were not clear enough.
Try this, First make a class that implements onTouchListener
private final class MyTouchListener implements OnTouchListener {
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
ClipData data = ClipData.newPlainText("", "");
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(
view);
view.startDrag(data, shadowBuilder, view, 0);
view.setVisibility(View.INVISIBLE);
return true;
} else {
return false;
}
}
}
Then define a drag listener
class MyDragListener implements OnDragListener {
Drawable enterShape = getResources().getDrawable(
R.drawable.shape_droptarget);
Drawable normalShape = getResources().getDrawable(R.drawable.shape);
#Override
public boolean onDrag(View v, DragEvent event) {
int action = event.getAction();
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
// do nothing
break;
case DragEvent.ACTION_DRAG_ENTERED:
v.setBackgroundDrawable(enterShape);
break;
case DragEvent.ACTION_DRAG_EXITED:
v.setBackgroundDrawable(normalShape);
break;
case DragEvent.ACTION_DROP:
// Dropped, reassign View to ViewGroup
View view = (View) event.getLocalState();
ViewGroup owner = (ViewGroup) view.getParent();
owner.removeView(view);
LinearLayout container = (LinearLayout) v;
container.addView(view);
view.setVisibility(View.VISIBLE);
break;
case DragEvent.ACTION_DRAG_ENDED:
v.setBackgroundDrawable(normalShape);
default:
break;
}
return true;
}
}
Now simply use these lines
findViewById(R.id.myimage1).setOnTouchListener(new MyTouchListener());
and
findViewById(R.id.bottomleft).setOnDragListener(new MyDragListener());
Here are some tutorials that might help you
Tutorialpoint
Link 2

Installation error: INSTALL_FAILED_OLDER_SDK in eclipse

I have an unexpe`ted problem with my Android project. I have a real android device with ice_cream sandwich installed. My app was working fine during the development but after I added a class to the project, I got an error:
Installation error: INSTALL_FAILED_OLDER_SDK
The problem is that everything is good in the manifest file. The minSdkversion is 8.
Here is my manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="zabolotnii.pavel.timer"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18 " />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="zabolotnii.pavel.timer.TimerActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I don't know, if there is any need to attach the new class ,but I didn't any changes to other code that should led to this error:
package zabolotnii.pavel.timer;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.*;
import android.widget.*;
import java.io.File;
import java.io.FilenameFilter;
import java.util.*;
public class OpenFileDialog extends AlertDialog.Builder {
private String currentPath = Environment.getExternalStorageDirectory().getPath();
private List<File> files = new ArrayList<File>();
private TextView title;
private ListView listView;
private FilenameFilter filenameFilter;
private int selectedIndex = -1;
private OpenDialogListener listener;
private Drawable folderIcon;
private Drawable fileIcon;
private String accessDeniedMessage;
public interface OpenDialogListener {
public void OnSelectedFile(String fileName);
}
private class FileAdapter extends ArrayAdapter<File> {
public FileAdapter(Context context, List<File> files) {
super(context, android.R.layout.simple_list_item_1, files);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView view = (TextView) super.getView(position, convertView, parent);
File file = getItem(position);
if (view != null) {
view.setText(file.getName());
if (file.isDirectory()) {
setDrawable(view, folderIcon);
} else {
setDrawable(view, fileIcon);
if (selectedIndex == position)
view.setBackgroundColor(getContext().getResources().getColor(android.R.color.holo_blue_dark));
else
view.setBackgroundColor(getContext().getResources().getColor(android.R.color.transparent));
}
}
return view;
}
private void setDrawable(TextView view, Drawable drawable) {
if (view != null) {
if (drawable != null) {
drawable.setBounds(0, 0, 60, 60);
view.setCompoundDrawables(drawable, null, null, null);
} else {
view.setCompoundDrawables(null, null, null, null);
}
}
}
}
public OpenFileDialog(Context context) {
super(context);
title = createTitle(context);
changeTitle();
LinearLayout linearLayout = createMainLayout(context);
linearLayout.addView(createBackItem(context));
listView = createListView(context);
linearLayout.addView(listView);
setCustomTitle(title).setView(linearLayout)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (selectedIndex > -1 && listener != null) {
listener.OnSelectedFile(listView.getItemAtPosition(selectedIndex).toString());
}
}
}).setNegativeButton(android.R.string.cancel, null);
}
#Override
public AlertDialog show() {
files.addAll(getFiles(currentPath));
listView.setAdapter(new FileAdapter(getContext(), files));
return super.show();
}
public OpenFileDialog setFilter(final String filter) {
filenameFilter = new FilenameFilter() {
#Override
public boolean accept(File file, String fileName) {
File tempFile = new File(String.format("%s/%s", file.getPath(), fileName));
if (tempFile.isFile())
return tempFile.getName().matches(filter);
return true;
}
};
return this;
}
public OpenFileDialog setOpenDialogListener(OpenDialogListener listener) {
this.listener = listener;
return this;
}
public OpenFileDialog setFolderIcon(Drawable drawable) {
this.folderIcon = drawable;
return this;
}
public OpenFileDialog setFileIcon(Drawable drawable) {
this.fileIcon = drawable;
return this;
}
public OpenFileDialog setAccessDeniedMessage(String message) {
this.accessDeniedMessage = message;
return this;
}
private static Display getDefaultDisplay(Context context) {
return ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
}
private static Point getScreenSize(Context context) {
Point screeSize = new Point();
getDefaultDisplay(context).getSize(screeSize);
return screeSize;
}
private static int getLinearLayoutMinHeight(Context context) {
return getScreenSize(context).y;
}
private LinearLayout createMainLayout(Context context) {
LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setMinimumHeight(getLinearLayoutMinHeight(context));
return linearLayout;
}
private int getItemHeight(Context context) {
TypedValue value = new TypedValue();
DisplayMetrics metrics = new DisplayMetrics();
context.getTheme().resolveAttribute(android.R.attr.listPreferredItemHeightSmall, value, true);
getDefaultDisplay(context).getMetrics(metrics);
return (int) TypedValue.complexToDimension(value.data, metrics);
}
private TextView createTextView(Context context, int style) {
TextView textView = new TextView(context);
textView.setTextAppearance(context, style);
int itemHeight = getItemHeight(context);
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, itemHeight));
textView.setMinHeight(itemHeight);
textView.setGravity(Gravity.CENTER_VERTICAL);
textView.setPadding(15, 0, 0, 0);
return textView;
}
private TextView createTitle(Context context) {
TextView textView = createTextView(context, android.R.style.TextAppearance_DeviceDefault_DialogWindowTitle);
return textView;
}
private TextView createBackItem(Context context) {
TextView textView = createTextView(context, android.R.style.TextAppearance_DeviceDefault_Small);
Drawable drawable = getContext().getResources().getDrawable(android.R.drawable.ic_menu_directions);
drawable.setBounds(0, 0, 60, 60);
textView.setCompoundDrawables(drawable, null, null, null);
textView.setLayoutParams(
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
File file = new File(currentPath);
File parentDirectory = file.getParentFile();
if (parentDirectory != null) {
currentPath = parentDirectory.getPath();
RebuildFiles(((FileAdapter) listView.getAdapter()));
}
}
});
return textView;
}
public int getTextWidth(String text, Paint paint) {
Rect bounds = new Rect();
paint.getTextBounds(text, 0, text.length(), bounds);
return bounds.left + bounds.width() + 80;
}
private void changeTitle() {
String titleText = currentPath;
int screenWidth = getScreenSize(getContext()).x;
int maxWidth = (int) (screenWidth * 0.99);
if (getTextWidth(titleText, title.getPaint()) > maxWidth) {
while (getTextWidth("..." + titleText, title.getPaint()) > maxWidth) {
int start = titleText.indexOf("/", 2);
if (start > 0)
titleText = titleText.substring(start);
else
titleText = titleText.substring(2);
}
title.setText("..." + titleText);
} else {
title.setText(titleText);
}
}
private List<File> getFiles(String directoryPath) {
File directory = new File(directoryPath);
List<File> fileList = Arrays.asList(directory.listFiles(filenameFilter));
Collections.sort(fileList, new Comparator<File>() {
#Override
public int compare(File file, File file2) {
if (file.isDirectory() && file2.isFile())
return -1;
else if (file.isFile() && file2.isDirectory())
return 1;
else
return file.getPath().compareTo(file2.getPath());
}
});
return fileList;
}
private void RebuildFiles(ArrayAdapter<File> adapter) {
try {
List<File> fileList = getFiles(currentPath);
files.clear();
selectedIndex = -1;
files.addAll(fileList);
adapter.notifyDataSetChanged();
changeTitle();
} catch (NullPointerException e) {
String message = getContext().getResources().getString(android.R.string.unknownName);
if (!accessDeniedMessage.equals(""))
message = accessDeniedMessage;
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
}
}
private ListView createListView(Context context) {
ListView listView = new ListView(context);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int index, long l) {
final ArrayAdapter<File> adapter = (FileAdapter) adapterView.getAdapter();
File file = adapter.getItem(index);
if (file.isDirectory()) {
currentPath = file.getPath();
RebuildFiles(adapter);
} else {
if (index != selectedIndex)
selectedIndex = index;
else
selectedIndex = -1;
adapter.notifyDataSetChanged();
}
}
});
return listView;
}
}
Remove the space from your targetSdkVersion value. Change
android:targetSdkVersion="18 "
to
android:targetSdkVersion="18"
The app installer has different logic (source) for versions given as strings such as "18 " as opposed to versions given as integers such as "18". You really need the value to be there as an integer.

Outof memeory when display images in gridview

I have an activity which contains a gridview which is used to display the images by camera or gallery, however I found that it may cause OutOfMemory exception sometimes, this is the code codes, I am not sure what's the problem?
public class WaterPointSubmitActivity extends Activity {
private final int DIALOG_TYPE_IMAGE = 11;
private final int Result_Code_Camera = 11;
private final int Result_Code_Local = 12;
private final int Dialog_Source_Value_TakePhoto = 0; // the index in the array.xml
private final int Dialog_Source_value_Local = 1;
private ArrayList<String> mGridViewImages = new ArrayList<String>();
private GridView mGridView;
private ImageAdapter mGridViewAdapter;
private ImageView mImageAddButton;
private Uri mPhotoToBeUploadURI;
private AsyncHttpClient mAsyncHttpClient = Helper.getAsyncHttpClient();
private RequestHandle mCurrentRequset;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_point_submit);
this.setupViews();
}
private void setupViews() {
mGridView = (GridView) findViewById(R.id.images_grid_view);
mGridViewAdapter = new ImageAdapter(this, R.layout.common_expose_image_item, mGridViewImages);
mGridView.setAdapter(mGridViewAdapter);
//trigger the image choose dialog
mImageAddButton = (ImageView) findViewById(R.id.pollution_add_image);
mImageAddButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showDialog(DIALOG_TYPE_IMAGE);
}
});
}
#Override
protected Dialog onCreateDialog(int id) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
switch (id) {
case DIALOG_TYPE_IMAGE:
builder.setTitle(getString(R.string.dialog_choose_photo)).setItems(R.array.point_image_source, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case Dialog_Source_Value_TakePhoto:
//get image by camera
mPhotoToBeUploadURI = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoToBeUploadURI);
startActivityForResult(cameraIntent, Result_Code_Camera);
break;
case Dialog_Source_value_Local:
//from gallery
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, Result_Code_Local);
break;
}
}
});
Dialog target = builder.create();
target.setCanceledOnTouchOutside(false);
return target;
}
return null;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
if (resultCode == RESULT_OK) {
String imageFile = null;
switch (requestCode) {
case Result_Code_Camera:
String[] projection = {
MediaStore.MediaColumns._ID,
MediaStore.Images.ImageColumns.ORIENTATION,
MediaStore.Images.Media.DATA
};
Cursor c = getContentResolver().query(mPhotoToBeUploadURI, projection, null, null, null);
c.moveToFirst();
imageFile = c.getString(c.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
break;
case Result_Code_Local:
Uri selectedImage = imageReturnedIntent.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imageFile = cursor.getString(columnIndex);
cursor.close();
break;
}
mGridViewImages.add(imageFile);
mGridViewAdapter.notifyDataSetChanged();
}
}
class ImageAdapter extends ArrayAdapter<String> {
private int mResourceId;
public ImageAdapter(Context context, int resource, List<String> items) {
super(context, resource, items);
mResourceId = resource;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null || convertView.getTag() == null) {
convertView = getLayoutInflater().inflate(mResourceId, parent, false);
holder = new ViewHolder();
holder.pointImage = (ImageView) convertView.findViewById(R.id.pollution_image);
holder.pointDeleteImage = convertView.findViewById(R.id.pollution_image_delete);
convertView.setTag(holder);
holder.pointDeleteImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
deleteImage(position);
}
});
} else {
holder = (ViewHolder) convertView.getTag();
}
String filePath = getItem(position);
if (filePath != null) {
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
holder.pointImage.setImageBitmap(bitmap);
}
return convertView;
}
}
private void deleteImage(int position) {
mGridViewImages.remove(position);
mGridViewAdapter.notifyDataSetChanged();
}
static class ViewHolder {
ImageView pointImage;
View pointDeleteImage;
}
}
What's the problem?
your view is loading full sized bitmaps causing OOM use BitmapFactory options to scale the bitmap before it is loaded into memory
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(selectedImagePath, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
options.inSampleSize = calculateInSampleSize(options,320,480);
options.inJustDecodeBounds = false;
Bitmap photo = BitmapFactory.decodeFile(selectedImagePath,options);
Helper Method
public int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// Choose the smallest ratio as inSampleSize value, this will guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
You just need to add this line to your manifest file....It will allocate the large memory for your application..
android:largeHeap="true"

Universal image loader imageview doesn't update itself with spinner

I'm using UIL to load thrumbs in a listview.
here is the imageview and the spinner in the cell layout :
<ImageView
android:id="#+id/imgAlbum"
android:layout_width="48dip"
android:layout_height="48dip"
android:layout_gravity="center|left"
android:scaleType="centerCrop"
android:visibility="gone" />
<ProgressBar
android:id="#+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
The list :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background"
android:orientation="vertical" >
<ListView
android:id="#+id/list_restaurant"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="4dp" >
</ListView>
</LinearLayout>
I config the loader like that :
public void setImageLoader(ImageLoader imageLoader, Context context) {
File cacheDir = StorageUtils.getCacheDirectory(context);
ImageLoaderConfiguration _config;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
_config = new ImageLoaderConfiguration.Builder(context).memoryCacheExtraOptions(0, 0).discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75).taskExecutor(null)
.taskExecutorForCachedImages(null).threadPoolSize(3) // default
.threadPriority(Thread.NORM_PRIORITY - 1) // default
.tasksProcessingOrder(QueueProcessingType.FIFO) // default
.denyCacheImageMultipleSizesInMemory().memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024)) // default
.memoryCacheSize(2 * 1024 * 1024).discCache(new UnlimitedDiscCache(cacheDir)) // default
.discCacheSize(50 * 1024 * 1024).discCacheFileCount(100).discCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default
.imageDownloader(new BaseImageDownloader(context)) // default
.defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
.enableLogging().build();
}
else {
_config = new ImageLoaderConfiguration.Builder(context).memoryCacheExtraOptions(0, 0)
// default/screendimensions
.discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75).taskExecutor(AsyncTask.THREAD_POOL_EXECUTOR).taskExecutorForCachedImages(AsyncTask.THREAD_POOL_EXECUTOR)
.threadPoolSize(3) // default
.threadPriority(Thread.NORM_PRIORITY - 1) // default
.tasksProcessingOrder(QueueProcessingType.FIFO) // default
.denyCacheImageMultipleSizesInMemory().memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024)) // default
.memoryCacheSize(2 * 1024 * 1024).discCache(new UnlimitedDiscCache(cacheDir)) // default
.discCacheSize(50 * 1024 * 1024).discCacheFileCount(100).discCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default
.imageDownloader(new BaseImageDownloader(context)) // default
.defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
.enableLogging().build();
}
if (!imageLoader.isInited()) {
imageLoader.init(_config);
}
}
And in the baseadapter i use it like that :
private ImageLoader _imageLoader;
private DisplayImageOptions _options;
in the constructor
this._imageLoader = ImageLoader.getInstance();
this._options = new DisplayImageOptions.Builder().showImageForEmptyUri(R.drawable.error).showImageOnFail(R.drawable.error).cacheInMemory().cacheOnDisc().bitmapConfig(Bitmap.Config.RGB_565)
.build();
Utils utils = new Utils();
utils.setImageLoader(_imageLoader, _activity);
In the GetView() :
final ProgressBar spinner = (ProgressBar) convertView.findViewById(R.id.loading);
_imageLoader.displayImage(etablissement.getImgThumb(), cellHolder.imageIcon, _options, new SimpleImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
view.setVisibility(View.GONE);
spinner.setVisibility(View.VISIBLE);
spinner.invalidate();
view.invalidate();
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
String message = null;
switch (failReason.getType()) {
case IO_ERROR:
message = "Input/Output error";
break;
case DECODING_ERROR:
message = "Image can't be decoded";
break;
case NETWORK_DENIED:
message = "Downloads are denied";
break;
case OUT_OF_MEMORY:
message = "Out Of Memory error";
break;
case UNKNOWN:
message = "Unknown error";
break;
}
view.setVisibility(View.VISIBLE);
spinner.setVisibility(View.GONE);spinner.invalidate();
view.invalidate();
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
view.setVisibility(View.VISIBLE);
spinner.setVisibility(View.GONE);
spinner.invalidate();
view.invalidate();
}
});
Everything works fine BUT the spinner stay instead of the imageview until you scroll the list the redraw the cells.. The imageview should refresh itself when the image is downloaded/got from cache or invalidate()
Here the list loading stay like that : http://imagik.fr/view-rl/45673
Here when i scroll down the imageview refresh : http://imagik.fr/view-rl/45674
Here when i re-scoll up the imageview refresh : http://imagik.fr/view-rl/45675
Any idea ??
EDIT:
The full adapter code (with the UIL part inside) :
public class AdapterDirectories extends BaseAdapter {
/**
* PRIVATE ATTRIBUTES
*/
// LOG
private static final String TAG = AdapterDirectories.class.getSimpleName();
// IHM
private static LayoutInflater _inflater = null;
private Activity _activity;
// DATA
private DataManager _dataManager;
private ImageLoader _imageLoader;
private DisplayImageOptions _options;
private int _section;
private float _latitude;
private float _longitude;
private List<Contact> _listContacts = new ArrayList<Contact>();
private List<Favoris> _listFavoris = new ArrayList<Favoris>();
public AdapterDirectories(Activity activity, boolean favoris, float latitude, float longitude, int section) {
this._activity = activity;
this._latitude = latitude;
this._longitude = longitude;
this._section = section;
//
ContactRepository contactRep = null;
//
if (favoris == false) {
_listContacts = EtablissementApplication._dataManager.get_listOfContacts(_section, _activity);
}
else {
// FAVORITE
this._listFavoris = EtablissementApplication._dataManager.get_listOfFavoris();
// DATA
contactRep = new ContactRepository(_activity);
contactRep.Open();
for (Favoris unFavoris : _listFavoris) {
_listContacts.add(contactRep.GetById(unFavoris.getIdentifiantContact()));
}
contactRep.Close();
}
_inflater = (LayoutInflater) _activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this._imageLoader = ImageLoader.getInstance();
this._options = new DisplayImageOptions.Builder().showImageForEmptyUri(R.drawable.error).showImageOnFail(R.drawable.error).cacheInMemory().cacheOnDisc()
.displayer(new RoundedBitmapDisplayer(Utils.IMAGE_BORDER_RADIUS)).bitmapConfig(Bitmap.Config.RGB_565).build();
Utils utils = new Utils();
utils.setImageLoader(_imageLoader, _activity);
}
#Override
public int getCount() {
return _listContacts.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
CellHolder cellHolder = null;
Contact _contact = _listContacts.get(position);
Etablissement etablissement = new Etablissement();
//
// GET
if (convertView == null) {
view = _inflater.inflate(R.layout.directory_list_item, null);
cellHolder = new CellHolder();
cellHolder.textTitle = (TextView) view.findViewById(R.id.annuaire_titre_etablissement);
cellHolder.textCategory = (TextView) view.findViewById(R.id.annuaire_categorie_etablissement);
cellHolder.textDistance = (TextView) view.findViewById(R.id.annuaire_distance_etablissement);
cellHolder.imageIcon = (ImageView) view.findViewById(R.id.img_icon);
cellHolder.textPromo = (TextView) view.findViewById(R.id.promo);
cellHolder.textTarif = (TextView) view.findViewById(R.id.annuaire_tarif_etablissement);
view.setTag(cellHolder);
}
else {
cellHolder = (CellHolder) convertView.getTag();
}
//
// SET
cellHolder.textTitle.setText(_contact.getName().toUpperCase());
try {
//
EtablissementRepository etablissementRep = new EtablissementRepository(_activity);
etablissementRep.Open();
int idEta = etablissementRep.GetByIdContact(_contact.getIdentifiant());
etablissement = etablissementRep.GetById(idEta);
etablissementRep.Close();
// CATEGORIES
if (_section == 0) {
if (etablissement.getSection() != null && !etablissement.getSection().getLibelle().equals("")) {
cellHolder.textCategory.setText(etablissement.getSection().getLibelle());
}
else {
cellHolder.textCategory.setVisibility(View.GONE);
}
}
else {
String categories = "";
for (Categorie cat : etablissement.getCategories()) {
categories = categories + cat.getLibelle() + "|";
}
if (!categories.equals("")) {
cellHolder.textCategory.setText(categories);
}
else {
cellHolder.textCategory.setText(_activity.getString(R.string.txt_no_categories));
}
}
//
// TARIF
String trancheTarif = "";
if (etablissement.getTarif() != null) {
trancheTarif = etablissement.getTarif().getMinPrice() + "\u20ac à " + etablissement.getTarif().getMaxPrice() + "\u20ac";
}
if (!trancheTarif.equals("") && etablissement.getTarif().getMinPrice() > 0 && etablissement.getTarif().getMaxPrice() > 0) {
cellHolder.textTarif.setText(trancheTarif);
}
else {
cellHolder.textTarif.setText("- \u20ac à - \u20ac");
}
// PROMO
boolean etatPromotion = false;
for (Promotion promo : etablissement.getPromotions()) {
if (promo.isPromoOnGoing()) {
etatPromotion = true;
}
}
if (!etatPromotion) { // PROMO OFF
cellHolder.textPromo.setVisibility(View.VISIBLE);
}
else { // PROMO ON
cellHolder.textPromo.setVisibility(View.VISIBLE);
}
// LOGO
final ProgressBar spinner = (ProgressBar) convertView.findViewById(R.id.loading);
_imageLoader.displayImage(etablissement.getImgThumb(), cellHolder.imageIcon, _options, new SimpleImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
String message = null;
switch (failReason.getType()) {
case IO_ERROR:
message = "Input/Output error";
break;
case DECODING_ERROR:
message = "Image can't be decoded";
break;
case NETWORK_DENIED:
message = "Downloads are denied";
break;
case OUT_OF_MEMORY:
message = "Out Of Memory error";
break;
case UNKNOWN:
message = "Unknown error";
break;
}
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
}
});
}
catch (Exception e) {
}
// DISTANCE
int distanceFormatee = 0;
if (_latitude == 0 || _longitude == 0) {
cellHolder.textDistance.setText("");
}
else {
int distance = (int) distanceBetween(_latitude, _longitude, _contact.getLatitude(), _contact.getLongitude());
distanceFormatee = distance / 1000;
if (distance < 1000) {
cellHolder.textDistance.setText("< 1 km");
}
else {
cellHolder.textDistance.setText(distanceFormatee + " km");
}
}
//
// SAVE DISTANCE
EtablissementApplication._dataManager.get_listOfContacts(_section, _activity).get(position).setDistance(distanceFormatee);
//
// DATA SAVE
List<Integer> _mapData = new ArrayList<Integer>();
_mapData.add(_contact.getIdentifiant());
_mapData.add(etablissement.getIdentifiant());
DataManager._contactForEtaHashMap.put(_contact.getName(), etablissement);
DataManager._mapContact.put(position, _mapData);
return view;
}
public class CellHolder {
public TextView textTitle;
public TextView textAdress;
public TextView textCategory;
public TextView textTarif;
public TextView textPromo;
public ImageView imageIcon;
public TextView textDistance;
}
public void clearData() {
_listContacts.clear();
_listFavoris.clear();
}
private double distanceBetween(float lat_a, float lng_a, float lat_b, float lng_b) {
float pk = (float) (180 / 3.14169);
float a1 = lat_a / pk;
float a2 = lng_a / pk;
float b1 = lat_b / pk;
float b2 = lng_b / pk;
float t1 = FloatMath.cos(a1) * FloatMath.cos(a2) * FloatMath.cos(b1) * FloatMath.cos(b2);
float t2 = FloatMath.cos(a1) * FloatMath.sin(a2) * FloatMath.cos(b1) * FloatMath.sin(b2);
float t3 = FloatMath.sin(a1) * FloatMath.sin(b1);
double tt = Math.acos(t1 + t2 + t3);
return 6366000 * tt;
}
}
You can achieve expected behaviour by this:
Your list item layout:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ProgressBar
android:id="#+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<ImageView
android:id="#+id/imgAlbum"
android:layout_width="48dip"
android:layout_height="48dip"
android:layout_gravity="center|left"
android:scaleType="centerCrop" />
</RelativeLayout
If you have ProgressBar and ImageView in this order, then ImageView will overlay the ProgressBar, when Image Loader set image into it so ProgressBar will not be visible anymore.
Then in your getView() method just simply load image with standard way. You dont have to bother with hiding/showing ProgressBar
You will have to put a function to refresh the 'source' that is providing the image resource to the spinner manually once the download is complete i.e i suppose when an onPost is complete in your async task if at all u are using one. This way the source providing the resource to the spinner will be updated all the time.
try this code and use Asynk task will help u:
http://thinkandroid.wordpress.com/2012/06/13/lazy-loading-images-from-urls-to-listviews/

Categories