Highlight selected item in “ListFragment”?

被刻印的时光 ゝ 提交于 2019-11-29 02:06:27
Codedroid

The following worked for me for:

res/color/menu_highlight.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item 
    android:state_pressed="true"
    android:drawable="@color/red"  />
  <item
    android:state_selected="true"
    android:drawable="@color/red" />
  <item 
    android:drawable="@color/white" />
</selector>

res/values/colors.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources> 
<color name="white">#FFFFFF</color>
<color name="red">#FF0000</color>
</resources>

res/layout/menuitem.xml:: (XML for every item in the list)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent">
    <TextView
        android:id="@+id/textmenu"
        android:layout_height="wrap_content"
        android:text="text"
        android:textColor="#FFFFFF" 
        android:background="@color/menu_highlight"
        android:visibility="visible"
        android:layout_width="fill_parent" />
</LinearLayout>

Finally, in the ListFragment class, add View previous and add the following code to the onlistitemclick function.. (mentioned in ListFragment: highlight selected row)

public class MenuListFragment extends ListFragment{

View previous;

@Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id); 
       //Logic to highlight selected item
        previous.setSelected(false);
        v.setSelected(true);
        previous=v;
    }

}    

From your ListView, call setChoiceMode(ListView.CHOICE_MODE_SINGLE). Then, whenever you want to highlight a selected item, call setItemChecked(index, true).

I tried the same and I didn't find any good solution. What I actually do is using this code to set the listener:

listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
    public void onItemClick(AdapterView<?> parent, View view, int position, long id){
        list_adapter.setSelectedPosition(position);
        listView.invalidate();
    }
});

where the list adapter defines the following public methods

@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;
}

That is, I change the background of the list item programmatically. Moreover to avoid the blinking effect when clicking the list element I don't define any selector for the pressed state

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true"
        android:drawable="@drawable/list_item_focused_color" />
    <item android:drawable="@drawable/list_item_default_color" />
</selector>

This works as intended for me. I didn't find any better solution since setSelected(true) doesn't work on list items!

I wasn't getting what I wanted so I kept on digging and came up with a "cheap" solution which might not be the best practice but does the job. I wanted the item to be highlighted when selected and the color should go away when other item is selected from the listFragment. This is what worked for me- I defined a static View V; and initialized it V = new View(getActivity()); Then inside my

onListItemClick(ListView l, View v, int position, long id)

            V.setBackgroundResource(0);
            v.setBackgroundResource(R.color.BLUE);
            V = v;

This worked very nice for me in the ListFragment, but I think it works only for Android 4.0 and up. I created a simple layout for the list item with android:background="?android:attr/activatedBackgroundIndicator (in case of Android below 4.0 you need to ceate the similar one in drawables):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:background="?android:attr/activatedBackgroundIndicator"
android:orientation="horizontal" >

<TextView
    android:id="@+id/list_item_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ellipsize="end"
    android:singleLine="true"
    android:textAppearance="?android:attr/textAppearanceListItemSmall"
    android:gravity="center_vertical"
    android:layout_margin="@dimen/double_view_margin" />

And then, just create a simple ArrayAdapter using this layout and set the choice mode to single:

final ArrayAdapter<String> labelsAdapter = new ArrayAdapter<String>(getActivity(), R.layout.item_simple_list_item, R.id.list_item_text, labels);

setListAdapter(labelsAdapter);

getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);

After that you can hightlight the necessary item with setItemChecked method:

@Override
public void onListItemClick(final ListView l, final View v, final int position, final long id) {
    getListView().setItemChecked(position, true);
}

i code

getListView().setItemChecked(0, true); 

after

setListAdapter(oAdapter);

code block

Something similar to type-a1pha but with the selectors, once you have the view you can view.setSelected(true) and that would add the style you have defined on your selector. you need to remove the flag once the action is performed.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!