使用ActionMode多选列表视图 - 如何保留所选项目?

时间:2015-03-18 16:41:54

标签: android listview android-listview multi-select android-actionmode

我尝试使用已安装的应用创建ListView。用户在向导中选择应用程序(基本上是viewpager)。

我的计划是创建一个自定义视图列表(图标,名称,包),以允许选择多个项目。不幸的复选框不起作用,因为我需要这个地方用于其他功能。所以,我会改变元素的背景。

所以,我在stackoverflow上找到了一个解决方案并稍微改了一下。 首先 - 这个列表的主要活动。

public class MainActivity extends ListActivity {

    private static final String TAG = MainActivity.class.getName();
    private ApplicationsAdapter applicationsAdapter;

    private void getAppList(){

        //get apps asynch
        createList(list);
    }

    private void createList(ArrayList<ApplicationItem> list){
        applicationsAdapter = new ApplicationsAdapter(this, R.layout.application_list_item, list);

        setListAdapter(applicationsAdapter);
        getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);

        getListView().setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {

            private int nr = 0;

            @Override
            public boolean onCreateActionMode(android.view.ActionMode mode, Menu menu) {
                MenuInflater inflater = getMenuInflater();
                inflater.inflate(R.menu.cabselection_menu, menu);
                return true;
            }

            @Override
            public boolean onPrepareActionMode(android.view.ActionMode mode, Menu menu) {
                return false;
            }

            @Override
            public boolean onActionItemClicked(android.view.ActionMode mode, MenuItem item) {
                return false;
            }

            @Override
            public void onDestroyActionMode(android.view.ActionMode mode) {
                nr = 0;
                applicationsAdapter.clearSelection();
            }

            @Override
            public void onItemCheckedStateChanged(android.view.ActionMode mode, int position, long id, boolean checked) {
                if (checked) {
                    nr++;
                    applicationsAdapter.setNewSelection(position, checked);
                    L.d(TAG, applicationsAdapter.getItem(position).getAppName());
                } else {
                    nr--;
                    applicationsAdapter.removeSelection(position);
                }
                mode.setTitle(nr + " rows selected!");

            }

        });
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getAppList();
    }


    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        ApplicationItem item = (ApplicationItem)l.getAdapter().getItem(position);
        L.d(TAG + "onListItemClick", applicationsAdapter.getItem(position).getAppName());

        l.setItemChecked(position, !applicationsAdapter.isPositionChecked(position));
    }


}

就我而言,通常整个事情都在一个片段内,在viewpager中。为了清楚起见,我把它改成了典型的活动。

现在,适配器:

public class ApplicationsAdapter extends ArrayAdapter<ApplicationItem> {

//    private HashMap<ApplicationItem, Boolean> objects;
private HashMap<Integer, Boolean> mSelection = new HashMap<Integer, Boolean>();


public ApplicationsAdapter(Context context, int textViewResourceId, ArrayList<ApplicationItem> objects) {
    super(context, textViewResourceId, objects);
    //this.objects = objects;
}

public void setNewSelection(int position, boolean value) {
    mSelection.put(position, value);
    notifyDataSetChanged();
}

public boolean isPositionChecked(int position) {
    Boolean result = mSelection.get(position);
    return result == null ? false : result;
}

public Set<Integer> getCurrentCheckedPosition() {
    return mSelection.keySet();
}

public void removeSelection(int position) {
    mSelection.remove(position);
    notifyDataSetChanged();
}

public void clearSelection() {
    mSelection = new HashMap<Integer, Boolean>();
    notifyDataSetChanged();
}

public ApplicationItem getItem(int position){
    return super.getItem(position);
}

public View getView(int position, View convertView, ViewGroup parent){
    View v = convertView;

    if (v == null) {
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = inflater.inflate(R.layout.application_list_item, null);
    }

    ApplicationItem item = super.getItem(position);


    if(item != null){
        TextView appName = (TextView) v.findViewById(R.id.appName);
        TextView appPackage = (TextView) v.findViewById(R.id.appPackage);
        ImageView appIcon = (ImageView) v.findViewById(R.id.appIcon);

        if (appName != null){
            appName.setText(item.getAppName());
        }

        if (appPackage != null){
            appPackage.setText(item.getPackageName());
        }

        if (appIcon != null){
            appIcon.setImageDrawable(item.getIcon());
        }


    }

    v.setBackgroundColor(Color.parseColor("#00FFFFFF")); //default color
    if (mSelection.get(position) != null) {
        v.setBackgroundColor(Color.BLUE);// this is a selected position so make it red
    }

    return v;
}
}

问题: ActionMode很不错,但我不确定在它被破坏后如何​​保留所选元素。 通常在onDestroyActionMode内部我清除选择。很好,所以我只是删除它。现在点击&#34;勾选&#34;符号仍然选中所有应用程序。但是,回到它们现在是有问题的,因为ActionMode只会启动#34;单击未选中的元素时。

那么 - 我该怎么处理呢?

1 个答案:

答案 0 :(得分:0)

哈,答案很简单。我昨天应该考虑一下,但显然我有点太累了。

首先,我将listview的模式改为

getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

已删除setMultiChoiceModeListener(),我只使用

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    ApplicationItem item = (ApplicationItem)l.getAdapter().getItem(position);
    L.d(TAG + "onListItemClick", applicationsAdapter.getItem(position).getAppName());

    boolean checked = item.isSelected();

    if (!checked) {
        item.setSelected(true);
        applicationsAdapter.setNewSelection(position, checked);
        L.d(TAG, applicationsAdapter.getItem(position).getAppName());
    } else {
        item.setSelected(false);
        applicationsAdapter.removeSelection(position);
    }
}

那很简单。 显然,ActionMode可能很有趣,但它不适合这项工作。

而且 - 来自第一篇文章的适配器可以用作更改背景而不是复选框的多选列表视图的示例。显然我找不到那么简单的东西。