在Android上的ListView中突出显示所选项目

时间:2023-01-19 10:59:26

I have been making an application that works with ListViews in Android, and I can't make it so that the selected (chacked) item has a different background. I'm using CHOICE_MODE_SINGLE. This is how my code looks so far:

我一直在制作一个与Android中的ListViews一起使用的应用程序,但我不能这样做以使所选(chacked)项具有不同的背景。我正在使用CHOICE_MODE_SINGLE。这是我的代码到目前为止的样子:


The ListView that I use:
(inside layout.xml)

我使用的ListView :(在layout.xml内)

<ListView
    android:id="@+id/listView"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:choiceMode="singleChoice"
    android:listSelector="@drawable/selector_test" >
</ListView>

The TextView layout I use in the adapter:
(listItem.xml)

我在适配器中使用的TextView布局:(listItem.xml)

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/listItem"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="23sp"
    android:textStyle="bold" />

This is where I add the adapter:

这是我添加适配器的地方:

mListAdapter = new ArrayAdapter<String>(this, R.layout.listItem, mList);
mListView = (ListView) findViewById(R.id.listView);
mListView.setAdapter(mAuthorAdapter);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
        String selected = mList.get(position);
        // ...
        mListView.setItemChecked(position, true);
    }
});

I'm sure that the proper item is checked on click, because when I call getCheckedItemPosition(), it returns the proper value.

我确定在点击时检查了正确的项目,因为当我调用getCheckedItemPosition()时,它返回正确的值。


And now, the two things I tried in order to highlight the checked item:

现在,我尝试了两件事来突出显示选中的项目:


Selector drawable:
(selector_test.xml)

选择器drawable:(selector_test.xml)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:enterFadeDuration="@android:integer/config_longAnimTime">

    <item android:state_checked="true"><shape>
            <solid android:color="@color/red" />
        </shape></item>
    <item android:state_selected="true"><shape>
            <solid android:color="@color/blue" />
        </shape></item>
    <item android:state_pressed="true"><shape>
            <solid android:color="@color/green" />
        </shape></item>

</selector>

I add it to .xml with:

我将它添加到.xml中:

android:listSelector="@drawable/selector_test"

Background drawable:
(background_test.xml)

背景drawable:(background_test.xml)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@color/red" android:state_checked="true"/>
    <item android:drawable="@color/blue" android:state_selected="true"/>
    <item android:drawable="@color/green"/>

</selector>

I add it to .xml with:

我将它添加到.xml中:

android:background="@drawable/background_test"

I've tried adding the selector and the background to both listView.xml and listItem.xml, but the only thing that changes is the default background color, and the color of the selector when the item is pressed (or held).
android:state_checked="true" and android:state_selected="true" seem to do nothing.

I can change the background by overriding the getView() method in ArrayAdapter and invoking setBackgroundColor() in it if the view is selected, and it does change the background, but also gets rid of the selector entirely. Also, I don't really like to override classes just to change one line of code, especially if that same thing can be achieved in a different way.

So what I'm asking is, is there a way to highlight checked item in ListView by adding a selector or background drawable to it, and I am just doing it wrong, or will I have to make it work some other way.

Thanks in advance! :)

我已经尝试将选择器和背景添加到listView.xml和listItem.xml中,但唯一改变的是默认背景颜色,以及按下(或保持)项目时选择器的颜色。 android:state_checked =“true”和android:state_selected =“true”似乎什么都不做。我可以通过覆盖ArrayAdapter中的getView()方法并在其中调用setBackgroundColor()来更改背景(如果选择了视图),它确实更改了背景,但也完全摆脱了选择器。另外,我真的不想仅仅为了改变一行代码来覆盖类,特别是如果可以以不同的方式实现同​​样的事情。所以我要问的是,有没有办法通过添加选择器或背景可绘制来强调ListView中的已检查项目,我只是做错了,或者我必须让它以其他方式工作。提前致谢! :)

7 个解决方案

#1


8  

add this line in onStart of your activity

在活动的onStart中添加此行

lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

where lv is instance of listView

其中lv是listView的实例

then override this method and add the following lines to it.

然后重写此方法并向其添加以下行。

 @Override
public void onListItemClick(ListView l, View v, int position, long id) {


    // Set the item as checked to be highlighted 
    lv.setItemChecked(position, true);
            v.setBackgroundColor(Color.BLUE);

        conversationAdapter.notifyDataSetChanged();

}

and then change the color of previous selected item's background back to normal in getView method of your custom adapter

然后在自定义适配器的getView方法中将以前所选项目背景的颜色更改为正常

#2


5  

Try this:

