Maintaining highlight for selected item in fragmen

2019-03-25 18:27发布

问题:

I have a layout with two fragments. The left hand fragment is a ListFragment using a SimpleCursorAdaptor, the right hand one is populated with details about the item selected from the list in the left fragment. I'm trying to figure out how to make sure the selected item from the ListFragment stays highlighted until another item in the list is selected.

After some research I got as far as trying to use android:background="@drawable/item_selector" I can changes the colors for the different states, but none of them seem to persist. I thought that selected would... it just seems logical that your selected item remains the selected item until you select a different one.

I even tried using v.setSelected(true); in my clickhandler hoping it might maintain the state, but that didn't work either.

Is there a state I'm missing? I looked through the dev docs and nothing else seemed appropriate...

item_selector.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/green" />
    <item 
        android:state_selected="true" 
        android:drawable="@color/blue" />
</selector>

I'm not sure what other code might help, so feel free to ask for whatever else you might think necessary.

回答1:

The answer was in the android documentation after further research (two parts of the documentation really).

First, in touch mode there is no selected or focused state.

Second, by default, listviews are set to a choice mode of none (meaning that no item in the list can have a chosen state). All I had to do was change the choice mode (it could be single or multiple, I only needed/wanted single) by adding this:

getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);

Then I used the choice state in my selector XML (translates to the activated state):

<item 
 android:state_activated="true" 
 android:drawable="@color/blue" />

Apply that in the row layout xml file as the background:

   <TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="35dp"
    android:background="@drawable/item_selector"
    android:gravity="center_vertical"/>

My chosen item now appears with a blue background until a different item is chosen.

Note that this (android:state_activated) requires Android API 11 or later.



回答2:

I believe you need to add state_focused too to make it feel like selected or highlighted.

<?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/green" />
    <item 
        android:state_selected="true" 
        android:drawable="@color/blue" />

    <item 
        android:state_focused="true" 
        android:drawable="@color/red" />
</selector>


回答3:

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