从 Fragments ListView 中的 CheckBox 启用上下文菜单
Enable the context menu from a CheckBox in a Fragments ListView
我有一个 Fragment
,其中嵌入了一个 ListView
和其他一些 View
。 ListView
正在为其列表项使用自定义布局,请参见下文。
编辑:这是我想要实现的。来自文档:
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
执行相同的操作?在 ArrayAdapter
或 Fragment
?
下面是自定义代码 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);
我有一个 Fragment
,其中嵌入了一个 ListView
和其他一些 View
。 ListView
正在为其列表项使用自定义布局,请参见下文。
编辑:这是我想要实现的。来自文档:
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
执行相同的操作?在 ArrayAdapter
或 Fragment
?
下面是自定义代码 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);