I have a custom adapter which is supposed to contain image buttons. However, I am bit confused on the implementation of the override for the getView() method. Since my image buttons are defined dynamically, I am able to recover an image button by using the code
#Override
public View getView(int i, View view, ViewGroup viewGroup){
ImageButton ibutton = (ImageButton) getItem(i);
How do I return its view? I have not specifically created an xml file for it since it is just an ImageButton (not in combination with anything else), but is it necessary to create an xml for it? Or is there a way to easily get the view from the imagebutton itself.
When I try this for getView(), the imagebutton is not clickable for some reason.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageButton imageButton = getItem(position);
return imageButton ;
}
Try to build you adapter something like this:
public class ImageButtonAdapter extends BaseAdapter {
private Context mContext;
// Constructor
public ImageButtonAdapter(Context c) {
mContext = c;
}
public int getCount() {
return listCount;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageButton for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageButton imageButton ;
if (convertView == null) {
imageButton = new ImageButton (mContext);
imageButton.setLayoutParams(lp);
}
else
{
imageButton = (ImageButton ) convertView;
}
imageButton.setBackgroundColor(Color.TRANSPARENT)
return imageButton ;
}
}
Related
I am new to android and I'm trying to figure out how to create a gallery of ImageViews on an app.
I have a server running that serves the images to the app which download correctly into a Arraylist of ImageViews.
I just need to add all of these images to a grid view.
I know I need to use an adaptor but I don't know how.
This is the code I have in my activity (images is populated else where)
ArrayList<ImageView> images = new ArrayList<>();
GridView table = (GridView) findViewById(R.id.table);
table.setAdapter(new ImageAdaptor(this.getBaseContext(), images));
And this is my adaptor
public class ImageAdaptor extends BaseAdapter{
private Context context;
private ArrayList<ImageView> images;
public ImageAdaptor(Context context, ArrayList<ImageView> images){
this.context = context;
this.images = images;
}
public int getCount(){
return this.images.size();
}
public Object getItem(int position){
return this.images.get(position);
}
public long getItemId(int position){
return position;
}
public View getView(int position, View convertView, ViewGroup parent){
ImageView image;
if (convertView == null){
image = new ImageView(this.context);
image.setLayoutParams(new GridView.LayoutParams(115, 115));
image.setScaleType(ImageView.ScaleType.CENTER_CROP);
}else{
image = (ImageView) convertView;
}
return image;
}
}
First thing, you should not make the arraylist of views as it wont be efficient for reusing views. However if you still want to do that, then solution is ,
public View getView(int position, View convertView, ViewGroup parent){
return images.get(position);
}
I have an Activity with a ListView. This ListView is set with the Class GetAllEntrysListViewAdapter:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ListCell cell;
if (convertView == null) {
convertView = inflater.inflate(R.layout.get_all_entry_list_view_cell, null);
cell = new ListCell();
cell.note = (TextView) convertView.findViewById(R.id.listViewNote);
cell.img = (ImageView) convertView.findViewById(R.id.listViewImg);
cell.likeButton = (ImageButton) convertView.findViewById(R.id.heartImage);
convertView.setTag(cell);
}
else {
cell = (ListCell)convertView.getTag();
}
public static class ListCell {
private TextView note;
private ImageView img;
public ImageButton likeButton;
}
In the Activity I now want to change the Image of likeButton on the certain list entry that is clicked, but how can I reach this certain element? Her is what I have until now:
GetAllEntrysListViewAdapter.ListCell listCell;
listCell = new GetAllEntrysListViewAdapter.ListCell();
getALlEntrysListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
// Get the likeButton of this entry and change the Image
Try this code. Replace your
getALlEntrysListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
// Get the likeButton of this entry and change the Image
}
with
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
//first get the elements by doing like
TextView note = (TextView)view.findViewById(R.id.listViewNote);
ImageView img = (ImageView) view.findViewById(R.id.listViewImg);
ImageButton likeButton = (ImageButton) convertView.findViewById(R.id.heartImage);
likeButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
likeButton.setBackgroundResource(R.id.icon);
}
});
}
This will be helpful ...thanks
That part should be done in getView() method itself. It should work like this.
Set data in your Adapter
Display data in getView for each item
Once you Like any item, update data with new Like status
Now call notifyDatasetChanged() on your adapter, getView() will update item view accordingly.
You should read ListAdapter first, and see some examples how it works.
I am trying to implement a listview that displays a list of directories. and under each directory is a gridview with associated adapter (shown below) showing a list of image thumbnails (see below image). I have it working great except whenever the list item is off the screen then brought back on screen, the images are reloaded. I am using an asynctask to download the thumbnails and replace the placeholder image for each imageview so it is not acceptable that everytime an item is offscreen, all of its thumbnails are downloaded again. Does anyone have an example of this type of implementation (gridview adapter within a listview adapter) where the imageview (or images) are stored? What is the proper way to do this?
Thanks in advance for your help.
Gallery Adapter
public class GalleryAdapter extends BaseAdapter {
private Context mContext;
ArrayList<GalleryItem> GalleryList;
//MediaAdapter adapter;
public GalleryAdapter(Context c,ArrayList<GalleryItem> l) {
mContext = c;
GalleryList = l;
}
public int getCount() {
return GalleryList.size();
}
public Object getItem(int position) {
return GalleryList.get(position);
}
public long getItemId(int position) {
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
GalleryViewHolder viewHolder = null;
if(convertView==null){
// inflate the layout
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
convertView = inflater.inflate(R.layout.gallery_item, parent, false);
viewHolder = new GalleryViewHolder();
viewHolder.title = (TextView) convertView.findViewById(R.id.title);
viewHolder.folder_settings = (ImageView) convertView.findViewById(R.id.folder_settings);
viewHolder.mediaGrid = (GridView) convertView.findViewById(R.id.imagegrid);
viewHolder.gridHolder = (LinearLayout) convertView.findViewById(R.id.gridholder);
convertView.setTag(viewHolder);
}
else{
viewHolder = (GalleryViewHolder) convertView.getTag();
}
viewHolder.title.setText(GalleryList.get(position).getTitle());
//Formatting the gridView to fit the screen dim.
ImageTools mWidth = new ImageTools(mContext);
viewHolder.mediaGrid.setColumnWidth(mWidth.imageSize());
int rows = (int) Math.ceil((GalleryList.get(position).getMedia().size() / mWidth.columnNumber)+1);
LinearLayout.LayoutParams labelLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, mWidth.imageSize()*rows);
viewHolder.gridHolder.setLayoutParams(labelLayoutParams);
viewHolder.mediaGrid.setLayoutParams(labelLayoutParams);
viewHolder.mediaGrid.setMinimumHeight(mWidth.imageSize()*rows);
//Set Adapter for image views
viewHolder.mediaGrid.setAdapter(new MediaAdapter(convertView.getContext(),GalleryList.get(position).getMedia()));
viewHolder.folder_settings.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Dialogs.createListDialog(mContext,"Folder Actions", R.array.gallery_action_array).show();
}
});
viewHolder.mediaGrid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
}
});
return convertView;
}
private class GalleryViewHolder {
private TextView title;
private ArrayList<ImageView> imageList;
private GridView mediaGrid;
private ImageView folder_settings;
private LinearLayout gridHolder;
private int position;
}
}
Media Adapter
public class MediaAdapter extends BaseAdapter {
private Context mContext;
ArrayList<MediaItem> mediaitems;
public MediaAdapter(Context c,ArrayList<MediaItem> l) {
mContext = c;
mediaitems = l;
}
public int getCount() {
return mediaitems.size();
}
public Object getItem(int position) {
return mediaitems.get(position);
}
public long getItemId(int position) {
return 0;
}
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.setImageResource(R.drawable.loading);
imageView.setTag(R.integer.path,mediaitems.get(position).getPath().toString());
imageView.setTag(R.integer.fullsize,"false");
imageView.setTag(R.integer.parentpath,mediaitems.get(position).getParentPath().toString());
imageView.setTag(R.integer.index , String.valueOf(position));
try {
new thumbDownload(mContext).execute(imageView);
} catch (DbxException e) {
e.printStackTrace();
}
ImageTools mWidth = new ImageTools(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(mWidth.imageSize(), mWidth.imageSize()));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
} else {
imageView = (ImageView) convertView;
}
//imageView.setImageBitmap(mediaitems.get(position).getBitmap());
return imageView;
}
}
Try with this..may be its silly way, but its worked for me. Just add a line of code inside your method like this for gallery adapter:
public View getView(int position, View convertView, ViewGroup parent) {
GalleryViewHolder viewHolder = null;
// Add this line.
convertView = null;
if(convertView==null){
// inflate the layout
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
convertView = inflater.inflate(R.layout.gallery_item, parent, false);
viewHolder = new GalleryViewHolder();
viewHolder.title = (TextView) convertView.findViewById(R.id.title);
viewHolder.folder_settings = (ImageView) convertView.findViewById(R.id.folder_settings);
viewHolder.mediaGrid = (GridView) convertView.findViewById(R.id.imagegrid);
viewHolder.gridHolder = (LinearLayout) convertView.findViewById(R.id.gridholder);
convertView.setTag(viewHolder);
}
else{
viewHolder = (GalleryViewHolder) convertView.getTag();
}
// rest of your code
}
You can use StickyGridHeaders to implement your UI and Android-Universal-Image-Loader for flexible asynchronous image loading.
StickyGridHeaders is an Android library that provides a GridView that shows items in sections with headers. By default the section headers stick to the top like the People app in Android 4.x but this can be turned off.
Android-Universal-Image-Loader aims to provide a reusable instrument for asynchronous image loading, caching and displaying.
I ended up Using a HashMap<String,Bitmap> to store the images once they were downloaded. I made the hashMap static in my mediaAdapter so I could add the bitmap from my asynctask when it was downloaded. Then in my media Adapter getView(), I added a if statement to check if the image had already been downloaded. If it had, I used setImageBitmap(myHash.get(key)).
i m developing an application in which gridview contain list of button...
when i place images instead of button in gridview then onItemClickEvent get fired..but if i place button in gridView then click event not getting callled...i dont know what is the problem...even i m not getting exception..
here is my code...
public class MainMenu extends Activity
{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
GridView gridview = (GridView) findViewById(R.id.mainMenu);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View v, int position, long id)
{
Toast.makeText(MainMenu.this, "hello" + position, Toast.LENGTH_SHORT).show();
}
});
}
//inner class for adapter
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;
Button btn;
if (convertView == null) { // if it's not recycled, initialize some attributes
btn=new Button(mContext);
// imageView = new ImageView(mContext);
btn.setLayoutParams(new GridView.LayoutParams(120,120));
// imageView.setLayoutParams(new GridView.LayoutParams(140,140));
//imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
btn.setPadding(10,15, 10,15);
btn.setImeActionLabel("hello",0);// actionId)
// imageView.setPadding(8,8, 8, 8);
} else
{
btn=(Button)convertView;
//imageView=(ImageView)convertView;
}
btn.setBackgroundResource(mThumbIds[position]);
//imageView.setImageResource(mThumbIds[position]);
//return imageView;
return btn;
}
// references to our images
private Integer[] mThumbIds =
{
R.drawable.pantrylocator_icon,
R.drawable.volunteeropportunity_icon,
R.drawable.volunteerlocator_icon,
R.drawable.volunteermanagement_icon,
R.drawable.donationform_icon,
R.drawable.donationviamsg_icon,
R.drawable.donationvideo_icon,
R.drawable.virtualfooddrive_icon,
R.drawable.newevent_icon,
R.drawable.pressrelease_icon,
R.drawable.volunteerphotos_icon,
R.drawable.aboutus_icon,
};
}
}
The button has its own OnClickListener:
public View getView(int position, View convertView, ViewGroup parent) {
//ImageView imageView;
Button btn;
if (convertView == null) { // if it's not recycled, initialize some attributes
btn=new Button(mContext);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
}
});
// imageView = new ImageView(mContext);
btn.setLayoutParams(new GridView.LayoutParams(120,120));
// imageView.setLayoutParams(new GridView.LayoutParams(140,140));
//imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
btn.setPadding(10,15, 10,15);
btn.setImeActionLabel("hello",0);// actionId)
// imageView.setPadding(8,8, 8, 8);
} else
{
btn=(Button)convertView;
//imageView=(ImageView)convertView;
}
btn.setBackgroundResource(mThumbIds[position]);
//imageView.setImageResource(mThumbIds[position]);
//return imageView;
return btn;
}
In your ImageAdapter-> getView method add the following line before returning newly created "convertView"
convertView.setClickable(false);
convertView.setFocusable(false);
If any of the views in gridview are clickable then they will block the grid's ItemClick listener from responding.
There is no onclick event written for the Buttons you are adding. Write code for the buttons to handle the click event! let us know then.
i have fece this problem also but finally got the solution i have follow the above suggession
and define button click event in base adapter class like as
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View v;
if(convertView==null){
LayoutInflater li = LayoutInflater.from(mContext);
v = li.inflate(R.layout.icon, null);
tv = (Button)v.findViewById(R.id.icon_text);
iv = (ImageView)v.findViewById(R.id.icon_image);
iv.setImageResource(mThumbIds[position]);
tv.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Toast.makeText(mContext, "vim", Toast.LENGTH_LONG).show();
}
});
}
else
{
v = (View)convertView;
}
return v;
}
gridview = (GridView) findViewById(R.id.gameGrid);
gridview.setAdapter(ia);
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Ur Code here
}
Add click events for the button added in gridView
Here's the cleanest way to do it: call performItemClick() on the GridView from within each button's click listener. That way you can still use the GridView's onItemClickListener like normal.
#Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
...
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((GridView) parent).performItemClick(v, position, 0);
}
});
}
http://www.migapro.com/click-events-listview-gridview/
I have solved my problem as i define button click event in base adpter class and my problem is solved......
here's a problem that i've run into lately:
I have a listview with a custom adapter class, the adapter takes in a listview and populates the listview with elements from it. Now, i'd like to have a button on each row of a listview to remove the item from it. How should i approach this problem? Is there a way to remotely trigger a method in the activity class and call notifydatachanged() method on the adapter to refresh the listview?
I've done something like that:
public class MyAdapter extends Adapter {
private final ArrayList<String> items = new ArrayList<String>();
// ...
deleteRow(int position) {
items.remove(position);
notifyDataSetChanged();
}
//
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
Tag tag = new Tag();
// inflate as usual, store references to widgets in the tag
tag.button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
deleteRow(position);
}
});
}
// don't forget to set the actual position for each row
Tag tag = (Tag)convertView.getTag();
// ...
tag.position = position;
// ...
}
class Tag {
int position;
TextView text1;
// ...
Button button;
}
}
In the getView() method, can't you just setOnClickListener() on the button?
Something like this:
static final class MyAdapter extends BaseAdapter {
/** override other methods here */
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
// inflate the view for row from xml file
// keep a reference to each widget on the row.
// here I only care about the button
holder = new ViewHolder();
holder.mButton = (Button)convertView.findViewById(R.id.button);
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
}
// redefine the action for the button corresponding to the row
holder.mButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// do something depending on position
performSomeAction(position);
// mark data as changed
MyAdapter.this.notifyDatasetChanged();
}
}
}
static final class ViewHolder {
// references to widgets
Button mButton;
}
}
If you're unsure about extending BaseAdapter, check out example List14 in ApiDemos. This techniques provides you with a flexible way to modify just about any aspect of your adapter, though it's quite some work.