尝试这个:

listViewDay.setItemChecked(position, true);
listViewDay.setSelection(position);

listitem.xml

listitem.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="40dp"
    android:background="@drawable/list_day_selector" >

    <TextView
        android:id="@+id/txtItemDay"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center_vertical|center_horizontal"
        android:text="22"
        android:textColor="@android:color/white"
        android:textSize="22sp" />

</LinearLayout>

list_selector.xml

list_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/list_item_bg_normal" android:state_activated="false"/>
    <item android:drawable="@drawable/bg_with_left_arrow" android:state_pressed="true"/>
    <item android:drawable="@drawable/bg_with_left_arrow" android:state_activated="true"/>

</selector>

#3


2  

Programmatically, use setSelector. For example:

以编程方式,使用setSelector。例如:

lv.setSelector(R.color.abc_background_cache_hint_selector_material_dark);

#4


0  

After some hours of encountering one glitch after another (including the selector leaving a dirty stripe), I decided to do it myself:

几个小时后遇到一个又一个小故障(包括选择器留下脏条纹),我决定自己做:

class MyListAdapter extends ArrayAdapter<MyData> {
    // !!! access to the current selection
    int mSelected = 0;
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v =  super.getView(position, convertView, parent);
        // !!! this is where the selected item is highlighted
        v.findViewById(R.id.selectionSign).setVisibility(position == mSelected ? View.VISIBLE : View.INVISIBLE);
        return v;
    }
    public CommandListAdapter(Context context, List<MyData> objects) {
        super(context, R.layout.mylistitem, R.id.mytext, objects);
    }
}

with the OnItemClickListener:

使用OnItemClickListener:

        mMyListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                setSelectionPosNoUpd(position);
                update();
            }
        });

and the functions defined as:

和功能定义为:

    void setSelectionPosNoUpd(int n) {
        mCommandListAdapter.mSelected = n;
        //update();
    }
    void update() {
        mListViewOfCommands.smoothScrollToPosition(getSelectionPos());
        mCommandListAdapter.notifyDataSetChanged();
    }

and the list item XML (res/layout/mylistitem.xml) is:

列表项XML(res / layout / mylistitem.xml)是:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
        <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/mytext" 
        />
    </LinearLayout>
    <View
        android:id="@+id/selectionSign"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#10ff5000"
        android:visibility="invisible"
        />
</FrameLayout>

The downside is that after changing the selection I have to update(): there is no easy way to unhighlight the previously highlighted view.

缺点是更改选择后我必须更新():没有简单的方法来取消突出显示以前突出显示的视图。

#5


0  

Set item state in selector like this:

在选择器中设置项状态,如下所示:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_activated="true"
        android:color="@color/XXX/>
</selector>

I don't know why state_checked not working. At first I thought it must be a Checkableview then I tried CheckedTextView. Still not working.
Anyway, state_activated will solve the problem.

我不知道为什么state_checked无法正常工作。起初我认为它必须是Checkableview然后我尝试了CheckedTextView。还是行不通。无论如何,state_activated将解决问题。

#6


-1  

I think you cann't use mListView inside anonymous class. You must use AdapterView arg0

我想你不能在匿名类中使用mListView。您必须使用AdapterView arg0

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View view,
                int position, long id) {
            AnyObject obj=(AnyObject)arg0.getItemAtPosition(position);

                            ........
                            .........
                            .........

        }
    });

#7


-1  

This post has worked out for me: http://www.mynewsfeed.x10.mx/articles/index.php?id=14

这篇文章对我来说很有用:http://www.mynewsfeed.x10.mx/articles/index.php?id = 14

The ListView (inside layout.xml):

ListView(在layout.xml内):

<ListView
    android:id="@+id/list"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:background="@drawable/list_custom"
    android:choiceMode="singleChoice"/>

Selector drawable(list_custom.xml):

选择器drawable(list_custom.xml):

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@color/orange"/>
    <item android:state_activated="true" android:drawable="@color/blue" />
    <item android:drawable="@color/green" />
</selector>

Color.xml in values folder:

值文件夹中的Color.xml:

<resources>
    <item name="blue" type="color">#FF33B5E5</item>
    <item name="green" type="color">#FF99CC00</item>
    <item name="orange" type="color">#FFFFBB33</item>
</resources>

#1


8  

add this line in onStart of your activity

在活动的onStart中添加此行

lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

where lv is instance of listView

其中lv是listView的实例

then override this method and add the following lines to it.

然后重写此方法并向其添加以下行。

 @Override
