I have gridview and have to download images to gridview. When I open app I cannot see any images, but I think my code is somehow correct. How to fix it?
I use this code in my adapter:
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) { // if it's not recycled, initialize some attributes
//float wd = 250 / Resources.getSystem().getDisplayMetrics().density;
//float hg = 300 / Resources.getSystem().getDisplayMetrics().density;
int pxwd = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 90, Resources.getSystem().getDisplayMetrics());
int pxhg = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 120, Resources.getSystem().getDisplayMetrics());
imageView = new ImageView(context);
imageView.setLayoutParams(new GridView.LayoutParams(pxwd, pxhg));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageDrawable(LoadImageFromURL(GridViewConfig.getImage_list().get(position)));
return imageView;
}
// references to our images
private Drawable LoadImageFromURL(String url)
{
try {
InputStream is = (InputStream) new URL(url).getContent();
return Drawable.createFromStream(is, "src");
} catch (Exception e) {
return null;
}
}
and here is url list:
public class GridViewConfig {
public static ArrayList<String> image_listGrid = new ArrayList<String>();
public static ArrayList<String> getImage_list() {
return image_listGrid;
}
public static void setImage_list(ArrayList<String> image_list) {
GridViewConfig.image_listGrid = image_list;
}
public static void addImageUrls(){
image_listGrid.add("someimage.jpg");
}
But problem is no image is showing on my GridView.
In your getView(...), you should use TypedValue.COMPLEX_UNIT_DIP replaces TypedValue.COMPLEX_UNIT_SP:
int pxwd = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 90, Resources.getSystem().getDisplayMetrics());
int pxhg = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 120, Resources.getSystem().getDisplayMetrics());
Hope this help!
Related
I need to create and set customize bitmap image on each row of listview. I am doing that using picasso. My code inside getView of adapter is like below,
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
View rowView = convertView;
if (rowView == null){
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.horizontal_listview_list_sample, parent, false);
viewHolder = new ViewHolder();
viewHolder.imgDot = (ImageView) rowView.findViewById(R.id.rowIcon);
viewHolder.rowIconBackround = (ImageView) rowView.findViewById(R.id.rowIconBackground);
rowView.setTag(viewHolder);
}else {
viewHolder = (ViewHolder) rowView.getTag();
}
//Start Custom Image View///////
String photoUrl1 = arrayList.get(position).getPhotoUrl();
if (photoUrl1.length()<8){
photoUrl1 = "SOME_URL";
}
final String photoUrl = photoUrl1;
final ImageView imgDot = viewHolder.imgDot;
// final viewHolder.imgDot = (ImageView) rowView.findViewById(R.id.rowIcon);
final View finalRowView = rowView;
final ViewHolder finalViewHolder = viewHolder;
final Target target = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap2, Picasso.LoadedFrom from) {
Log.d("PICASO", " called: " + "onBitmapLoaded called");
Bitmap original;
original = new MyProfile().getResizedBitmap(bitmap2, (int) new MainActivity().dipToPixels(MainActivity.getInstance(), 63), (int) new MainActivity().dipToPixels(MainActivity.getInstance(), 63));
BitmapDrawable bitmap = (BitmapDrawable) finalRowView.getResources().getDrawable(R.drawable.drawer_pro_pic_placeholder);
int bitmapHeight= bitmap .getBitmap().getHeight();
int bitmapWidth = bitmap .getBitmap().getWidth();
Bitmap mask = BitmapFactory.decodeResource(finalRowView.getResources(), R.drawable.drawer_pro_pic_placeholder);
Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
int width = mask.getWidth();
int height = mask.getHeight();
float centerX = (width - original.getWidth()) * 0.5f;
float centerY = (height- original.getHeight()) * 0.5f;
mCanvas.drawBitmap(original, centerX, centerY, null);
mCanvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
imgDot.getLayoutParams().height = bitmapHeight;
imgDot.getLayoutParams().width = bitmapWidth;
imgDot.setScaleType(ImageView.ScaleType.CENTER_CROP);
imgDot.setImageBitmap(result);
imgDot.setAdjustViewBounds(true);
Picasso.with(context).cancelRequest(finalViewHolder.imgDot);
targets.remove(this);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
Log.d("PICASO", " called: " + "onBitmapFailed called");
Picasso.with(context).cancelRequest(finalViewHolder.imgDot);
targets.remove(this);
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
Log.d("PICASO", "responseForRegistration called: " + "onPrepareLoad called");
}
};
targets.add(target);
// imgDot.setTag(target);
Picasso.with(context).load(photoUrl).into(target);
//End Custom Image View////////////
return rowView;
}
Suppose, there is two row so two customize bitmap will be created. When first one is created its showing nice but when second one created then this last image is showing in both row's imageview.
What I need to change in my code?
Any help will be appreciated.
You could try something by creating handler as subclass of your adapter and passing specific reference of your view holder and position which will help us to avoid overriding issue of target listener
// construct the handler inside your adapter's constructor so you know it is on the UI thread
Handler myHandler = new Handler();
class LoadImage implements Runnable {
ImageView iv;
int position;
public LoadImage(ImageView iv, int position) {
this.iv = iv;
this.position = position;
}
#Override
public void run() {
// keep your target listener stuffs here
Target target = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap2, Picasso.LoadedFrom from) {
Log.d("PICASO", " called: " + "onBitmapLoaded called");
Bitmap original;
original = new MyProfile().getResizedBitmap(bitmap2, (int) new MainActivity().dipToPixels(MainActivity.getInstance(), 63), (int) new MainActivity().dipToPixels(MainActivity.getInstance(), 63));
BitmapDrawable bitmap = (BitmapDrawable) finalRowView.getResources().getDrawable(R.drawable.drawer_pro_pic_placeholder);
int bitmapHeight= bitmap .getBitmap().getHeight();
int bitmapWidth = bitmap .getBitmap().getWidth();
Bitmap mask = BitmapFactory.decodeResource(finalRowView.getResources(), R.drawable.drawer_pro_pic_placeholder);
Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
int width = mask.getWidth();
int height = mask.getHeight();
float centerX = (width - original.getWidth()) * 0.5f;
float centerY = (height- original.getHeight()) * 0.5f;
mCanvas.drawBitmap(original, centerX, centerY, null);
mCanvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
iv.getLayoutParams().height = bitmapHeight;
iv.getLayoutParams().width = bitmapWidth;
iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
iv.setImageBitmap(result);
iv.setAdjustViewBounds(true);
Picasso.with(context).cancelRequest(iv);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
Log.d("PICASO", " called: " + "onBitmapFailed called");
Picasso.with(context).cancelRequest(iv);
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
Log.d("PICASO", "responseForRegistration called: " + "onPrepareLoad called");
}
};
Picasso.with(context).load(photoList.get(position)).into(target);
}
}
And you will call it from your getView by :
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
View rowView = convertView;
if (rowView == null){
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.horizontal_listview_list_sample, parent, false);
viewHolder = new ViewHolder();
viewHolder.imgDot = (ImageView) rowView.findViewById(R.id.rowIcon);
viewHolder.rowIconBackround = (ImageView) rowView.findViewById(R.id.rowIconBackground);
rowView.setTag(viewHolder);
//Change is here
viewHolder.mRunnable = new LoadImage(viewHolder.imgDot, position);
}else {
viewHolder = (ViewHolder) rowView.getTag();
//Change is here
myHandler.removeCallbacks(viewHolder.mRunnable);
}
//Start Custom Image View///////
String photoUrl1 = arrayList.get(position).getPhotoUrl();
if (photoUrl1.length()<8){
photoUrl1 = "SOME_URL";
}
final String photoUrl = photoUrl1;
final ImageView imgDot = viewHolder.imgDot;
// final viewHolder.imgDot = (ImageView) rowView.findViewById(R.id.rowIcon);
final View finalRowView = rowView;
final ViewHolder finalViewHolder = viewHolder;
//Change is here
myHandler.postDelayed(viewHolder.mRunnable, 3000);
return rowView;
}
I have a GridView where I add images directly with ImageView (I don't use an XML for the image). Now, I want to add image name at the bottom of each cell using a TextView. How can I do it? Thanks in advance.
Custom Adapter Class:
public class GridViewImageAdapter extends BaseAdapter {
private Activity _activity;
private ArrayList<String> _filePaths = new ArrayList<String>();
private int imageWidth;
private GridView imageCarrete;
public GridViewImageAdapter(Activity activity, ArrayList<String> filePaths,
int imageWidth, GridView imageCarrete) {
this._activity = activity;
this._filePaths = filePaths;
this.imageWidth = imageWidth;
this.imageCarrete = imageCarrete;
}
#Override
public int getCount() {
return this._filePaths.size();
}
#Override
public Object getItem(int position) {
return this._filePaths.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(_activity);
} else {
imageView = (ImageView) convertView;
}
// get screen dimensions
Bitmap image = decodeFile(_filePaths.get(position), imageWidth,
imageWidth);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(imageWidth,
imageWidth));
imageView.setImageBitmap(image);
// Listener del GridView
imageCarrete.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
Intent i = new Intent(_activity, FullScreenViewActivity.class);
i.putExtra("position", position);
_activity.startActivityForResult(i, 1234);
}
});
return imageView;
}
/*
* Resizing image size
*/
public static Bitmap decodeFile(String filePath, int WIDTH, int HIGHT) {
try {
File f = new File(filePath);
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
final int REQUIRED_WIDTH = WIDTH;
final int REQUIRED_HIGHT = HIGHT;
int scale = 1;
while (o.outWidth / scale / 2 >= REQUIRED_WIDTH
&& o.outHeight / scale / 2 >= REQUIRED_HIGHT)
scale *= 2;
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
public void remove(String path){
_filePaths.remove(path);
}
}
GridView XML
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/grid_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:numColumns="auto_fit"
android:gravity="center"
android:stretchMode="columnWidth"
android:background="#000000">
</GridView>
Within your getView() method, replace your ImageView with a TextView with a drawable:
TextView tv = new TextView(context);
tv.setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom);
you will supply the drawable to the top and 0 to the rest, ie:
tv.setCompoundDrawablesWithIntrinsicBounds(0, yourDrawable, 0, 0);
Just create a LinearLayout as you are creating Imagview in getView() method... add ImageView and TextView to it with addView() method.... have a look ..
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout _ll;
if (convertView == null) {
_ll = new LinearLayout(mContext);
_ll.setOrientation(LinearLayout.VERTICAL);
ImageView img = new ImageView(mContext);
img.setLayoutParams(new LinearLayout.LayoutParams(100, 100)); // your image size
img.setBackgroundResource(images[position]); // here pass your array list position
_ll.addView(img);
TextView text = new TextView(mContext);
text.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
text.setText("dsaf");
text.setGravity(Gravity.CENTER);
_ll.addView(text);
} else {
_ll = (LinearLayout) convertView;
}
return _ll;
}
You can also use RelativeLayout if you want to overlay your text over image..
I'm having images from url and it store in string array and on touch ImageView i'm trying to display images in GridView but images not displayed.
here is my Activity class.
public class GridViewActivity extends Activity {
private GridViewImageAdapter adapter;
private GridView gridView;
private int columnWidth;
ArrayList<String> imagepath;
Utility utils;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grid_view);
gridView = (GridView) findViewById(R.id.grid_view);
Intent i = getIntent();
imagepath = i.getExtras().getStringArrayList("event_photo");
Log.i("Grid View", "hello..."+imagepath);
utils = new Utility(this);
// Initilizing Grid View
InitilizeGridLayout();
// Gridview adapter
adapter = new GridViewImageAdapter(GridViewActivity.this, imagepath,
columnWidth);
// setting grid view adapter
gridView.setAdapter(adapter);
}
private void InitilizeGridLayout() {
Resources r = getResources();
float padding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
AppConstant.GRID_PADDING, r.getDisplayMetrics());
columnWidth = (int) ((utils.getScreenWidth() - ((AppConstant.NUM_OF_COLUMNS + 1) * padding)) / AppConstant.NUM_OF_COLUMNS);
gridView.setNumColumns(AppConstant.NUM_OF_COLUMNS);
gridView.setColumnWidth(columnWidth);
gridView.setStretchMode(GridView.NO_STRETCH);
gridView.setPadding((int) padding, (int) padding, (int) padding,
(int) padding);
gridView.setHorizontalSpacing((int) padding);
gridView.setVerticalSpacing((int) padding);
}
}
here is my adapter class.
public class GridViewImageAdapter extends BaseAdapter {
private Activity _activity;
private ArrayList<String> _filePaths = new ArrayList<String>();
private int imageWidth;
public GridViewImageAdapter(Activity activity, ArrayList<String> filePaths,
int imageWidth) {
this._activity = activity;
this._filePaths = filePaths;
this.imageWidth = imageWidth;
}
#Override
public int getCount() {
return this._filePaths.size();
}
#Override
public Object getItem(int position) {
return this._filePaths.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(_activity);
} else {
imageView = (ImageView) convertView;
}
// get screen dimensions
Bitmap image = decodeFile(_filePaths.get(position), imageWidth,
imageWidth);
Log.i("Grid View", "image bitmap..."+image);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(imageWidth,
imageWidth));
imageView.setImageBitmap(image);
// image view click listener
imageView.setOnClickListener(new OnImageClickListener(position));
return imageView;
}
class OnImageClickListener implements OnClickListener {
int _postion;
// constructor
public OnImageClickListener(int position) {
this._postion = position;
}
#Override
public void onClick(View v) {
// on selecting grid view image
// launch full screen activity
/*Intent i = new Intent(_activity, FullScreenViewActivity.class);
i.putExtra("position", _postion);
_activity.startActivity(i);*/
}
}
/*
* Resizing image size
*/
public static Bitmap decodeFile(String filePath, int WIDTH, int HIGHT) {
try {
File f = new File(filePath);
Log.i("Grid View", "imagefb bfhdb"+filePath);
Log.i("Grid View", "imagefb nj"+f);
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
final int REQUIRED_WIDTH = WIDTH;
final int REQUIRED_HIGHT = HIGHT;
int scale = 1;
while (o.outWidth / scale / 2 >= REQUIRED_WIDTH
&& o.outHeight / scale / 2 >= REQUIRED_HIGHT)
scale *= 2;
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
if any one have solution please let me know.
//The Path where my images are saving
/storage/emulated/0/Pictures/CameraExample/JPEG_20150107_152640.jpeg
//This is one of the file path.
//I need to sort images like last taken photo as the first one to display //inside the grid view as of now images are displayed, recent photo at the //last.
Below is my code
public class ImageAdapter extends BaseAdapter{
private Context context;
private int imageWidth;
private Activity activity;
ArrayList<String> itemList = new ArrayList<String>();
Bitmap bitmap;
public ImageAdapter(Activity activity,ArrayList<String> itemList,int imageWidth) {
this.activity = activity;
this.itemList = itemList;
this.imageWidth = imageWidth;
}
#Override
public int getCount() {
return this.itemList.size();
}
void add(String path) {
itemList.add(path);
}
#Override
public Object getItem(int position) {
return this.itemList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(activity);
}
else {
imageView = (ImageView) convertView;
}
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(imageWidth ,imageWidth ));
bitmap = decodeFile(itemList.get(position), imageWidth, imageWidth);
imageView.setImageBitmap(bitmap);
imageView.setOnClickListener( new OnImageClickListener(position));
return imageView;
}
class OnImageClickListener implements View.OnClickListener {
int position;
public OnImageClickListener(int position){
this.position = position;
}
#Override
public void onClick(View v) {
Intent intent = new Intent(activity, ImageDisplayActivity.class);
intent.putExtra("position", position);
Log.d("ImageAdapter","Intent.putExtra ");
activity.startActivity(intent);
}
}
public Bitmap decodeFile(String path, int reqWidth, int reqHeight) {
try {
File f = new File(path);
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
final int REQUIRED_WIDTH = reqWidth;
final int REQUIRED_HEIGHT = reqHeight;
int scale = 1;
while (o.outWidth / scale / 2 >= REQUIRED_WIDTH && o.outHeight / scale / 2 >= REQUIRED_HEIGHT)
scale *= 2;
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
// And Finally when I scroll my grid view . Scrolling is not so smooth. Please help me in solving two problems.
// My GridView Activity Class
public class GridViewActivity extends Activity {
private ImageAdapter imageAdapter;
private HelperUtils utils;
private ArrayList<String> itemList = new ArrayList<String>();
private GridView gridView;
private int columnWidth;
private Activity activity;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gridview);
gridView = (GridView) findViewById(R.id.gridView);
utils = new HelperUtils(this);
InitilizeGridLayout();
itemList = utils.getFilePaths();
imageAdapter = new ImageAdapter(this, itemList, columnWidth);
gridView.setAdapter(imageAdapter);
}
private void InitilizeGridLayout() {
Resources r = getResources();
float padding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, HelperAppConstant.GRID_PADDING, r.getDisplayMetrics());
columnWidth = (int) ((utils.getScreenWidth() - ((HelperAppConstant.NUM_OF_COLUMNS + 1) * padding)) / HelperAppConstant.NUM_OF_COLUMNS);
gridView.setNumColumns(HelperAppConstant.NUM_OF_COLUMNS);
gridView.setColumnWidth(columnWidth);
gridView.setStretchMode(GridView.NO_STRETCH);
gridView.setPadding((int) padding, (int) padding, (int) padding, (int) padding);
gridView.setHorizontalSpacing((int) padding);
gridView.setVerticalSpacing((int) padding);
}
}
Remove the Collections.sort(itemList); from your getView method.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
Log.d("ImageAdapter","Inside the if condition");
imageView = new ImageView(activity);
}
else {
imageView = (ImageView) convertView;
}
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(imageWidth ,imageWidth ));
// bitmap = decodeFile(itemList.get(position), imageWidth, imageWidth);
bitmap = decodeFile(getItem(position), imageWidth, imageWidth);
imageView.setImageBitmap(bitmap);
return imageView;
}
Sort the list just before you populate your grid view in your onCreate method.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gridview);
gridView = (GridView) findViewById(R.id.gridView);
utils = new HelperUtils(this);
InitilizeGridLayout();
itemList = utils.getFilePaths();
Collections.sort(itemList);
imageAdapter = new ImageAdapter(this, itemList, columnWidth);
gridView.setAdapter(imageAdapter);
}
You could follow the example in this link by creating a list of items that contains the image file path and the image bitmap. This way, you wouldn't have to decode the bitmap everytime getView is called. You could just decode it once before you populate the gridview.
Since the images are sorted in ascending order, you can replace you getItem method with the one below:
#Override
public Object getItem(int position) {
return this.itemList.get(itemList.size() - 1 - position);
}
I updated the getView method. You should use getItem(position) instead of itemList.get(position) to decode the bitmap.
For making your scroll smooth you have to display the images with Picasso library, I had the same issue !
I am developing an Android application for tablet which will be used as a catalog of many products (around 10 000).
I display them in a gridview, I only display the 250 first, and if I reach the end of these 250 I load 250 more.
My problem is the pictures. My application seems to work when I scroll not quickly, it is smooth, and there is no problems but it can use 300 or 400 MB of RAM, so I guess I'm doing something badly. I heard that I'm supposed to use WeakReferences but I'm not sure how to use them... That was for the first "problem". (It is not really important since the user may only use this application, and if it works very well... But yes, if I can improve it I will try)
The other big problem here is that when I do something like :
Scroll fast to the bottom
Immediately scroll fast to the top
Some pictures of the "bottom" are displayed on the pictures of the "top" (and not temporarly, they change again only if I scroll and come back at them).
What I know actually :
The mechanism of the griview reuse the views. If I have 10 views visibles, When the 5 first are not visibles, they are used for the 5 next ones that will be visible. I don't know how many view are in this "recycler".
This means that when I scroll to the bottom I see the 5 views which were not visible in the place of the 5 next ones for a few moment then the good views are loaded. To not have this bad effect, I set a picture white (the color of my background) using the method setRecyclerListener().
I don't "recycle" / use the good way to load my pictures and recycle them but don't know how to make it better
I use animations, I don't think there is any link with my problem due to them
I load the pictures in AsyncTask, that seems to work, but the picures are always loaded (in fast scroll too) which is not really a good thing
When scrolling bottom then top quickly sometimes I have the wrong pictures displayed. It may happen in other cases.
public class ProduitsAdapter extends ArrayAdapter<Article> {
private final Activity context;
private ArrayList<Article> params;
private Resources res;
static class ViewHolder {
public TextView numero;
public TextView design;
public ImageView image;
public ImageSwitcher imgSwitcher;
public ImageView codeBarre;
public TextView codeBarreText;
public TextView colisage;
public TextView col3;
public TextView col4;
public TextView col5;
public String image_string = "";
public boolean found = true;
public ImageView nouveaute;
}
public ProduitsAdapter(Activity context, ArrayList<Article> params) {
super(context, R.layout.list_single, params);
res = Catalogue.activity.getResources();
this.context = context;
this.params = params;
}
public int getCount() {
return params.size();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = context.getLayoutInflater();
ViewHolder viewHolder = new ViewHolder();
if (Catalogue.type_aff.equals("list")) {
rowView = inflater.inflate(R.layout.list_single, null);
viewHolder.numero = (TextView) rowView
.findViewById(R.id.numero);
viewHolder.design = (TextView) rowView
.findViewById(R.id.designation);
viewHolder.col3 = (TextView) rowView.findViewById(R.id.col3);
viewHolder.col4 = (TextView) rowView.findViewById(R.id.col4);
viewHolder.col5 = (TextView) rowView.findViewById(R.id.col5);
} else {
rowView = inflater.inflate(R.layout.fragment_grid_item, null);
viewHolder.numero = (TextView) rowView
.findViewById(R.id.numero);
viewHolder.design = (TextView) rowView
.findViewById(R.id.designation);
viewHolder.colisage = (TextView) rowView
.findViewById(R.id.grid_colisage);
viewHolder.codeBarre = (ImageView) rowView
.findViewById(R.id.code_barre);
viewHolder.codeBarreText = (TextView) rowView
.findViewById(R.id.code_barre_text);
viewHolder.nouveaute = (ImageView) rowView
.findViewById(R.id.img_nouveaute);
}
viewHolder.image = (ImageView) rowView.findViewById(R.id.img);
rowView.setTag(viewHolder);
}
ViewHolder holder = (ViewHolder) rowView.getTag();
if (Catalogue.type_aff.equals("list")) {
holder.col3.setText(params.get(position).getColonne_pref(3));
holder.col4.setText(params.get(position).getColonne_pref(4));
holder.col5.setText(params.get(position).getColonne_pref(5));
} else {
if (params.get(position).isNouveaute()) {
holder.nouveaute.setImageResource(R.drawable.nouveaute);
holder.nouveaute.setVisibility(ImageView.VISIBLE);
} else
holder.nouveaute.setVisibility(ImageView.GONE);
holder.colisage.setText(params.get(position).getColisage());
if (ProduitsFragment.barcodeVisible) {
holder.codeBarreText.setText(params.get(position)
.getGencodNegoce());
}
}
holder.numero.setText(params.get(position).getCodeArt());
holder.design.setText(params.get(position).getDesignation_pref());
// This is how I store my pictures, because finding one picture in a folder of 10 000 pictures takes too much time
String pattern_deb = holder.numero.getText() + "";
String chemin = Environment.getExternalStorageDirectory().getPath()
+ res.getString(R.string.chemin_app_data)
+ MainActivity.listDossiersSocietes
.get(MainActivity.societeSelected)
+ res.getString(R.string.chemin_dossier_photos);
for (int i = 0; i < pattern_deb.length() - 2; i++) {
chemin += "/" + pattern_deb.charAt(i);
}
chemin += "/";
File f = new File(chemin + params.get(position).getFichierPhoto());
if (f.exists()) {
holder.image_string = f.getAbsolutePath();
new loadImagesFromFileThread(holder, position).execute();
if (!Catalogue.type_aff.equals("list")
&& ProduitsFragment.barcodeVisible)
new loadBarCodeThread(holder, position).execute();
} else {
holder.image.setImageResource(R.drawable.notfound300);
}
return rowView;
}
private BitmapDrawable loadImagesFromFile(ViewHolder holder, int position) {
holder.found = true;
File bmp = new File(holder.image_string);
if (bmp.exists() && !bmp.isDirectory()) {
if (position < ProduitsFragment.gridView.getFirstVisiblePosition()
&& position > ProduitsFragment.gridView
.getLastVisiblePosition()) {
holder.found = false;
return null;
} else {
if (holder.image.getVisibility() == ImageView.VISIBLE) {
holder.found = false;
return null;
}
}
Bitmap myBitmap = BitmapFactory.decodeFile(bmp.getAbsolutePath());
int width = myBitmap.getWidth();
int height = myBitmap.getHeight();
int newWidth = 200;
int newHeight = 200;
if (Catalogue.type_aff.equals("list")) {
newWidth = 40;
newHeight = 40;
} else {
if (Catalogue.nbGrid == 5) {
newWidth = 200;
newHeight = 200;
}
if (Catalogue.nbGrid == 3) {
newWidth = 300;
newHeight = 300;
}
}
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(myBitmap, 0, 0, width,
height, matrix, true);
BitmapDrawable bmd = new BitmapDrawable(context.getResources(),
resizedBitmap);
return bmd;
} else {
holder.found = false;
return null;
}
}
private class loadImagesFromFileThread extends
AsyncTask<Void, Void, BitmapDrawable> {
ViewHolder holder;
int position;
public loadImagesFromFileThread(ViewHolder holder, int position) {
this.holder = holder;
this.position = position;
this.holder.image.setVisibility(ImageView.INVISIBLE);
}
#Override
protected BitmapDrawable doInBackground(Void... params) {
return loadImagesFromFile(holder, position);
}
#Override
protected void onPostExecute(BitmapDrawable bmd) {
if (ProduitsFragment.isNotScrolling) {
if (bmd != null) {
holder.image.setImageDrawable(bmd);
if (holder.image.getVisibility() != ImageView.VISIBLE
&& !(position < ProduitsFragment.gridView
.getFirstVisiblePosition() && position > ProduitsFragment.gridView
.getLastVisiblePosition())) {
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator());
fadeIn.setDuration(500);
fadeIn.setStartOffset(500);
holder.image.startAnimation(fadeIn);
holder.image.setVisibility(ImageView.VISIBLE);
}
} else {
if (position < ProduitsFragment.gridView
.getFirstVisiblePosition()
&& position > ProduitsFragment.gridView
.getLastVisiblePosition()) {
Log.e("DEBUG", "...");
} else {
if (holder.image.getVisibility() != ImageView.VISIBLE) {
if (!holder.found) {
if (Catalogue.type_aff.equals("list")) {
holder.image
.setImageResource(R.drawable.notfound40);
} else {
if (Catalogue.nbGrid == 5) {
holder.image
.setImageResource(R.drawable.notfound200);
}
if (Catalogue.nbGrid == 3) {
holder.image
.setImageResource(R.drawable.notfound300);
}
}
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator());
fadeIn.setDuration(500);
holder.image.startAnimation(fadeIn);
holder.image.setVisibility(ImageView.VISIBLE);
} else {
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator());
fadeIn.setDuration(500);
holder.image.startAnimation(fadeIn);
}
holder.image.setVisibility(ImageView.VISIBLE);
}
}
}
}
}
}
}
I would appreciate any help to correct the problem of the wrong pictures, and if anyone can explain me how to load them properly with some code if possible (without using 300 MB of RAM) that would be really nice.