GridView not displaying correct thumbnail - android

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

Related

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

Grid view scrolling and image loading very slow

I am using the below code to populate a grid view with images, the image loading in the grid view is slow ,The Grid view scrolling is quite slow and stuck at some point. I am not sure what am i doing wrong.
No error messages are written in the logcat
package com.dbprox.tagpic;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import java.io.File;
import java.util.ArrayList;
public class imagegallery extends AppCompatActivity {
private class ImageAdapter extends BaseAdapter {
private Context mContext;
ArrayList<String> itemList = new ArrayList<String>();
public ImageAdapter(Context c) {
mContext = c;
}
void add(String path){
itemList.add(path);
}
#Override
public int getCount() {
return itemList.size();
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
#Override
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(185, 185));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(5, 5, 5, 5);
} else {
imageView = (ImageView) convertView;
}
Bitmap bm = decodeSampledBitmapFromUri(itemList.get(position), 185, 185);
if(bm!=null){
imageView.setImageBitmap(bm);
}
return imageView;
}
public Bitmap decodeSampledBitmapFromUri(String path, int reqWidth, int reqHeight) {
Bitmap bm = null;
// 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;
bm = BitmapFactory.decodeFile(path, options);
return bm;
}
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) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
return inSampleSize;
}
}
ImageAdapter myImageAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_imagegallery);
GridView gridview = (GridView) findViewById(R.id.imagegridview);
gridview.setFastScrollEnabled(true);
myImageAdapter = new ImageAdapter(this);
gridview.setAdapter(myImageAdapter);
String ExternalStorageDirectoryPath = Environment
.getExternalStorageDirectory()
.getAbsolutePath();
String targetPath =Environment.getExternalStorageDirectory().toString()+"/Pictures"; //ExternalStorageDirectoryPath + "/Pictures";
// Toast.makeText(getApplicationContext(), targetPath, Toast.LENGTH_LONG).show();
File targetDirector = new File(targetPath);
File[] files = targetDirector.listFiles();
for (File file : files){
try {
myImageAdapter.add(file.getAbsolutePath());
}catch(Exception e) {
Log.d("TAG", "Error is " + e);}
}
}
}
All the image related operations you are performing are being done on the main thread which blocks the UI. You need to push all this work to a worker thread.
Alternatively use libraries like Glide or Picasso to do all the heavy lifting for you.
I had the same issue. Load your images using Picasso - Square and the application will run smoother than ever. Works for both images fetched from servers as well as drawable resources.

ImageView GridView bad order and bad performance

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

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!

Sort Image according to DATE and TIME inside gridview android

//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 !

Categories

Resources