This is my code in which the image is not showing properly:
public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.PhotoViewHolder> implements SizeCalculatorDelegate {
ArrayList<String> source_title = new ArrayList<String>();
private final double[] mImageAspectRatios;
private Context mContext;
public double aspectRatioForIndex(int index) {
// Precaution, have better handling for this in greedo-layout
if (index >= getItemCount()) return 1.0;
return mImageAspectRatios[getLoopedIndex(index)];
}
public class PhotoViewHolder extends RecyclerView.ViewHolder {
private ImageView mImageView;
public PhotoViewHolder(ImageView imageView) {
super(imageView);
mImageView = imageView;
}
}
public MoviesAdapter(Context context, ArrayList<String> image) {
mContext = context;
this.source_title = image;
mImageAspectRatios = new double[source_title.size()];
// calculateImageAspectRatios();
}
#Override
public PhotoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ImageView imageView = new ImageView(mContext);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
));
return new PhotoViewHolder(imageView);
}
#Override
public void onBindViewHolder(final PhotoViewHolder holder, int position) {
Picasso.with(mContext).load(source_title.get(position)).into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
holder.mImageView.setImageBitmap(bitmap);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
Log.d("bitmapfailed", "errorDrawable " + errorDrawable);
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
Log.d("onPrepareLoad", "placeHolderDrawable " + placeHolderDrawable);
}
});
}
#Override
public int getItemCount() {
return source_title.size();
}
// private void calculateImageAspectRatios() {
// BitmapFactory.Options options = new BitmapFactory.Options();
// options.inJustDecodeBounds = true;
//
// for (int i = 0; i < source_title.size(); i++) {
//
// int value = Integer.parseInt(source_title.get(i));
//
// BitmapFactory.decodeResource(mContext.getResources(), value, options);
// mImageAspectRatios[i] = options.outWidth / (double) options.outHeight;
// }
// }
// Index gets wrapped around <code>Constants.IMAGES.length</code> so we can loop content.
private int getLoopedIndex(int index) {
return index % source_title.size(); // wrap around
}
}
and this is the original demo code
public class PhotosAdapter extends RecyclerView.Adapter<PhotosAdapter.PhotoViewHolder> implements SizeCalculatorDelegate {
private static final int IMAGE_COUNT = 500; // number of images adapter will show
private final int[] mImageResIds = Constants.IMAGES;
private final double[] mImageAspectRatios = new double[mImageResIds.length];
private Context mContext;
#Override
public double aspectRatioForIndex(int index) {
// Precaution, have better handling for this in greedo-layout
if (index >= getItemCount()) return 1.0;
Log.d("index", mImageAspectRatios + "");
return mImageAspectRatios[getLoopedIndex(index)];
}
public class PhotoViewHolder extends RecyclerView.ViewHolder {
private ImageView mImageView;
public PhotoViewHolder(ImageView imageView) {
super(imageView);
mImageView = imageView;
}
}
public PhotosAdapter(Context context) {
mContext = context;
calculateImageAspectRatios();
}
#Override
public PhotoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ImageView imageView = new ImageView(mContext);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
));
return new PhotoViewHolder(imageView);
}
#Override
public void onBindViewHolder(PhotoViewHolder holder, int position) {
Picasso.with(mContext)
.load(mImageResIds[getLoopedIndex(position)])
.into(holder.mImageView);
}
#Override
public int getItemCount() {
return IMAGE_COUNT;
}
private void calculateImageAspectRatios() {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
for (int i = 0; i < mImageResIds.length; i++) {
BitmapFactory.decodeResource(mContext.getResources(), mImageResIds[i], options);
mImageAspectRatios[i] = options.outWidth / (double) options.outHeight;
}
}
// Index gets wrapped around <code>Constants.IMAGES.length</code> so we can loop content.
private int getLoopedIndex(int index) {
return index % Constants.IMAGES.length; // wrap around
}
}
in this demo the image shows properly but in my demo images not show, tha data from source_title arraylist is showing properly but this demo does not work properly, as I use onBindViewHolder method it goes into onPrepareLoad exception called null value of placeHolderDrawable...
Is there any solution to use it or some other method or way to solve this issue?
Sorry for my english and thnx in advance...
Related
developing an image picker using recyclerview with all images in devices for an android app, facing an issue when user scroll through images its memory usage keeps increasing eventually if lots of images there is oom exception, have searched for this issue over the internet, have applied several techniques but it is of little use, i have seen other app(whatsapp, olx) its picker scrolling is nice and no oom, i also tried dump heap in android studio to detect memory leakage, i found that there are as many viewholders as number of images, its not being recycled, am not able to find the reason, please help me in detecting the issue, attaching code..
/** adapter class for grid recyclerview*/
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private ArrayList<CreateList> galleryList;
private Context context;
private List<String> imageUrls = new ArrayList<>(3);
private List<Integer> positionList = new ArrayList<>(3);
int count = 0;
RequestOptions options;
RequestBuilder glide;
RequestManager glideMain;
int imgWidth;
public MyAdapter(Context context, ArrayList<CreateList> galleryList, RequestOptions options, RequestBuilder<Bitmap> glide, RequestManager glideMain, int imgWidth) {
this.galleryList = galleryList;
this.context = context;
this.options = options;
this.glide = glide;
this.glideMain = glideMain;
this.imgWidth = imgWidth;
}
#Override
public void onViewRecycled(#NonNull ViewHolder holder) {
holder.img.setOnClickListener(null);
holder.img.setColorFilter(null);
holder.img.setImageDrawable(null);
if(holder.title.getText().toString().equals("1")){
}
//holder.itemView.setOnClickListener(null);
glideMain.clear(holder.img);
super.onViewRecycled(holder);
}
#Override
public void onViewDetachedFromWindow(#NonNull ViewHolder holder) {
/* holder.img.setOnClickListener(null);
holder.img.setColorFilter(null);*/
holder.img.setImageDrawable(null);
// holder.itemView.setOnClickListener(null);
glideMain.clear(holder.img);
super.onViewDetachedFromWindow(holder);
}
#Override
public void onViewAttachedToWindow(#NonNull final ViewHolder holder) {
/* holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
holder.handleThumbnail(view);
}
});*/
super.onViewAttachedToWindow(holder);
}
public ArrayList<CreateList> getGalleryList() {
return galleryList;
}
public void setGalleryList(ArrayList<CreateList> galleryList) {
this.galleryList = galleryList;
}
public List<Integer> getPositionList() {
return positionList;
}
public void setPositionList(List<Integer> positionList) {
this.positionList = positionList;
}
public List<String> getImageUrls() {
return imageUrls;
}
public void setImageUrls(List<String> imageUrls) {
this.imageUrls = imageUrls;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cell_layout, viewGroup, false);
//img.setOnClickListener();
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final MyAdapter.ViewHolder viewHolder, int pos) {
glide
.load(galleryList.get(pos).getImage_Location())
.thumbnail(0.1F)
.apply(options)
.into(viewHolder.img);
if (positionList.contains(pos)){
// view not selected
//viewHolder.parent.setBackgroundColor(Color.LTGRAY);
viewHolder.title.setVisibility(View.VISIBLE);
viewHolder.title.setText(String.valueOf(positionList.indexOf(pos)+1));
viewHolder.img.setColorFilter(viewHolder.getColorWithAlpha(Color.GREEN, 0.3f));
}
}
#Override
public int getItemCount() {
return galleryList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView title;
private ImageView img;
public ViewHolder(View view) {
super(view);
title = (TextView)view.findViewById(R.id.highlightText);
img = (ImageView) view.findViewById(R.id.img);
/* view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
handleThumbnail(v);
}
});*/
/* img = view.findViewById(R.id.img);*/
img.setLayoutParams(new ConstraintLayout.LayoutParams(imgWidth, imgWidth));
/*img.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// This is OnClick of any list Item
handleThumbnail(v);
}
});*/
/* img.setOnTouchListener(new View.OnTouchListener() {
private Rect rect;
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
img.setColorFilter(Color.argb(50, 0, 0, 0));
rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
}
if(event.getAction() == MotionEvent.ACTION_UP){
img.setColorFilter(Color.argb(0, 0, 0, 0));
}
if(event.getAction() == MotionEvent.ACTION_MOVE){
if(!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())){
img.setColorFilter(Color.argb(0, 0, 0, 0));
}
}
return false;
}
});*/
}
public void handleThumbnail(View v) {
if(!imageUrls.contains(galleryList.get(getAdapterPosition()).getImage_Location())) {
if(count<3) {
positionList.add(getAdapterPosition());
String selectedImgUrl = galleryList.get(getAdapterPosition()).getImage_Location();
imageUrls.add(selectedImgUrl);
//img.setBackground(context.getResources().getDrawable(R.drawable.button_background_checked));
img.setColorFilter(getColorWithAlpha(Color.GREEN, 0.3f));
//title.setVisibility(View.VISIBLE);
//title.setText(String.valueOf(count+1));
//View viewSelected = gridRecycler.findViewHolderForAdapterPosition(position).itemView;
title.setVisibility(View.VISIBLE);
title.setText(String.valueOf(count+1));
count++;
} else {
Toast.makeText().show();
}
} else {
imageUrls.remove(galleryList.get(getAdapterPosition()).getImage_Location());
positionList.remove(new Integer(getAdapterPosition()));
//imageUrls.remove( Integer.parseInt(title.getText().toString()));
title.setVisibility(View.GONE);
count--;
// img.setBackground(context.getResources().getDrawable(R.drawable.button_background));
img.setColorFilter(Color.argb(0, 0, 0, 0));
EventBus.getDefault().post(new MessageEvent(imageUrls, positionList));
}
}
public int getColorWithAlpha(int color, float ratio) {
int newColor = 0;
int alpha = Math.round(Color.alpha(color) * ratio);
int r = Color.red(color);
int g = Color.green(color);
int b = Color.blue(color);
newColor = Color.argb(alpha, r, g, b);
return newColor;
}
}
activity code using background thread to load data and set in adapter:
private class PrepareData extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int imgWidth = (int) (displayMetrics.widthPixels*0.32);
RequestOptions options = new RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.override(imgWidth/3)
.dontAnimate()
.centerCrop()
.skipMemoryCache(true);
final RequestManager glide = Glide.with(gridRecycler.getContext());
RequestBuilder builder = glide.asBitmap();
gridRecycler.setHasFixedSize(true);
final RecyclerView.LayoutManager layoutManager = new GridLayoutManager(gridRecycler.getContext(), 3);
createLists = getAllFolderImages(this);
adapter = new MyAdapter(this, createLists, options, builder, glide, imgWidth);
gridRecycler.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
glide.resumeRequests();
}
if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL || newState==AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
glide.pauseRequests();
System.gc();
}
}
});
runOnUiThread(new Runnable() {
#Override
public void run() {
gridRecycler.setLayoutManager(layoutManager);
gridRecycler.setAdapter(adapter);
//put the code here that is giving exception
}
});
return null;
}
}
android profiling screen-shot, its visible that viewholder is consuming lots of memory and has lots of instances.
This is my PhotosAdapter class for loading images with changing heigh or width.
import com.fivehundredpx.greedolayout.GreedoLayoutSizeCalculator.SizeCalculatorDelegate;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target;
import java.util.ArrayList;
/**
* Created by Julian Villella on 16-02-24.
*/
public class PhotosAdapter extends RecyclerView.Adapter<PhotosAdapter.PhotoViewHolder> implements SizeCalculatorDelegate {
private static final int IMAGE_COUNT = 500;
// private final double[] mImageAspectRatios = new double[Constants.IMAGES.length];
ArrayList<String> source_title = new ArrayList<String>();
ArrayList<String> mImageResIds = new ArrayList<String>();
private Context mContext;
// #Override
// public double aspectRatioForIndex(int index) {
// // Precaution, have better handling for this in greedo-layout
// if (index >= getItemCount()) return 1.0;
// return mImageAspectRatios[getLoopedIndex(index)];
// }
#Override
public double aspectRatioForIndex(int index) {
// Precaution, have better handling for this in greedo-layout
if (index >= getItemCount()) return 1.0;
return mImageResIds.size();
}
public class PhotoViewHolder extends RecyclerView.ViewHolder {
private ImageView mImageView;
public PhotoViewHolder(ImageView imageView) {
super(imageView);
mImageView = imageView;
Log.d("PhotoViewHolderimage", imageView + "");
}
}
public PhotosAdapter(Context context, ArrayList<String> source_title, ArrayList<String> source_filepath) {
mContext = context;
this.mImageResIds = source_filepath;
this.source_title = source_title;
Log.d("start", "start" + mImageResIds);
// calculateImageAspectRatios();
}
#Override
public PhotoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ImageView imageView = new ImageView(mContext);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
));
Log.d("PhotoViewHoldermake", imageView + "");
return new PhotoViewHolder(imageView);
}
#Override
public void onBindViewHolder(final PhotoViewHolder holder, int position) {
// Picasso.with(mContext)
// .load(mImageResIds.get(position))
// .into(holder.mImageView);
Log.d("onBindViewHolder", holder + "");
Log.d("mImageResIds", mImageResIds.get(position));
Picasso.with(mContext).load(mImageResIds.get(position)).into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
holder.mImageView.setImageBitmap(bitmap);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
Log.d("Imageloadingfailed", " " + errorDrawable);
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
Log.d("Imageloading", "placeHolderDrawable " + placeHolderDrawable);
}
});
}
#Override
public int getItemCount() {
return mImageResIds.size();
}
// private void calculateImageAspectRatios() {
// BitmapFactory.Options options = new BitmapFactory.Options();
// options.inJustDecodeBounds = true;
//
// for (int i = 0; i < mImageResIds.size(); i++) {
// BitmapFactory.decodeResource(mContext.getResources(), mImageResIds.indexOf(i), options);
// mImageAspectRatios[i] = options.outWidth / (double) options.outHeight;
// }
// }
// Index gets wrapped around <code>Constants.IMAGES.length</code> so we can loop content.
// private int getLoopedIndex(int index) {
// return index % Constants.IMAGES.length; // wrap around
// }
}
When this class run , data is there but not showing the image ,the onBindViewHolder method runs and there is an issue and due to this issue the picasso Override method onPrepareLoad and it shows the placeHolderDrawable null exception
i m using this code as reference https://github.com/500px/greedo-layout-for-android
If any one have any solution or any suggestion regarding this issue please help me out of this issue.
Sorry for my english and thanks in advance.
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 found a tutorial on the Internet for an image slider but I don't know how to make it work on my phone. In the emulator it is giving me a message about setting nat directory path. I don't know how to do that. . .
Could anyone help me, please?
Code for Activities are:
Code for FullScreenViewActivity.java:
public class FullScreenViewActivity extends Activity{
private Utils utils;
private FullScreenImageAdapter adapter;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fullscreen_view);
viewPager = (ViewPager) findViewById(R.id.pager);
utils = new Utils(getApplicationContext());
Intent i = getIntent();
int position = i.getIntExtra("position", 0);
adapter = new FullScreenImageAdapter(FullScreenViewActivity.this,
utils.getFilePaths());
viewPager.setAdapter(adapter);
// displaying selected image first
viewPager.setCurrentItem(position);
}
}
Code for GridViewActivity.java:
public class GridViewActivity extends Activity {
private Utils utils;
private ArrayList<String> imagePaths = new ArrayList<String>();
private GridViewImageAdapter adapter;
private GridView gridView;
private int columnWidth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grid_view);
gridView = (GridView) findViewById(R.id.grid_view);
utils = new Utils(this);
// Initilizing Grid View
InitilizeGridLayout();
// loading all image paths from SD card
imagePaths = utils.getFilePaths();
// Gridview adapter
adapter = new GridViewImageAdapter(GridViewActivity.this, imagePaths,
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);
}
}
Code for FullScreenImageAdapter.java:
public class FullScreenImageAdapter extends PagerAdapter {
private Activity _activity;
private ArrayList<String> _imagePaths;
private LayoutInflater inflater;
// constructor
public FullScreenImageAdapter(Activity activity,
ArrayList<String> imagePaths) {
this._activity = activity;
this._imagePaths = imagePaths;
}
#Override
public int getCount() {
return this._imagePaths.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((RelativeLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
TouchImageView imgDisplay;
Button btnClose;
inflater = (LayoutInflater) _activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View viewLayout = inflater.inflate(R.layout.layout_fullscreen_image, container,
false);
imgDisplay = (TouchImageView) viewLayout.findViewById(R.id.imgDisplay);
btnClose = (Button) viewLayout.findViewById(R.id.btnClose);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(_imagePaths.get(position), options);
imgDisplay.setImageBitmap(bitmap);
// close button click event
btnClose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
_activity.finish();
}
});
((ViewPager) container).addView(viewLayout);
return viewLayout;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((RelativeLayout) object);
}
}
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);
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);
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;
}
}
Code for GridViewImageAdapter.java:
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);
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);
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;
}
}
util.java
public class Utils {
private Context _context;
// constructor
public Utils(Context context) {
this._context = context;
}
/*
* Reading file paths from SDCard
*/
public ArrayList<String> getFilePaths() {
ArrayList<String> filePaths = new ArrayList<String>();
File directory = new File(
android.os.Environment.getExternalStorageDirectory()
+ File.separator + AppConstant.PHOTO_ALBUM);
// check for directory
if (directory.isDirectory()) {
// getting list of file paths
File[] listFiles = directory.listFiles();
// Check for count
if (listFiles.length > 0) {
// loop through all files
for (int i = 0; i < listFiles.length; i++) {
// get file path
String filePath = listFiles[i].getAbsolutePath();
// check for supported file extension
if (IsSupportedFile(filePath)) {
// Add image path to array list
filePaths.add(filePath);
}
}
} else {
// image directory is empty
Toast.makeText(
_context,
AppConstant.PHOTO_ALBUM
+ " is empty. Please load some images in it !",
Toast.LENGTH_LONG).show();
}
} else {
AlertDialog.Builder alert = new AlertDialog.Builder(_context);
alert.setTitle("Error!");
alert.setMessage(AppConstant.PHOTO_ALBUM
+ " directory path is not valid! Please set the image directory name AppConstant.java class");
alert.setPositiveButton("OK", null);
alert.show();
}
return filePaths;
}
/*
* Check supported file extensions
*
* #returns boolean
*/
private boolean IsSupportedFile(String filePath) {
String ext = filePath.substring((filePath.lastIndexOf(".") + 1),
filePath.length());
if (AppConstant.FILE_EXTN
.contains(ext.toLowerCase(Locale.getDefault())))
return true;
else
return false;
}
/*
* getting screen width
*/
public int getScreenWidth() {
int columnWidth;
WindowManager wm = (WindowManager) _context
.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
final Point point = new Point();
try {
display.getSize(point);
} catch (java.lang.NoSuchMethodError ignore) { // Older device
point.x = display.getWidth();
point.y = display.getHeight();
}
columnWidth = point.x;
return columnWidth;
}
}
AppConstant.java
public class AppConstant {
// Number of columns of Grid View
public static final int NUM_OF_COLUMNS = 3;
// Gridview image padding
public static final int GRID_PADDING = 8; // in dp
// SD card image directory
public static final String PHOTO_ALBUM = "NAT";
// supported file formats
public static final List<String> FILE_EXTN = Arrays.asList("jpg", "jpeg",
"png");
}
The only problem is setting the nat directory path so that it works on my phone.
I had the same problem (same tutorial :D), the problem is that you need a place to store all the wallpapers, so just change
// SD card image directory
public static final String PHOTO_ALBUM = "NAT";
to
// SD card image directory
public static final String PHOTO_ALBUM = "Camera";
for example to show the cameras pics.
public static final String PHOTO_ALBUM =Environment.getExternalStorageDirectory().getPath()+ "/DCIM/"+"/100ANDRO/";
"/DCIM/100ANDRO/" is a path where my Pictures are stored.
just change NAT by DCIM/Camera here your internal phone memory pics. i tried this and its work but some other problem occurs, when i click any pic then application is force stop if you resolve this problem then let m know. thank you