Android - 单击一个后,保持ListView的项目突出显示

时间:2012-02-14 17:01:52

标签: android listview android-listview highlighting

所以我有一个包含2个ListView小部件的活动,当您在第一个小部件中选择一个值时,第二个小部件将填充与第一个ListView中的选择相关的值。这个机制没有问题,但现在我希望用户选择保持突出显示。我已经阅读了与此主题相关的大量问题,似乎有无数种方法可以实现这一目标,但在尝试了4-5之后,我仍然无法使其工作。

我已经使用ListView XML属性对第二个android:listSelector="#CCCCCC"进行了处理,但是一旦OnItemClickListener被引入混合中,这似乎就会被清除干净(就像一个我在我的第一个ListView)上使用。

到目前为止,这是我所拥有的:

自定义OnItemClickListener我发现浏览了有关此主题的各种答案(稍微修改了它以便将我的信息加载到第二个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));
    }
}

这是我的list_selector.xml文件:

<?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>

调用并执行方法(OnItemClick),但ListItem的背景颜色保持不变:/

我无法相信这个简单的任务已经证明是如此复杂。

如果我省略了可能有用的代码,或者我的问题缺乏细节,请随时指出,我会尽力解释自己。

11 个答案:

答案 0 :(得分:62)

为所选项目放置一个位置变量。在onItemClicked()方法中更改位置。检查getView()内的列表适配器中的选定位置,并设置所选项目的背景。

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

}

现在,在单击列表项时设置selectedIndex变量。

public class TestActivity extends Activity implements OnItemClickListener
{
    // Implemented onItemClickListener

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id)
    {
        adapter.setSelectedIndex(position);
    }
}

答案 1 :(得分:5)

为了扩展Shaiful的出色解决方案,你可能无法让他在你的情况下工作。

如果您使用的是public void onListItemClick(ListView l, View v, int index, long id)中的所有代码,如果您正在使用片段并且必须声明接口而不是实现OnListItemClickListener,或者导致IDE生成错误的任何内容,您可能必须访问变量和方法静态。

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

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

其他一些不同之处在于您不必将任何变量初始化为“0”或“-1”,并且在您的活动中调用notifyDataSetChanged()。

再次感谢您的解决方案@Shaiful。它确实帮我节省了时间,试图让iOS中的默认设置适用于Android,同时避免选择器/项目/聚焦/按下等等。

答案 2 :(得分:4)

我遇到了类似的问题。这是我的解决方案:

首先将自定义列表选择器添加到列表视图中:

<ListView
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="fill_parent"
    android:listSelector="@drawable/listselector" />

在listselector.xml里面:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_accelerated="false"
        android:drawable="@drawable/bg" />
</selector>

最后是一个可绘制的bg.xml,其中包含突出显示的颜色:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#33b5e6"/>
</shape>

答案 3 :(得分:3)

我认为最好和最简单的解决方案就是这个。您需要在ListView上设置任何android:listSelector或对适配器进行任何更改。您甚至需要拨打setSelection(position)中的任何OnItemClickListener,因为它会自动处理。

  1. 设置为ListView:

    android:choiceMode="singleChoice"
    
  2. 设置列表项目本身的背景:

    android:background="?android:attr/activatedBackgroundIndicator"
    
  3. 这就是它。

  4. 这样您就可以获得默认的系统行为。这是在默认android.R.layout.simple_list_item_activated_1布局中完成的方式。

答案 4 :(得分:2)

两周前我一直在寻找它,结果是使用可绘制的选择器是不可能的。 有关详细信息,请阅读Android开发人员博客中的这篇文章:Touch Mode

简历中:仅当您的手指在屏幕上时,才会选择项目。

其他可能性是保存哪个项目在var中选择并使用您的自定义适配器进行不同的绘制,如Shaiful所说。

答案 5 :(得分:2)

lv.setSelector(R.drawable.highlighter);

highlighter.png图片放入drawable文件夹中
在列表视图中突出显示所选项目的最简单方法。

答案 6 :(得分:2)

