i have a listview with pictures and texts in each element. I have to be able to change one of the image if the user clicks on it and change it back to the original if the user clicks it again. I have a base adapter class that i use to add the data to the listview. in the getview method i set a onclick listener to the image to change it. The problem i'm having is it only changes if i scroll away from the element and come back to it. how can i change so that it will update the listview with out scrolling away from it.
You can use the method
notifyDataSetChanged();
after you change the image src in your listViewAdapter (who extends BaseAdapter)
eg.
public class ProductItemListView extends ListView {
public ProductItemListView() {
super(context);
mProductAdapter = new ProductItemAdapter(context);
this.setAdapter(mProductAdapter);
}
}
public class ProductItemAdapter extends BaseAdapter {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
...
myImage.setBackgroundResource(R.drawable.other_image);
notifyDataSetChanged();
}
}
Simply set a OnItemClickListener on your ListView.
The rest is pretty straight-forward using ImageView.setImageDrawable or similar.
Related
I have a listview that is populated via an adapter. I need one of the items (which are just bits of text) in the listview to have a different background compared to the others (to mark it as the currently selected one).
I have all of the background logic, I just need a way to say listview.setBackgroundById(int position)
or something like that.
How do I do this?
This needs to be as simple as possible, 'cause all of the other things done in the Activity are currently working perfectly. :)
As asked, this is my Adapter that I'm using:
public class SampleAdapter extends ArrayAdapter<SampleItem> {
private String title;
public SampleAdapter(Context context) {
super(context, 0);
}
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.row_station, null);
}
TextView title = (TextView)convertView.findViewById(R.id.station_name);
font.setFont(title, 2, getActivity());
title.setText(getItem(position).title);
RelativeLayout info = (RelativeLayout)convertView.findViewById(R.id.info_relative_button);
info.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
MainActivity.setCurrentTab(41);
MainActivity.setBackDisabled(true);
Log.e("current tab:",String.valueOf(MainActivity.getCurrentTab()));
Fragment fragment = new StationInfo();
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
UserManager.getInstance().setStationId(getItem(position).id);
}
});
return convertView;
}
}
The SampleItem has 2 String fields, title and id, it's very simple.
You need to use a custom list adapter and have it return views with your desired background. Create a class extending ListAdapter or any of the existing SimpleAdapter etc and override getView to inflate a suitable view for your element, and add any logic you need to set the background of that view.
There is no way to tell the listview itself to decorate some of its elements by id or position.
Update: I just noticed you added the list adapter code.
Since you are already implementing getView, to change the background of your element simply call convertView.setBackgroundColor, or have two different views inflated depending on the situation.
(BTW it's really bad practice to call static methods on your activity like in your onClickListener.)
In ListView adapter:
#Override
public View getView(int position, View view, ViewGroup viewGroup) {
if(view==null)
....
//for example every even list item to be grey, every odd to be white
if(((position+1)%2)==0)
view.setBackgroundColor(mContext.getResources().getColor(R.color.grey));
else view.setBackgroundColor(mContext.getResources().getColor(android.R.color.white));
Hope you get an idea...
I have been developing an android application and i am stuck in the middle.
The problem is i am using SimpleAdapter to do the adapter stuff and show items in the Listview and as far as i know i cannot override the getView() method of SimpleAdapter class to bound click listeners to the items.
There is a other way to handle click events of sub items like using XML, you can write in the XML like android:clickable="true"and android:onClick="clicklistenr", using this i can get the item but my problem is if i use this then i cannot get the position of the adapter which i need to get adapter item values and handle other tasks. So i am stuck here any help would be appreciable. thanks.
For example i have a ListView which contains one image, TextView, like Button, share Button in each of its items. And there is no way i can find that either its image or button clicked using setOnItemClickListener. So i need a way to handle click events of these sub items of a ListView, i am using SimpleAdapter.
Just call listView.setOnItemClickListener() with your implementation of the listener.
and use like
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
}
});
Where list=(ListView)findViewById(R.id.list); and list.setAdapter(your_adapter);
For More details Follow: http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/
Hope It Will Help You.. :)
You can use like
myListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
HashMap<String, Object> obj = (HashMap<String, Object>) adapter.getItem(position);
String result= (String) obj.get("name");
Log.d("Yourtag", name);
}
});
First of all your problem is how to handle the items of a custom listview.. not sub. Anyways...
If you are using SimpleAdapter , you may use getView().But if you are using SimpleAdapter you don't need to use the getView() as the it handles the mapping of data to your layout via the resource. For inforamtion check the SimpleAdapter in developer site.
Another thing is there is not mandatory for using any particular adapter. You can create any adapter class which will extends the BaseAdapter which will implement the getView().
Inside getView() you can able to inflate your custom layout(which contains the image,button etc..) to your view or convertview.something like:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.yourcustomlayout, null);
//Initialize your custom views here
TextView someText= (TextView) vi.findViewById(R.id.tvSometext);
Button likeButton = (Button ) vi.findViewById(R.id.btnLike);
//put data or call onclicklistener or
//whatever you want to do with custom views
likeButton .setOnClickListener(...){
//on click
}
}
Ans simply call this through your constructor with some data and appropriate context.
Amir,
I am not sure you found the solution or not. You can do this way:
#Override
public View getView(int position, View view, ViewGroup viewGroup) {
//for each subitem, set click listener & set tag having position as
// value.
ImageView imv = (ImageView)view.findViewById(R.id.live_view);
imv.setTag(i);
imv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("INFO","Live view clicked");
//This will give you position in listview.
int position = (int) v.getTag();
}
});
}
I hope it will help you and others looking to find relevant answer.
May be there is some other solution too, but it will surely work.
I have a custom list view with simple text and button, this button open a dialog that allow user to delete or save a file, but i want to get the view of the row when i push this button to perform a delete animation.
How can i get the view of this specific row, inside on a button click listener?
I use a custom array Adapter with Base Adapter!
extends BaseAdapter implements View.OnClickListener{
Thanks in advance, i don't know if it's necessary to put here the code, it's so long.
you should use the custom adapter for your list view and add tag to your button that represent the position of your row and after that in your clicklistener you should get the tag and find out that which row has been clicked .
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Button yourbtn= (Button) v.findViewById(R.id.yourbtnid);
yourbtn.setTag(position);
yourbtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Button btn = (Button)arg0;
int position = Integer.parseInt(btn .getTag().toString());
}
}
You need to do this from the ListView by using ListView.setOnItemSelectedListener(). The OnItemSelectedListener returns the View.
If you're implementing your click action inside the Adapter code itself (which I think is not the best way to do it), you can get an instance of the whole strip by calling getParentView() as many times as needed, depending on how deep into your parent layout the button is.
I am doing a project where i am a using a custom list view, which contains a textview. Data is coming from the server. I want to change the height of the cell, based on the data size. If the content is more than two lines, i have to trim it to two lines and show a see more button. On clicking the see more button expand the cell to show full details.I googled about it. But i cannot find any useful resource.Could any one help me to solve this, any useful links or suggestions?`
One way to do this is to first invalidate the listView forcing it to redraw the visible elements and then handle the layout change in the getView method of your adapter.
Try this:
Add a showTrimmed(int position, boolean value) method to your adapter. This will update a structure inside your adapter that keeps track of the list items that you want to trim or not trim. Then in the getView method, when creating the item view, you test if the current element should be trimmed or not and based on the result you create the proper view.
I did something similar to achieve a different but similar result and it works.
Remember to call invalidate after calling showTrimmed to force the listView to redraw the displayed items.
Edit: I post my code which is different from what you want to do but it's quite similar in the idea:
public class HeroListViewAdapter extends ArrayAdapter<Hero> {
public static int NO_POS = -1;
private List<Hero> heroes;
private int selected_pos = NO_POS;
public HeroListViewAdapter(Context context, List<Hero> heroes){
super(context, R.layout.hero_list_item_view, heroes);
this.heroes = heroes;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = GuiBuilder.createHeroListItemView(heroes.get(position),getContext(),parent,false);
if(position == selected_pos){
rowView.setBackgroundColor((rowView.getResources().getColor(R.color.list_item_selected_color)));
}
return rowView;
}
public void setSelectedPosition(int selected_pos){
this.selected_pos = selected_pos;
}
public int getSelectedPosition(){
return selected_pos;
}
public Hero getSelectedHero(){
if(selected_pos>=0 && selected_pos<heroes.size())
return this.getItem(selected_pos);
else
return null;
}
}
instead of setSelectedPosition you should have the showTrimmed method which updates an inner member as setSelectedPos does, in order to keep track of the trimmed state of every list item. Then in the getView method you do the test (like I do in if(position == selected_pos)) and then you build your custom trimmed or not trimmed list item based on the result of the test. My listener which uses these functions is:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
list_adapter.setSelectedPosition(position);
listView.invalidate();
}
}
);
you can try to update this idea to your needs. In particular in my case I do this to highlight the clicked listview item by programmatically changing its background.
I am trying to highlight an item in a ListView (touchable interface). The aim is that the user will touch an image and it will select the item in the ListView moving it to be visible (it does not all show on the screen at the same time) and then highlight the item in the ListView related to the position on the image by changing the background color of the item view. I have a custom ListAdapter with a view for each item.
From the image I can get the postion of the item in the ListView. From this I can call listView.setSelection(selectedPos). This positions the item at the top of the list. However I now want to get the view for this item; I have tried getFirstVisiblePosition() however it seems that this is not available until the list has been layed out (I am responding to a click on the image) so I cannot use this.
Nothing else I try works - all I want to do is to do something like listView.getViewAt(index) but I simply cannot find a way of doing it. I cannot use 'selected' as I am in touchable mode.
For what seems a very simple thing - I've wasted a day; any help would be greatly appreciated!
Cheers,
Neil
Shouldn't listView.getChildAt(position) do what you want?
Try creating your own custom adapter for the list view. For example:
private class CustomAdapter extends ArrayAdapter<RowData> {
public CustomAdapter(Context context, int resource, List<RowData> objects) {
super(context, resource, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//convertView holds the view for each item.
TextView txt = (TextView)convertView.findViewById(R.id.button);
//do some other stuff with the views
return convertView;
}
}
I got round this by doing the following:
I marked the item I wished to select in the adapter first by adding in my own method
Then when the view is requested I can check to see if the view is for a position at which I requested
I get then modify the presented view that is returned by GetView
This seems the simplest option.