I have 92 images and I would like to have an indicator such as a check mark to indicate that an image is unlocked. I have the check mark in a .png file and what I tried at first was to just make a seperate copy of each image with the check mark put on top of the image in photoshop. However I know that there must be a simpler way of just adding the check mark file on top of the image that is already there instead of having a copy of the image with the check mark already on it.
I have a GridViewAdapter class responsible for loading the original images into a gridview:
#Override public View getView(int position, View convertView, ViewGroup parent) {
SquaredImageView view = (SquaredImageView) convertView;
if (view == null) {
view = new SquaredImageView(context);
view.setScaleType(CENTER_CROP);
}
// Get the image URL for the current position.
Integer url = getItem(position);
// Trigger the download of the URL asynchronously into the image view.
Picasso.with(context) //
.load(url) //
//
.error(R.drawable.error) //
.fit() //
.into(view);
return view;
}
where url is a list that contains the references to each image to be loaded
the mentioned SquaredImageView class is:
/** An image view which always remains square with respect to its width. */
final class SquaredImageView extends ImageView {
public SquaredImageView(Context context) {
super(context);
}
public SquaredImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth());
}
}
Any suggestions are appreciated
I can think of a few ways to do this:
Option 1:
Wrap the SquaredImageView in a Framelayout and place another SqauredImageView inside of it. Set the check mark on the second image view.
Option 2:
Wrap the SquaredImageView in a FrameLayout and set the checkmark image on the foreground property of the FrameLayout (using setForeground).
Option 3:
Create a ForegroundSquaredImageView which supports overlaying an image (similar to the foreground property of FrameLayout).
The code for something like this can be found here: https://gist.github.com/JakeWharton/0a251d67649305d84e8a. You'll need to change it to extend from your SquaredImageView.
Related
I have a RecyclerView adapter that looks like this:
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private static Context context;
private List<Message> mDataset;
public RecyclerAdapter(Context context, List<Message> myDataset) {
this.context = context;
this.mDataset = myDataset;
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener, View.OnClickListener {
public TextView title;
public LinearLayout placeholder;
public ViewHolder(View view) {
super(view);
view.setOnCreateContextMenuListener(this);
title = (TextView) view.findViewById(R.id.title);
placeholder = (LinearLayout) view.findViewById(R.id.placeholder);
}
}
#Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_layout, parent, false);
ViewHolder vh = new ViewHolder((LinearLayout) view);
return vh;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Message item = mDataset.get(position);
holder.title.setText(item.getTitle());
int numImages = item.getImages().size();
if (numImages > 0) {
View test = LayoutInflater.from(holder.placeholder.getContext()).inflate(R.layout.images, holder.placeholder, false);
ImageView image = (ImageView) test.findViewById(R.id.image);
Glide.with(context)
.load("http://www.website.com/test.png")
.fitCenter()
.into(image);
holder.placeholder.addView(test);
}
}
#Override
public int getItemCount() {
return mDataset.size();
}
}
However, some of the items in the RecyclerView are showing images when they shouldn't be. How can I stop this from happening?
I do the check if (numImages > 0) { in onBindViewHolder(), but that's still not stopping it from showing images for items that shouldn't have images.
You should set imageView.setImageDrawable (null)
In onBindViewHolder() before setting the image using glide.
Setting image drawable to null fix the issue.
Hope it helps!
The problem is in onBindViewHolder, here:
if (numImages > 0) {
View test = LayoutInflater.from(holder.placeholder.getContext()).inflate(R.layout.images, holder.placeholder, false);
ImageView image = (ImageView) test.findViewById(R.id.image);
Glide.with(context)
.load("http://www.website.com/test.png")
.fitCenter()
.into(image);
holder.placeholder.addView(test);
}
If numImages is equal to 0, you're simply allowing the previously started load into the view you're reusing to continue. When it finishes, it will still load the old image into your view. To prevent this, tell Glide to cancel the previous load by calling clear:
if (numImages > 0) {
View test = LayoutInflater.from(holder.placeholder.getContext()).inflate(R.layout.images, holder.placeholder, false);
ImageView image = (ImageView) test.findViewById(R.id.image);
Glide.with(context)
.load("http://www.website.com/test.png")
.fitCenter()
.into(image);
holder.placeholder.addView(test);
} else {
Glide.clear(image);
}
When you call into(), Glide handles canceling the old load for you. If you're not going to call into(), you must call clear() yourself.
Every call to onBindViewHolder must include either a load() call or a clear() call.
I also had issues with RecyclerView showing wrong images. This happens because RecyclerView is not inflating view for every new list item: instead list items are being recycled.
By recycling views we can ruffly understand cloning views. A cloned view might have an image set from the previous interaction.
This is especially fair if your are using Picasso, Glide, or some other lib for async loading. These libs hold reference to an ImageView, and set an image on that refference when image is loaded.
By the time the image gets loaded, the item view might have gotten cloned, and the image is going to be set to the wrong clone.
To make a long story short, I solved this problem by restricting RecyclerView from cloning my item views:
setIsRecyclable(false)in ViewHolder constructor.
Now RecyclerView is working a bit slower, but at least the images are set right.
Or else cansel loading image in onViewRecycled(ViewHolder holde)
The issue here is that, as you are working with views that are going to be recycled, you'll need to handle all the possible scenarios at the time your binding your view.
For example, if you're adding the ImageView to the LinearLayout on position 0 of the data source, then, if position 4 doesn't met the condition, its view will most likely have the ImageView added when binding position 0.
You can add the content of R.layout.images content inside your
R.layout.message_layout layout's R.id.placeholder and showing/hiding the placeholder depending on the case.
So, your onBindViewHolder method would be something like:
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Message item = mDataset.get(position);
holder.title.setText(item.getTitle());
int numImages = item.getImages().size();
if (numImages > 0) {
holder.placeholder.setVisivility(View.VISIBLE);
ImageView image = (ImageView)holder.placeholder.findViewById(R.id.image);
Glide.with(context)
.load("http://www.website.com/test.png")
.fitCenter()
.into(image);
}else{
holder.placeholder.setVisibility(View.INVISIBLE);
}
}
Sometimes when using RecyclerView, a View may be re-used and retain the size from a previous position that will be changed for the current position. To handle those cases, you can create a new [ViewTarget and pass in true for waitForLayout]:
#Override
public void onBindViewHolder(VH holder, int position) {
Glide.with(fragment)
.load(urls.get(position))
.into(new DrawableImageViewTarget(holder.imageView,/*waitForLayout=*/ true));
https://bumptech.github.io/glide/doc/targets.html
I also had the same problem and ended with below solution and it working fine for me..
Have your hands on this solution might be work for you too (Put below code in your adapter class)-
If you are using Kotlin -
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getItemViewType(position: Int): Int {
return position
}
If you are using JAVA -
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
This works for me in onBindViewHolder!
if(!m.getPicture().isEmpty())
{
holder.setIsRecyclable(false);
Picasso.with(holder.profile_pic.getContext()).load(m.getPicture()).placeholder(R.mipmap.ic_launcher_round).into(holder.profile_pic);
Animation fadeOut = new AlphaAnimation(0, 1);
fadeOut.setInterpolator(new AccelerateInterpolator());
fadeOut.setDuration(1000);
holder.profile_pic.startAnimation(fadeOut);
}
else
{
holder.setIsRecyclable(true);
}
I was having same issue I solved by writing holder.setIsRecyclable(false).Worked for me.
#Override
public void onBindViewHolder(#NonNull RecylerViewHolder holder, int position) {
NewsFeed currentFeed = newsFeeds.get(position);
holder.textView.setText(currentFeed.getNewsTitle());
holder.sectionView.setText(currentFeed.getNewsSection());
if(currentFeed.getImageId() == "NOIMG") {
holder.setIsRecyclable(false);
Log.v("ImageLoad","Image not loaded");
} else {
Picasso.get().load(currentFeed.getImageId()).into(holder.imageView);
Log.v("ImageLoad","Image id "+ currentFeed.getImageId());
}
holder.dateView.setText(getModifiedDate(currentFeed.getDate()));
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getItemViewType(position: Int): Int {
return position
}
This Works for Me
I Had the same issue and i fixed it like this:
GOAL : onViewAttachedToWindow
#Override
public void onViewAttachedToWindow(Holder holder) {
super.onViewAttachedToWindow(holder);
StructAllItems sfi = mArrayList.get(position);
if (!sfi.getPicHayatParking().isEmpty()) {
holder.viewFliperMelk.addSlider(new TextSliderView(mContext.getApplicationContext()).image(T.GET_MELK_IMAGE + '/' + sfi.getPicHayatParking() + ".jpg").setScaleType(BaseSliderView.ScaleType.CenterCrop));
}
if (!sfi.getPicSleepRoom().isEmpty()) {
holder.viewFliperMelk.addSlider(new TextSliderView(mContext.getApplicationContext()).image(T.GET_MELK_IMAGE + '/' + sfi.getPicSleepRoom() + ".jpg").setScaleType(BaseSliderView.ScaleType.CenterCrop));
}
if (!sfi.getPicSalonPazirayi().isEmpty()) {
holder.viewFliperMelk.addSlider(new TextSliderView(mContext.getApplicationContext()).image(T.GET_MELK_IMAGE + '/' + sfi.getPicSalonPazirayi() + ".jpg").setScaleType(BaseSliderView.ScaleType.CenterCrop));
}
if (!sfi.getPicNamayeStruct().isEmpty()) {
holder.viewFliperMelk.addSlider(new TextSliderView(mContext.getApplicationContext()).image(T.GET_MELK_IMAGE + '/' + sfi.getPicNamayeStruct() + ".jpg").setScaleType(BaseSliderView.ScaleType.CenterCrop));
}
}
I had a similar issue when getting pictures from the photo gallery and putting them in a recyclerview with GridLayoutManager(never had the issue with Glide). So in the adapter onBindViewHolder use a HashMap or SparseIntArray to put the current hashcode(this is the common thing that the recycled views have in common) and adapter position inside it. Then call your background task and then once it's done and before you set the image, check to see if the hashcode key - which will always have the current adapter position as the value - still has the same value (adapter position) as when you first called the background task.
(Global variable)
private SparseIntArray hashMap = new SparseIntArray();
onBindViewHolder(ViewHolder holder, int position){
holder.imageView.setImageResource(R.drawable.grey_square);
hashMap.put(holder.hashCode(), position);
yourBackgroundTask(ViewHolder holder, int position);
}
yourBackGroundTask(ViewHolder holder, int holderPosition){
do some stuff in the background.....
*if you want to stop to image from downloading / or in my case
fetching the image from MediaStore then do -
if(hashMap.get(holder.hashCode())!=(holderPos)){
return null;
}
- in the background task, before the call to get the
image
onPostExecute{
if(hashMap.get(holder.hashCode())==(holderPosition)){
holder.imageView.setImageBitmap(result);
}
}
}
So i am just providing an extension to this answer since there is not much space to leave it as comment.
After trying out like mentioned in one of above solutions i found out that, the real issue can still be addressed even if you are using a static resource(is not being downloaded and is available locally)
So basically on onBindViewHolder event i just converted the resource to drawable and added it like below :
imageView.setImageDrawable(ContextCompat.getDrawable(context,R.drawable.album_art_unknown));
this way you wont have an empty space on the view while glide/async downloader is loading the actual image from network.
plus looking at that being reloaded every time i also added below code while calling the recycler adapter class;
recyclerView.setItemViewCacheSize(10);
recyclerView.setDrawingCacheEnabled(true);
so by using above way you wont need to set setIsRecyclable(false) which is degrading if you have larger datasets.
By doing this i you will have a flicker free loading of recyclerview of course except for the initial loads.
I would like to say that if you send the ImageView and any load-async command (for instance loading from S3), the recycler view does get confused.
I did set the bitmap null in the onViewRecycled and tested with attach and detach views etc. the issue never went away.
The issue is that if a holderView gets used for image-1, image-10 and stops at the scroll with image-19, what the user sees is image-1, then image-10 and then image-19.
One method that worked for me is to keep a hash_map that helps know what is the latest image that needs to be displayed on that ImageView.
Remember, the holder is recycled, so the hash for that view is persistent.
1- Create this map for storing what image should be displayed,
public static HashMap<Integer, String> VIEW_SYNCHER = new HashMap<Integer, String>();
2- In your Adapter, onBindViewHolder,
String thumbnailCacheKey = "img-url";
GLOBALS.VIEW_SYNCHER.put(holder.thumbnailImage.hashCode(), thumbnailCacheKey);
3- Then you have some async call to make the network call and load the image in the view right ?
In that code after loading the image from S3, you test to make sure what goes into the View,
// The ImageView in the network data loader, get its hash.
int viewCode = iim.imView[0].hashCode();
if (GLOBALS.VIEW_SYNCHER.containsKey(viewCode))
if (GLOBALS.VIEW_SYNCHER.get(viewCode).equals(bitmapKey))
iim.imView[0].setImageBitmap(GLOBALS.BITMAP_CACHE.get(bitmapKey).bitmapData);
So essentially, you make sure what is the last image key that should go into a view, then when you download the image you check to make sure that's the last image URL that goes in that view.
This solution worked for me.
This is my first post...im a beginner trying to make an app for android.
im trying to make a simple match game using a deck of playing cards. Ive been able to get open source svg and png playing cards online. They either come in individual cards images (in png or svg formats) or one image (svg or png) with every card spaced nicely with a contrast background.
With all of the research ive done, i try to utilize these svg or png files but run into either out of memory issues or very slow UX performance.
My goal is to get a gridview to show all 52 cards that swipe horizontally. and if i click on a card, and match its face...then i get a point.
heres my layout activty_play_board.xml
just have one item...a gridview:
<GridView
android:id="#+id/gridView"
android:layout_width="match_parent"
android:layout_height="540dp"
android:horizontalSpacing="2dp"
android:numColumns="4"
android:stretchMode="columnWidth"
android:verticalSpacing="2dp" />
I use this public class that i got from googles dev website. it allows me to fill in the gridview with the svg or png cards
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, 270));
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.setPadding(4,4, 4, 4);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
private Integer[] mThumbIds = {
R.drawable.two_of_clubs,
R.drawable.two_of_diamonds,
R.drawable.two_of_hearts,
R.drawable.two_of_spades,
R.drawable.three_of_clubs,
R.drawable.three_of_diamonds,
R.drawable.three_of_hearts,
R.drawable.three_of_spades,
R.drawable.four_of_clubs,
R.drawable.four_of_diamonds,
R.drawable.four_of_hearts,
R.drawable.four_of_spades,
R.drawable.five_of_clubs,
R.drawable.five_of_diamonds,
R.drawable.five_of_hearts,
R.drawable.five_of_spades,
R.drawable.six_of_diamonds,
R.drawable.six_of_hearts,
R.drawable.six_of_spades,
R.drawable.six_of_clubs,
R.drawable.seven_of_diamonds,
R.drawable.seven_of_hearts,
R.drawable.seven_of_spades,
R.drawable.seven_of_clubs,
R.drawable.eight_of_diamonds,
R.drawable.eight_of_hearts,
R.drawable.eight_of_clubs,
R.drawable.eight_of_spades,
R.drawable.nine_of_diamonds,
R.drawable.nine_of_hearts,
R.drawable.nine_of_spades,
R.drawable.nine_of_clubs,
R.drawable.ten_of_clubs,
R.drawable.ten_of_diamonds,
R.drawable.ten_of_hearts,
R.drawable.ten_of_spades,
R.drawable.jack_of_clubs,
R.drawable.jack_of_diamonds,
R.drawable.jack_of_hearts,
R.drawable.jack_of_spades,
R.drawable.queen_of_clubs,
R.drawable.queen_of_diamonds,
R.drawable.queen_of_hearts,
R.drawable.queen_of_spades,
R.drawable.king_of_spades,
R.drawable.king_of_clubs,
R.drawable.king_of_diamonds,
R.drawable.king_of_hearts,
R.drawable.ace_of_spades,
R.drawable.ace_of_diamonds,
R.drawable.ace_of_hearts,
R.drawable.ace_of_clubs
};}
heres my onCreate:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grid_board);
Button goBackOnClick = (Button) findViewById(R.id.playBoardButton);
GridView gridview = (GridView) findViewById(R.id.gridView);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(newAdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
Toast.makeText(GridBoard.this, "Spot: " + position, Toast.LENGTH_LONG).show();
}
});
I have several questions.
How do i utilize the SVG file? am i calling the one big svg file and then referencing a specific location on the file when i call it for an imageview within my gridview?
i dont know how to use the one big SVG file, so ive tried using the individual svg images. but when i do that, my device is very laggy and slow. also sometimes the app crashes due to out of memory errors. Is there a special syntax to use when trying to reference a specific card within the large SVG file? Or do i have to manually edit the big svg file and get the smaller cards?
Is there a better way to do this than using a gridview?
any other general guidance would be greatly appreciated.
Thank you!
Heres my card sources:
one big palette
https://upload.wikimedia.org/wikipedia/commons/8/81/English_pattern_playing_cards_deck.svg
individual cards and one big palette
http://byronknoll.blogspot.com/2011/03/vector-playing-cards.html
I've got the following code from "Android in Practice" book. It's implementation of custom adapter which downloads images from the internet. It uses private class RetrieveImageTask to retrieve pictures.
Can someone explain me why the first thing the adapter class does is to get image from the cache instead of downloading it ? I understand it in a way that, the first time it displays
default image which was set in the beginning of getView(), then sets downloaded image, but does it mean that view is being refreshed constantly by calling getView() ?
And why author sets tag of image to item ID in getView() and then sets it to null in onPostExecute() ?
DealsAdapter
private class DealsAdapter extends ArrayAdapter<Item> {
public DealsAdapter(List<Item> items) {
super(DealList.this, R.layout.list_item, items);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_item, parent, false);
}
// use ViewHolder here to prevent multiple calls to findViewById (if you have a large collection)
TextView text = (TextView) convertView.findViewById(R.id.deal_title);
ImageView image = (ImageView) convertView.findViewById(R.id.deal_img);
image.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.ddicon));
Item item = getItem(position);
if (item != null) {
text.setText(item.getTitle());
Bitmap bitmap = app.getImageCache().get(item.getItemId()); //<------HERE
if (bitmap != null) {
image.setImageBitmap(bitmap);
} else {
// put item ID on image as TAG for use in task
image.setTag(item.getItemId());
// separate thread/via task, for retrieving each image
// (note that this is brittle as is, should stop all threads in onPause)
new RetrieveImageTask(image).execute(item.getSmallPicUrl());
}
}
return convertView;
}
}
RetriveImageTask
private class RetrieveImageTask extends AsyncTask<String, Void, Bitmap> {
private ImageView imageView;
public RetrieveImageTask(ImageView imageView) {
this.imageView = imageView;
}
#Override
protected Bitmap doInBackground(String... args) {
Bitmap bitmap = app.retrieveBitmap(args[0]);
return bitmap;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
app.getImageCache().put((Long) imageView.getTag(), bitmap);
imageView.setTag(null);
}
}
}
Its called lazy loading. well images take time to download from net so by that some dummy image is set. As the downloading completes it will replaced with dummy image. Basically is matter of user experience with application.
the tag has something to do with how the cache mechanism of your code works- the key of the items is their number in this sample , meaning it is used to identify which image was downloaded so that you could load it from the cache instead of from the internet.
i agree that it's weird, as it could simply put the url of the image instead. using the url is more logical .
the sample isn't so efficient as it doesn't use the viewHolder design pattern (you can learn about it via the lecture "the world of listView") and doesn't have downsampling in mind (you can check out this post about it).
the image that is shown before showing the correct image is for showing the user that it's being prepared (like a placeholder saying "downloading...").
it's just a sample for you to learn from.
https://github.com/nostra13/Android-Universal-Image-Loader
It works beautifuly except for the very first item in a listview is having its image loading task canceled.
It says it Is called when image loading task was cancelled because View for image was reused in newer task
however since the view is clearly still visible, this view shouldn't be recycled yet? I am using convertView.
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
if (getItemViewType(position) == HAS_IMAGE)
{
if (convertView == null)
{
convertView = li.inflate(R.layout.item_update_pic, null);
new UpdateWithImageWrapper(convertView, position); // this is where views are looked up and set
}
((UpdateWithImageWrapper) convertView.getTag()).setMyData(data.get(position), position); // this is where the correct data is set to the views and images are set to be loaded
}
else
{
if (convertView == null)
{
convertView = li.inflate(R.layout.item_update, null);
new UpdateNoImageWrapper(convertView, position);
}
((UpdateNoImageWrapper) convertView.getTag()).setMyData(data.get(position), position);
}
return convertView;
}
Does anyone have solution?
Edit: just wanted to add that it has the issue with all of my list views.
using ImageLoader 1.8.4
Perhaps there is a way to stop the listview from recycling so quickly?
I finally figured out the real answer.
in my ImageLoadingListener()
#Override
public void onLoadingCancelled(String imageUri, View view) { }
I was setting the image to a image that represented a loading error. Well as it turns out, that if i do not change the image when this method is called then everything works fine.
So the real issue for me is that when the onLoadingCancelled method is called, the image has already been loaded, and setting the imageview here to a image representing a cancel overwrites a successful loading of the real image.
Blatant n00b question: I have several directories of pictures and wish to display randomly pictures from only one, which I select by a set of radio buttons. How do I specify the directory when using :
//"ha" is ha.png, which I would like to be at drawable/1/ha.png
image.setImageResource(R.drawable.ha);
Can I use setImageResource for this? If so how? If not, what should I use and how?
The object of the exercise is a flashcard program with different lessons (hence the dividing up of images) selectable at the first activity.
You cannot have subfolders under res/drawable, if you are referring to the drawables folder in your apk.
If you are referring to a random folder on your sdcard, then it's fine to use subfolders, but then you cannot use R.drawable.* for that approach to refer to the image.
In that case you need to load the image using
Bitmap bmp = BitmapFactory.decodeFile("/sdcard/drawable/1/ha.png");
which returns a bitmap, which you can use like
image.setImageBitmap(bmp)
see http://developer.android.com/reference/android/widget/ImageView.html#setImageBitmap(android.graphics.Bitmap)
In order to react on changes made to the radion button, see
How to set On click listener on the Radio Button in android
You can use a GridView to show the images from a directory selected from a radio button (as your requirement says). After creating a GridView, associate a adapter to it. Please refer below for a n example adapter :
public class ImageAdapter extends BaseAdapter {
/** LayoutInflater. */
private LayoutInflater mInflater;
/** The i. */
private ImageView i;
/**
* Instantiates a new image adapter.
*
* #param c
* the c
*/
public ImageAdapter(Context c) {
mInflater = LayoutInflater.from(c);
}
public int getCount() {
// scaled pictures will have the list of
// which you have from the directory
return scaledPictures.size();
}
public Bitmap getItem(int position) {
return scaledPictures.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.image, parent, false);
} else {
i = (ImageView) convertView;
}
Bitmap bitmap = getItem(position);
i = (ImageView) convertView.findViewById(R.id.galleryimage);
i.setImageBitmap(bitmap);
bitmap = null;
return i;
}
}