public void onListItemClick(ListView l, View v, int position, long id) {


    // Set the item as checked to be highlighted 
    lv.setItemChecked(position, true);
            v.setBackgroundColor(Color.BLUE);

        conversationAdapter.notifyDataSetChanged();

}

and then change the color of previous selected item's background back to normal in getView method of your custom adapter

然后在自定义适配器的getView方法中将以前所选项目背景的颜色更改为正常

#2


5  

Try this:

尝试这个:

listViewDay.setItemChecked(position, true);
listViewDay.setSelection(position);

listitem.xml

listitem.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="40dp"
    android:background="@drawable/list_day_selector" >

    <TextView
        android:id="@+id/txtItemDay"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center_vertical|center_horizontal"
        android:text="22"
        android:textColor="@android:color/white"
        android:textSize="22sp" />

</LinearLayout>

list_selector.xml

list_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/list_item_bg_normal" android:state_activated="false"/>
    <item android:drawable="@drawable/bg_with_left_arrow" android:state_pressed="true"/>
    <item android:drawable="@drawable/bg_with_left_arrow" android:state_activated="true"/>

</selector>

#3


2  

Programmatically, use setSelector. For example:

以编程方式,使用setSelector。例如:

lv.setSelector(R.color.abc_background_cache_hint_selector_material_dark);

#4


0  

After some hours of encountering one glitch after another (including the selector leaving a dirty stripe), I decided to do it myself:

几个小时后遇到一个又一个小故障(包括选择器留下脏条纹),我决定自己做:

class MyListAdapter extends ArrayAdapter<MyData> {
    // !!! access to the current selection
    int mSelected = 0;
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v =  super.getView(position, convertView, parent);
        // !!! this is where the selected item is highlighted
        v.findViewById(R.id.selectionSign).setVisibility(position == mSelected ? View.VISIBLE : View.INVISIBLE);
        return v;
    }
    public CommandListAdapter(Context context, List<MyData> objects) {
        super(context, R.layout.mylistitem, R.id.mytext, objects);
    }
}

with the OnItemClickListener:

使用OnItemClickListener:

        mMyListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                setSelectionPosNoUpd(position);
                update();
            }
        });

and the functions defined as:

和功能定义为:

    void setSelectionPosNoUpd(int n) {
        mCommandListAdapter.mSelected = n;
        //update();
    }
    void update() {
        mListViewOfCommands.smoothScrollToPosition(getSelectionPos());
        mCommandListAdapter.notifyDataSetChanged();
    }

and the list item XML (res/layout/mylistitem.xml) is:

列表项XML(res / layout / mylistitem.xml)是:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
        <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/mytext" 
        />
    </LinearLayout>
    <View
        android:id="@+id/selectionSign"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#10ff5000"
        android:visibility="invisible"
        />
</FrameLayout>

The downside is that after changing the selection I have to update(): there is no easy way to unhighlight the previously highlighted view.

缺点是更改选择后我必须更新():没有简单的方法来取消突出显示以前突出显示的视图。

#5


0  

Set item state in selector like this:

在选择器中设置项状态,如下所示:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_activated="true"
        android:color="@color/XXX/>
</selector>

I don't know why state_checked not working. At first I thought it must be a Checkableview then I tried CheckedTextView. Still not working.
Anyway, state_activated will solve the problem.

我不知道为什么state_checked无法正常工作。起初我认为它必须是Checkableview然后我尝试了CheckedTextView。还是行不通。无论如何,state_activated将解决问题。

#6


-1  

I think you cann't use mListView inside anonymous class. You must use AdapterView arg0

我想你不能在匿名类中使用mListView。您必须使用AdapterView arg0

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View view,
                int position, long id) {
            AnyObject obj=(AnyObject)arg0.getItemAtPosition(position);

                            ........
                            .........
                            .........

        }
    });

#7


-1  

This post has worked out for me: http://www.mynewsfeed.x10.mx/articles/index.php?id=14

这篇文章对我来说很有用:http://www.mynewsfeed.x10.mx/articles/index.php?id = 14

The ListView (inside layout.xml):

ListView(在layout.xml内):

<ListView
    android:id="@+id/list"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:background="@drawable/list_custom"
    android:choiceMode="singleChoice"/>

Selector drawable(list_custom.xml):

选择器drawable(list_custom.xml):

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@color/orange"/>
    <item android:state_activated="true" android:drawable="@color/blue" />
    <item android:drawable="@color/green" />
</selector>

Color.xml in values folder:

值文件夹中的Color.xml:

<resources>
    <item name="blue" type="color">#FF33B5E5</item>
    <item name="green" type="color">#FF99CC00</item>
    <item name="orange" type="color">#FFFFBB33</item>
</resources>