Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - Keep ListView's item highlighted once one has been clicked

So I have an activity with 2 ListView widgets, when you select a value in the first one, the second is populated with values related to the selection in the first ListView. This mechanic works without a problem, but now I want the user choices to stay highlighted. I've read a good ammount of question related to this topic and it seems there is a myriad of ways one can accomplish this but after trying about 4-5 of em' I still can't get it to work.

I've got it working on the second ListView using the android:listSelector="#CCCCCC" XML Attribute, but this seems to be wiped clean once a OnItemClickListener is introduced into the mix (like the one I use on my first ListView).

So far here's what I've got:

Custom OnItemClickListener I found browsing various answer regarding this topic (slightly modified it in order for it to load my info the second ListView):

private class ItemHighlighterListener implements OnItemClickListener {      private View oldSelection = null;      public void clearSelection() {         if(oldSelection != null) {             oldSelection.setBackgroundColor(android.R.color.transparent);         }     }      public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {         clearSelection();         oldSelection = view;         view.setBackgroundDrawable(view.getContext().getResources().getDrawable(R.drawable.list_selector));         loadClubs(mXMLPortalOptions.getRegion(pos).getId());         mClubList.setAdapter(new ArrayAdapter<String>(getApplicationContext(), R.layout.list_item_white, mClubs));     } } 

Here's my list_selector.xml file :

<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android">      <item android:state_selected="true"><shape>             <solid android:color="#CCCCCC" />         </shape></item>      <item android:state_selected="false"><shape>             <solid android:color="#FFFFFF" />         </shape></item>  </selector> 

The method (OnItemClick) is called and executed, but the background of my ListItem stays the same color :/

I can't believe that this simple task has proven so complicated.

If I have omitted code that could be useful or if my question is lacking details, feel free to point that out and I'll do my best to explain myself.

like image 281
Jean-Philippe Roy Avatar asked Feb 14 '12 17:02

Jean-Philippe Roy


2 Answers

Put a position variable for selected item. Change the position in onItemClicked() method. Check the selected position in List Adapter inside getView() and set the background for the selected item.

public class TestAdapter extends BaseAdapter {     private Context context;     private ArrayList<TestList> testList;     private int selectedIndex;     private int selectedColor = Color.parseColor("#1b1b1b");      public TestAdapter(Context ctx, ArrayList<TestList> testList)     {         this.context = ctx;         this.testList = testList;         selectedIndex = -1;     }      public void setSelectedIndex(int ind)     {         selectedIndex = ind;         notifyDataSetChanged();     }      @Override     public int getCount()     {         return testList.size();     }      @Override     public Object getItem(int position)     {         return testList.get(position);     }      @Override     public long getItemId(int position)     {         return position;     }      private class ViewHolder     {         TextView tv;     }      @Override     public View getView(int position, View convertView, ViewGroup parent)     {         View vi = convertView;         ViewHolder holder;         if(convertView == null)         {             vi = LayoutInflater.from(context).inflate(R.layout.test_list_item, null);             holder = new ViewHolder();              holder.tv = (TextView) vi;              vi.setTag(holder);         }         else         {             holder = (ViewHolder) vi.getTag();         }          if(selectedIndex!= -1 && position == selectedIndex)         {             holder.tv.setBackgroundColor(Color.BLACK);         }         else         {             holder.tv.setBackgroundColor(selectedColor);         }         holder.tv.setText("" + (position + 1) + " " + testList.get(position).getTestText());          return vi;     }  } 

Now set the selectedIndex variable when a list item clicked.

public class TestActivity extends Activity implements OnItemClickListener {     // Implemented onItemClickListener      @Override     public void onItemClick(AdapterView<?> parent, View view, int position, long id)     {         adapter.setSelectedIndex(position);     } } 
like image 100
Shaiful Avatar answered Sep 28 '22 05:09

Shaiful


To expand on Shaiful's great solution, you might not get his to work in your situation.

If you are using have your code all in public void onListItemClick(ListView l, View v, int index, long id), if you're using fragments and have to declare an interface instead of implementing OnListItemClickListener, or whatever is causing your IDE to generate errors, you might have to access variables and methods statically.

public static int selectedPosition = 0; ArrayAdapter<Your_obj> adapter = null;  @Override public void onListItemClick(ListView l, View v, int index, long id) {     super.onListItemClick(l, v, index, id);          selectedPosition = index;         Your_adapter.setSelectedIndex(selectedPosition);         adapter.notifyDataSetChanged(); } 

And in Your_adapter:

private static int selectedIndex;  //public Your_adapter...  public static void setSelectedIndex(int ind) {     selectedIndex = ind; }  @Override public View getView(int position, View convertView, ViewGroup parent) {     WellHolder holder = null;      if (null == convertView) {                  //set up your "holder"     }      if (position == selectedIndex) {         convertView.setBackgroundColor(convertView.getResources().getColor(R.color.cyan));     }     else {         convertView.setBackgroundColor(convertView.getResources().getColor(R.color.silver));     }      return convertView; } 

Some other differences are that you don't have to initialize any variables as "0" or "-1" and notifyDataSetChanged() is called in your activity.

Once again, thanks for your solution @Shaiful. It certainly helped save me time trying to get what is default in iOS to work for Android, all while avoiding selector/item/focused/pressed/etc.

like image 42
whyoz Avatar answered Sep 28 '22 06:09

whyoz