从 Fragments ListView 中的 CheckBox 启用上下文菜单

Enable the context menu from a CheckBox in a Fragments ListView

我有一个 Fragment,其中嵌入了一个 ListView 和其他一些 ViewListView 正在为其列表项使用自定义布局,请参见下文。

编辑:这是我想要实现的。来自文档:

In some cases in which the contextual actions provide common action items, you might want to add a checkbox or a similar UI element that allows users to select items, because they might not discover the long-click behavior. When a user selects the checkbox, you can invoke the contextual action mode by setting the respective list item to the checked state with setItemChecked().

CustomListViewItem.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_margin="@dimen/activity_vertical_margin"
    android:layout_width="match_parent"
    android:weightSum="10"
    android:layout_height="wrap_content">

    <LinearLayout
        android:layout_weight="1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:textStyle="bold"
            android:layout_width="wrap_content"
            android:ellipsize="end"
            android:singleLine="true"
            android:layout_height="wrap_content"
            android:text="New Text"
            android:id="@+id/tvNotesListAdapterTitle" />

        <TextView
            android:textStyle="italic"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="New Text"
            android:id="@+id/tvNotesListAdapterTimestamp" />
    </LinearLayout>

    <RelativeLayout

        android:layout_weight="9"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <CheckBox
            android:id="@+id/cb_notes"
            android:button="@null"
            android:drawableRight="?android:attr/listChoiceIndicatorMultiple"
            android:drawableEnd="?android:attr/listChoiceIndicatorMultiple"
            android:layout_centerVertical="true"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />
    </RelativeLayout>


</LinearLayout>

CheckBox 的目的是让用户能够调用 Contextual Menu。但是,我似乎没有做对。正如开发人员示例所示,我在长按 ListView 项时成功调用了上下文菜单。这是在托管 ListView.

Fragment 中完成的

如何以及在何处对 ListView 中的 CheckBox 执行相同的操作?在 ArrayAdapterFragment?

下面是自定义代码 ArrayAdapter

CustomArrayAdapter.java:

public class NotesArrayAdapter extends ArrayAdapter<Note> {

    private ArrayList<Note> allNotes;

    public NotesArrayAdapter(Context ctx, ArrayList<Note> allNotes) {
        super(ctx, R.layout.arrayadapter_notes, allNotes);
        this.allNotes = allNotes;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row;
        if (convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(getContext());
            //R.layout.arrayadapter_notes is my custom layout for my ListView items.
            row = inflater.inflate(
                    R.layout.arrayadapter_notes, null);
        } else {
            row = convertView;
        }

        TextView tvTitle = (TextView) row.findViewById(R.id.tvNotesListAdapterTitle);
        TextView tvTimeStamp = (TextView) row.findViewById(R.id.tvNotesListAdapterTimestamp);

        String timeStamp = allNotes.get(position).getTimestamp();
        String note = allNotes.get(position).getNote();

        tvTitle.setText(note);
        tvTimeStamp.setText(timeStamp);

        return row;
    }

}

我还没有找到上述内容的任何工作示例。在这件事上的任何帮助将不胜感激。简而言之,当一个或多个 CheckBox 被选中时,我不确定在哪里以及如何调用上下文菜单。

通过在我的 ArrayAdapter class 中实现回调接口解决了这个问题

private NotesAdapterCallback callback;

public interface NotesAdapterCallback {
    public void checkBoxChecked();
}

public void setCallback(NotesAdapterCallback callback) {
    this.callback = callback;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row;
    if (convertView == null) {
        LayoutInflater inflater = LayoutInflater.from(getContext());
        row = inflater.inflate(
                R.layout.arrayadapter_notes, null);
    } else {
        row = convertView;
    }

    TextView tvTitle = (TextView) row.findViewById(R.id.tvNotesListAdapterTitle);
    TextView tvTimeStamp = (TextView) row.findViewById(R.id.tvNotesListAdapterTimestamp);
    CheckBox cbNote = (CheckBox) row.findViewById(R.id.cb_notes);

    String timeStamp = allNotes.get(position).getTimestamp();
    String note = allNotes.get(position).getNote();

    tvTitle.setText(note);
    tvTimeStamp.setText(timeStamp);

    cbNote.setOnCheckedChangeListener(this);

    return row;

}

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    if (isChecked) {
        if (callback != null) {
            callback.checkBoxChecked();
        }
    }
}

并像这样在我的 Fragment 中实现接口

private ActionMode mActionMode;

@Override
public void checkBoxChecked() {
    if (mActionMode != null) {
        return;
    }else{
        mActionMode = getActivity().startActionMode(mActionModeCallback);
    }
}

private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {

    // Called when the action mode is created; startActionMode() was called
    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        // Inflate a menu resource providing context menu items
        MenuInflater inflater = mode.getMenuInflater();
        inflater.inflate(R.menu.context, menu);
        return true;
    }

    // Called each time the action mode is shown. Always called after onCreateActionMode, but
    // may be called multiple times if the mode is invalidated.
    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false; // Return false if nothing is done
    }

    // Called when the user selects a contextual menu item
    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        switch (item.getItemId()) {
            case R.id.context_delete:

                mode.finish(); // Action picked, so close the CAB
                return true;
            case R.id.context_move:

                mode.finish(); // Action picked, so close the CAB
                return true;
            default:
                return false;
        }
    }

    // Called when the user exits the action mode
    @Override
    public void onDestroyActionMode(ActionMode mode) {
        mActionMode = null;
    }
};

不要忘记在 ArrayAdapter

上设置回调
notesAdapter = new NotesArrayAdapter(getActivity(), allNotes);
lwNotes.setAdapter(notesAdapter);
notesAdapter.setCallback(this);