【问题标题】:setSelected works in onLongClick() but doesn't work in bindView()setSelected 在 onLongClick() 中有效,但在 bindView() 中无效
【发布时间】:2015-08-03 06:23:33
【问题描述】:

我正在实现CAB,我的 ListView 是从数据库中填充的。当我滚动 ListView 或旋转设备屏幕时,之前选择的项目的背景将恢复为默认背景。

我用来存储选择状态以在bindView中恢复它的持有人:

private static class ViewInfo {
    boolean selected;
}

绑定视图:

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        view.setOnLongClickListener(mOnLongClickListener);
        Object tag = view.getTag();
        if (tag != null) {
            ViewInfo info = (ViewInfo) view.getTag();
            view.setSelected(info.selected);
        } else {
            view.setTag(new ViewInfo());
        }

        // Load data from the database here
    }

OnLongClickListener:

mOnLongClickListener = new OnLongClickListener() {

    @Override
    public boolean onLongClick(View v) {
        ViewInfo viewInfo = (ViewInfo) v.getTag();
        v.setSelected(viewInfo.selected = !viewInfo.selected);
        return true;
    }
};

我的列表视图:

<ListView
    android:id="@+id/filtering_list"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:choiceMode="multipleChoiceModal"
    android:drawSelectorOnTop="true" />

我的列表项背景filtering_list_item_bg

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

    <item android:drawable="@android:color/holo_blue_light" android:state_pressed="true"/>
    <!-- pressed -->
    <item android:drawable="@android:color/holo_blue_light" android:state_focused="true"/>
    <!-- focused -->
    <item android:drawable="@android:color/background_light" android:state_selected="true"/>

</selector>

我的列表项布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/filtering_list_item_bg"
    android:paddingBottom="12dp"
    android:paddingLeft="8dp"
    android:paddingRight="8dp"
    android:paddingTop="12dp" >

    <!-- text views, image views, etc. -->

</RelativeLayout>

我在这里无法理解的是为什么setSelectedbindView 中被调用但不改变背景。

【问题讨论】:

标签: android listview


【解决方案1】:

我设法在没有setSelected 的情况下保存了所选项目的颜色。

我的列表项没有背景颜色。它是根据当前状态(选择/未选择)以编程方式分配的。

我的列表项布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="12dp"
    android:paddingLeft="8dp"
    android:paddingRight="8dp"
    android:paddingTop="12dp" >
    <!-- text views, image views, etc. -->
</RelativeLayout>

我的列表视图。

<ListView
        android:id="@+id/filtering_list"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

OtItemLongClickListener。我将所选项目保存到哈希表,因为它offers O(1) for the get, put, and remove operations.

mFilteringListView.setOnItemLongClickListener(new OnItemLongClickListener() {

    @Override
    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
        if (mAdapter.mSelectedIds.get(id) == null || !mAdapter.mSelectedIds.get(id)) {
            mAdapter.mSelectedIds.put(id, true);
            view.setBackgroundColor(getActivity().getResources().getColor(R.color.highlighted_item));
        } else {
            /*
             * I don't put a false because there is no reason to store unselected items.
             * If the user selects and unselects items much, the hash table will grow
             * rapidly
             * 
             * Maksim Dmitriev
             * May 21, 2015
             */
            mAdapter.mSelectedIds.remove(id);
            view.setBackgroundColor(getActivity().getResources().getColor(android.R.color.white));
        }
        return true;
    }
});

为哈希表中的每个项目恢复背景的 ListView 适配器:

private static class ListAdapter extends SimpleCursorAdapter {

    final Context mContext;
    LongSparseArray<Boolean> mSelectedIds = new LongSparseArray<Boolean>();

    public ListAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
        super(context, layout, c, from, to, flags);
        mContext = context;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        long id = cursor.getInt(cursor.getColumnIndex(Columns._ID));
        if (mSelectedIds.get(id) == null || !mSelectedIds.get(id)) {
            view.setBackgroundColor(mContext.getResources().getColor(android.R.color.white));
        } else {
            view.setBackgroundColor(mContext.getResources().getColor(R.color.highlighted_item));
        }
        // fill the other text views, image views, etc.
    }
}

【讨论】:

    【解决方案2】:

    您在哪里将选择器设置为列表项?你需要这样做。

    试试这个 - 转到您的列表项 XML 代码,假设外部布局如下所示

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:background="@drawable/my_selector"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    注意线 - android:background =“@ drawable / my_selector” - 您需要在列表项中添加它,然后选择它将更改颜色等。

    将长按监听器添加到您的 listView 而不是项目 - 您的 bitbucket 存储库中的第 173 行应该是

     mAdapter = new ListAdapter(getActivity(),
                    R.layout.filter_list_item,
                    null,
                    COLUMNS,
                    new int[] { R.id.ip_address, R.id.port },
                    0);
    
            mFilteringListView.setAdapter(mAdapter);
    
           mFilteringListView.setOnLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                ViewInfo viewInfo = (ViewInfo) v.getTag();
                    if (viewInfo.selected) {
                        mSelectedCount--;
                    } else {
                        mSelectedCount++;
                    }
                    v.setSelected(viewInfo.selected = !viewInfo.selected);
                    if (mSelectedCount > 0) {
                        mActivity.startActionMode(mActionModeCallback);
                    }
                    return true;
            }
        });
    

    【讨论】:

    • 我编辑了我的问题。我是否正确设置了背景?我添加的内容不起作用。
    • 远程这两行,它应该可以工作 - android:choiceMode="multipleChoiceModal" android:drawSelectorOnTop="true"
    • 是的,我的意思是*删除。列表项布局的其余部分是什么样的?你真的能看到列表中的任何项目吗?
    • 是的,我看到了我的所有物品。问题是setSelectedbindView 中被调用但不改变背景。
    猜你喜欢
    • 2021-03-04
    • 2015-07-21
    • 2015-11-13
    • 2016-02-19
    • 2014-10-23
    • 2022-01-23
    • 2010-11-24
    • 2018-11-01
    • 2016-03-09
    相关资源
    最近更新 更多