15

您不能使用以下状态可绘制作为列表视图项的背景。

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

在 Pre Honeycomb 设备上,因为那里不支持此选择器,并且 android 版本不跟踪激活的项目。

如何模仿这种行为?尤其是在使用片段时(在一个片段的左侧列出,并根据选择的内容在右侧显示详细视图),此指标非常重要。

我知道这个问题之前在这里被问过,但是那里接受的答案链接到博客文章,该文章在“步骤 4”中指出不可能激活指示器,而只是禁用使用以防止错误。这导致没有显示我正在搜索的指标。

4

4 回答 4

28

我用一个小技巧解决了这个问题:通过滥用state_checked自 Android 版本 1 以来就存在的属性,可以模拟state_activated行为。无需自己修改 List 适配器或保存状态。

我写了一个详细的例子,其中包含了所有必要的代码来复制并将它发布在一个github 存储库上。

于 2012-12-13T15:49:26.400 回答
3

就像 Chris Jenkins 建议的那样,我只是在我的getView覆盖中添加了一些代码:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    // ...

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
        convertView.setBackgroundColor(Color.WHITE);
        if (listView.isItemChecked(position)) {
            convertView.setBackgroundColor(Color.LTGRAY);
        }
    }
}

在我的情况下,是否自动处理了被检查的项目(使用 CHOICE_MODE_MULTIPLE 和 v7 ActionMode.Callback 和 setOnItemLongClickListener 调用回调)

于 2013-11-22T15:24:56.943 回答
0

只需将适配器中选定列表项的背景更改为“已激活”可绘制对象。

所以在我的适配器中获取视图方法可能看起来像这样:

getView(int pos, View convertView, ViewGroup parent){
//... etc get view etc
    if(mSelectedItemPos == pos){
        v.setBackgroundDrawable(ctx.getResources().getDrawable(R.drawable.list_item_selected_state);
        //or v.setBackgroundResource(R.drawable.list_item.....);
    } else {
        v.setBackgroundDrawable(ctx.getResources().getDrawable(R.drawable.list_item_selector);            
    }
}

如果我想支持视图上的选定/激活状态,这就是我所做的一切。更多的工作,但可以像你想要的那样灵活。

于 2012-11-23T14:48:52.397 回答
0

我之前通过以下方式手动完成了它:

创建一个数组来保存列表的选定状态,在适配器构造函数中对其进行初始化,然后在您的 getView 方法(以防当前选定的项目滚动出视图)和您的 onItemClick 方法(以更改当前选择并打开关闭旧的)。

public static boolean selectedStatus[];  // array to hold selected state
public static View oldView;        // view to hold so we can set background back to normal after 

构造 函数初始化数组

public class MyCursorAdapter extends SimpleCursorAdapter {
    private LayoutInflater mInflater;
    private int layout;

    public MyCursorAdapter(Context context, int layout, Cursor c,
        String[] from, int[] to, int flags) {
            super(context, layout, c, from, to, flags);
            mInflater = LayoutInflater.from(context);
            this.layout = layout;
            selectedStatus = new boolean[c.getCount()];
            for (int i = 0; i < c.getCount(); i++) {
            selectedStatus[i] = false;  // Start with all items unselected
        }
    }
} 

当孩子滚动出视图时需要getView

@Override 
public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null)
         convertView = View.inflate(context, layout, null);

    if(selectedStatus[position] == true){
        v.setBackgroundResource(R.color.blue);                          
    } else {
        v.setBackgroundResource(R.color.black);
    }
    return v; 
} 

onItemClick 更改数组和屏幕上的选定项目

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

        mRowId = id;
        EventDisplayFragment eventdisplay = new EventDisplayFragment();
        getFragmentManager().beginTransaction()
                .replace(R.id.rightpane, eventdisplay).commit();
        if(MyCursorAdapter.oldView != null){
            MyCursorAdapter.oldView.setBackgroundResource(R.color.black);   // change the background of the old selected item back to default black                 }
        MyCursorAdapter.oldView = v;                                        // set oldView to current view so we have a reference to change back on next selection
        for (int i = 0; i < selectedStatus.length; i++) {
            if(i == position){                              // set the current view to true and all others to false
                    selectedStatus[i] = true;
                } else {
                    selectedStatus[i] = false;
                }
            }
        }
        v.setBackgroundResource(R.color.blue);
        return true;
    }
});
于 2012-11-23T15:17:22.357 回答