ImageView GridView bad order and bad performance - android

If I have (1)(2)(3)(4)(5)(6)(7)(8) images in GridView show - > (1)(2)(3)(4)(1)(2)(3)(4) which this code and this work which very good performance.
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {//here
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(300, 300));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
File imgFile = new File(ImagesApi.getCalculatedList().get(
position));
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile
.getAbsolutePath());
imageView.setImageBitmap(Bitmap.createScaledBitmap(myBitmap,
(int) (myBitmap.getWidth() * 0.12),
(int) (myBitmap.getHeight() * 0.12), true));
myBitmap.recycle();
} else {
imageView = (ImageView) convertView;
}
return imageView;
}
public int getCount() {
return ImagesApi.getCalculatedList().size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return position;
}
If I add if (convertView == null || position != convertView.getId()) { and imageView.setId(position); in "//here" I get images in GridView which correct order but which very very bad performance. Ui thread go very very slow.
ImagesApi.getCalculatedList() is constant ArrayList of image paths

Related

How to set custom aspect ratio in grid view in Android?

I am trying to set a 3:2 ratio for a gridview (IE 300 pixels by 200 per cell). Here is my image adapter:
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// 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
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(200, 200));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
// references to our images
private Integer[] mThumbIds = {
R.drawable.image1, R.drawable.image2, R.drawable.image3,
};
}
I've tried adjusting the imageView.setLayoutParams(new GridView.LayoutParams(200, 200)); width parameter to 300 but it results in overlapping. Here is my XML File:
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="90dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center"
/>
Weird overlapping:
Hi there you can try like this from your Activity :
ViewGroup.LayoutParams layoutParams = gridview.getLayoutParams();
layoutParams.height = 200;
layoutParams.width = 300;
gridview.setLayoutParams(layoutParams);
or
int final width = 300;
int final height = 200;
ViewGroup.LayoutParams lauoutParams = new ViewGroup.LayoutParams(width,height);
gridView.setLayoutParams(lp);
This might help.
Discovered this library: AsymetricGridView

How to add TextView inside a GridView filled with ImageView

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..

GridView Images is not loading

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!

GridView not displaying correct thumbnail

I have a folder on my SDCard that is hidden with the .nomedia. I have this Imageadapter that displays the contents of the folder (Images and Videos) in a GridView. They all seem to show up, but sometimes when I click on a thumbnail that I know is a Video, an image is displayed or even a different video. Can someone please tell me where I am going wrong with this?
GridViewImageAdapter.class
package com.soboapps.todos.adapter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ThumbnailUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
public class GridViewImageAdapter extends BaseAdapter {
private Activity mActivity;
private ArrayList<String> mFilePaths = new ArrayList<String>();
private int imageWidth;
public GridViewImageAdapter(Activity activity, ArrayList<String> filePaths, int imageWidth) {
this.mActivity = activity;
this.mFilePaths = filePaths;
this.imageWidth = imageWidth;
}
#Override
public int getCount() {
return this.mFilePaths.size();
}
#Override
public Object getItem(int position) {
return this.mFilePaths.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent)
{
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mActivity);
if(mFilePaths.get(position).contains("jpg") || mFilePaths.get(position).contains("jpeg") ||
mFilePaths.get(position).contains("png"))
{
Bitmap image = BitmapFactory.decodeFile(mFilePaths.get(position)); //Creation of Thumbnail of image
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(imageWidth, imageWidth));
imageView.setImageBitmap(image);
}
else if(mFilePaths.get(position).contains(".mp4") || mFilePaths.get(position).contains(".3gp"))
{
Bitmap video = ThumbnailUtils.createVideoThumbnail(mFilePaths.get(position), imageWidth); //Creation of Thumbnail of video
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(imageWidth, imageWidth));
imageView.setImageBitmap(video);
}
}
else
{
imageView = (ImageView)convertView;
}
return imageView;
}
/*
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mActivity);
} else {
imageView = (ImageView) convertView;
}
// get screen dimensions
Bitmap image = decodeFile(mFilePaths.get(position), imageWidth, imageWidth);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(imageWidth, imageWidth));
imageView.setImageBitmap(image);
return imageView;
}
*/
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;
}
}
Inside your getView() function you're not setting the thumbnail correctly in the case where convertView is not null. Rearrange your code like this to handle that case:
public View getView(int position, View convertView, ViewGroup parent)
{
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mActivity);
} else {
imageView = (ImageView) convertView;
}
if(mFilePaths.get(position).contains("jpg") || mFilePaths.get(position).contains("jpeg") ||
mFilePaths.get(position).contains("png"))
{
Bitmap image = BitmapFactory.decodeFile(mFilePaths.get(position)); //Creation of Thumbnail of image
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(imageWidth, imageWidth));
imageView.setImageBitmap(image);
}
else if(mFilePaths.get(position).contains(".mp4") || mFilePaths.get(position).contains(".3gp"))
{
Bitmap video = ThumbnailUtils.createVideoThumbnail(mFilePaths.get(position), imageWidth); //Creation of Thumbnail of video
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(imageWidth, imageWidth));
imageView.setImageBitmap(video);
}
return imageView;
}
The convertView parameter isn't a view that has already been initialized to the specified position, that you can return as is. It's a view that was being used to display a different grid element, that is being recycled for a different position, so you need to set it up.
Also, if you have laggy UI issues, look into creating your thumbnails in an AsyncTask or thread pool instead of on the main UI thread. Check out questions such as this one for information about how to do that: Loading images in a gridview with async task