//create a list_itemselectorin drawable folder
//you will get the list item selected background color change once you select //the item

    <selector xmlns:android="http://schemas.android.com/apk/res/android">

        <!-- Focused State -->
        <item android:state_focused="true"><shape>
                <solid android:color="#66FFFFFF" />
            </shape></item>
        <!-- Pressed State -->

        <item android:state_pressed="true"><shape>
                <solid android:color="@color/Black" />
            </shape></item>

        <!-- Default State -->
        <item><shape>
                <solid android:color="@color/Black" />
            </shape></item>

    </selector>


    //create a list in layout folder
      <ListView
            android:id="@+id/mySlidingList"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:choiceMode="singleChoice"
            android:divider="@color/GrayHot"
            android:dividerHeight="1dip"
            android:listSelector="@drawable/list_itemselector"
            android:scrollbars="none" />

//查看输出。

答案 7 :(得分:0)

如果您可以使用drawable显示listItem突出显示,那么您应该使用以下代码: -

listView.setSelector(R.drawable.bg_image);

有效。

答案 8 :(得分:0)

有一个简单的全XML解决方案,对我有用。 首先,使用选择器代码定义XML-drawable,其中“正常”状态将对应于列表项的“选择的未按下”视觉状态,并且state_pressed = true对应于“按下”视觉状态。 文件“custom_item_selector.xml”的示例,类似于Holo蓝色选择:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <solid
                android:color="#643292ff">
            </solid>
            <stroke
                android:width="1dp"
                android:color="#c83292ff">
            </stroke>
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <solid
                android:color="#323292ff">
            </solid>
            <stroke
                android:width="1dp"
                android:color="#783292ff">
            </stroke>
        </shape>
    </item>
</selector>

(也可以在那里设置聚焦状态)。 其次,将此xml-drawable应用为ListView的listSelector并设置它所需的choiceMode:

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

这就是全部。它允许为“简单选择”和“按下选定”项目定义不同的视觉状态,例如在按下时使项目更亮。

答案 9 :(得分:0)

要保持列表项(多项选择)突出显示,点击(激活)后,请按照步骤操作。

<强> 1。设置背景以将项目布局列为可绘制。

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

        <ImageView
            android:id="@+id/icon"
            android:layout_width="22px"
            android:layout_height="22px"
            android:layout_marginLeft="4px"
            android:layout_marginRight="10px"
            android:layout_marginTop="4px"
            android:src="@mipmap/ic_launcher" >
        </ImageView>

        <TextView
            android:id="@+id/label"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@+id/label"
            android:textSize="20px" >
        </TextView>
    </LinearLayout>

<强> 2。可绘制选择器

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

<item android:state_pressed="true"     android:drawable="@android:color/holo_red_light" />

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

</selector>

第3。 Listview设置多项选择模式

getListView()setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

按下时enter image description here

下图显示,当用户选择多个列表项时。

激活时enter image description here

答案 10 :(得分:0)

总结一下这篇文章,并可能在将来帮助别人我建议答案:)

首先,我们需要创建包含以下内容的res/drawable/list_item_background.xml文件:

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

当然,请指定您的可绘制资源。您还可以添加其他<item>元素以及state_pressedstate_focused等不同状态。

然后,我们应该将background参数设置为我们的自定义列表项ViewGroup元素(f.i. res/layout/list_item_layout.xml),如下所示:

android:background="@drawable/list_item_background"

下一步是修改我们的自定义Adapter课程。以下是代码片段:

public class CustomAdapter extends BaseAdapter {
    private List<Item> items;
    private LayoutInflater itemInflater;        
    private int selectedIndex; // add this

    public CustomAdapter(Context c, List<Item> items) {
        this.items = items;
        this.itemInflater = LayoutInflater.from(c);
        selectedIndex = -1; // add this
    }

    /* add this */
    public void setSelectedIndex(int index) {
        selectedIndex = index;
        notifyDataSetChanged();
    }

    /* other adapter's stuff */

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if(convertView == null) {
            convertView = itemInflater.inflate(R.layout.list_item_layout, parent, false);
        }

        // add this
        convertView.setActivated(selectedIndex != -1 && position == selectedIndex);

        /* do some stuff */

        return convertView;
    }
}

最后,我们应该在setSelectedIndex(position)的{​​{1}}方法中调用onItemClick(...)适配器的方法。

AdapterView.OnItemClickListener

现在,我们可以对突出显示的正确列表项感到满意:)

P.S。如果我们想在列表中启用多选模式,我们只需将以下字符串放在我们保存public class YourActivity extends Activity implements AdapterView.OnItemClickListener { private CustomAdapter mCustomAdapter; /* activity implementation */ @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { mCustomAdapter.setSelectedIndex(position); } } 实例的活动类中:

listView

因此,我们会突出显示正确的多个项目。

- 希望这有助于任何人:)