Gridview does not show all the picture, only a small part

I have the following GridView:
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(context);
imageView.setScaleType(ScaleType.CENTER_CROP);
} else {
imageView = (ImageView) convertView;
}
if (mTemplates.get(position).getResource() != 0) {
LogService.log("", "zzzzzzzzzzzzzzzz======loaded from resource" + mTemplates.get(position).getResource() + "???????????" + mTemplates.size());
imageView.setImageResource(mTemplates.get(position).getResource());
} else {
imageView.setImageDrawable(mTemplates.get(position).getDrawableThumbnail());
// imageView.setImageResource(mTemplates.get(0).getResource());
LogService.log("", "zzzzzzzzzzzzzzzz======loaded from drawable");
LogService.log("", "=========SIZE: " + mTemplates.size());
}
return imageView;
}
Now I have some elements that do not have resources in the Drawables, but instead in a folder on the sdcard, so I create a drawable from the source of this pictures, and try to load that drawable on the gridview:
imageView.setImageDrawable(mTemplates.get(position).getDrawableThumbnail());
But its like the gridview does not recognise these, and if its on the same collumn with other pictures it is shown, but if its on another collumn (lower), it will only show 2-3mm of the picture (also doesn't recognise its position like its not therE).
If I hardcode and use the first picture from Resources like this:
imageView.setImageResource(mTemplates.get(0).getResource());
It all works, what could be the issue?
Because the actually size of the pic, is the small size, but when loading an imageView from Resources it strectches it to its parents size.
Resolved this issue by calculating the height needed, and then load all the pictures with that height:
public AdapterGridView(Context c) {
context = c;
DisplayMetrics metrics = new DisplayMetrics();
((Activity) c).getWindowManager().getDefaultDisplay().getMetrics(metrics);
if (Constants.IS_TABLET) {
height = metrics.widthPixels / 9 - (int) Util.pxFromDp(2, c);
} else {
height = metrics.widthPixels / 4 - (int) Util.pxFromDp(2, c);
}
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(context);
} else {
imageView = (ImageView) convertView;
}
imageView.setScaleType(ScaleType.CENTER_CROP);
imageView.setAdjustViewBounds(true);
if (mTemplates.get(position).getResource() != 0) {
imageView.setImageResource(mTemplates.get(position).getResource());
} else {
imageView.setImageDrawable(mTemplates.get(position).getDrawableThumbnail());
}
imageView.setLayoutParams(new LayoutParams(height, height));
return imageView;
}

Categories

Resources