根据选择的数量更改 ActionBar 项目
Change ActionBar items depending on how many selected
如何根据 RecyclerView 中选择的项目数更改 ActionBar
菜单包含的内容?例如,当在 'selection mode,' 中选择一张卡片时,我希望编辑图标(铅笔)可见。一旦选择了多个项目,我希望“编辑”图标从选项中消失。
下面的代码: 我尝试创建一个条件,如果所选项目的数量为 [=13],mDeletionMode
创建一个带有编辑图标的菜单=] ,如果数字大于一,则创建一个没有铅笔的菜单。我的方法是愚蠢的,因为我意识到菜单是在一个项目经历 longClick
之后才创建的,当然那时候只会选择一个项目。我离开了 dumb-dumb code
我曾经尝试过这个只是为了展示我的方法,而我实际上正在寻找的是以下内容:
public class SubjectManagerFragment extends BaseFragment implements ActionMode.Callback {
public static ArrayList<SubjectInfo> subjectList = new ArrayList<SubjectInfo>();
public static FloatingActionButton fabCreateSubject;
private AlertDialog.Builder build;
private MultiSelector mMultiSelector = new MultiSelector();
public ActionMode actionMode;
public RecyclerView recList;
public CardView cardView;
public ItemClickSupport itemClick;
// currently an adaptation from:
// https://github.com/bignerdranch/recyclerview-multiselect#modal-multiselection-with-long-click
public ActionMode.Callback mDeleteMode = new ModalMultiSelectorCallback(mMultiSelector) {
@Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
super.onCreateActionMode(actionMode, menu);
if (mMultiSelector.getSelectedPositions().size() <= 1) {
getActivity().getMenuInflater().inflate(R.menu.menu_subject_manager, menu);
} else {
getActivity().getMenuInflater().inflate(R.menu.menu_subject_manager_multiple, menu);
}
return true;
}
@Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.action_select_all:
// Delete crimes from model
//actually do nothing.
mMultiSelector.clearSelections();
return true;
default:
break;
}
return false;
}
};
public static final String ARG_PARAM1 = "param1";
public static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
public static SubjectManagerFragment newInstance(String param1, String param2) {
SubjectManagerFragment fragment = new SubjectManagerFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public SubjectManagerFragment() {
// Required empty public constructor
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
//non graphical initialization
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(false);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View smFragmentView = inflater.inflate(R.layout.fragment_subject_manager, container, false);
recList = (RecyclerView) smFragmentView.findViewById(R.id.subject_card_list);
cardView = (CardView) smFragmentView.findViewById(R.id.subject_card);
recList.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
llm.setOrientation(LinearLayoutManager.VERTICAL);
subjectList = getSubjectInfoArrayList();
recList.setLayoutManager(llm);
recList.setAdapter(new CrimeAdapter());
fabCreateSubject = (FloatingActionButton) smFragmentView.findViewById(R.id.fab_create_subject);
fabCreateSubject.setOnClickListener (new View.OnClickListener() {
@Override
public void onClick(View v) {
build = new AlertDialog.Builder(getActivity());
LayoutInflater inflater1 = getActivity().getLayoutInflater();
View alertview = inflater1.inflate(R.layout.create_subject_dialog, null);
// Pass null as the parent view because its going in the dialog layout
build.setView(alertview);
final EditText inputSubjectName = (EditText) alertview.findViewById(R.id.dialog_edit_subject_card_name);
final EditText inputSubjectGrade = (EditText) alertview.findViewById(R.id.dialog_edit_subject_card_grade);
build.setTitle("Add Subject");
build.setPositiveButton("Save", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
String enteredSubjectName = inputSubjectName.getText().toString();
int enteredSubjectGrade = Integer.parseInt("0" + inputSubjectGrade.getText().toString()); //was getting stupid error from null value going to int?
boolean enteredSubjectIsArchived = false;
if (subjectCanBeEntered(inputSubjectName, inputSubjectGrade, subjectList)) {
SubjectInfo si = new SubjectInfo(enteredSubjectName, "Assignments", enteredSubjectGrade, enteredSubjectIsArchived, true);
si.save();
subjectList.add(si);
getActivity().recreate();
sa.notifyDataSetChanged();
recList.smoothScrollToPosition(subjectList.size()-1);
} //will need to check if subject already exists, but YOLO for now.
dialog.cancel();
}
});
build.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = build.create();
alert.show();
}
});
// Inflate the layout for this fragment
return smFragmentView;
}
public ArrayList<SubjectInfo> getSubjectInfoArrayList(){
ArrayList<SubjectInfo> sial= new ArrayList<SubjectInfo>();
List<SubjectInfo> sil = SubjectInfo.listAll(SubjectInfo.class);
sial.addAll(sil);
for (int go = 0; go <sial.size(); go++) {
if (sial.get(go).itemHeaderTitle.equals("Archived")) {
sial.remove(go);
}
}
return sial;
}
public boolean subjectCanBeEntered (EditText inputName, EditText inputGrade, ArrayList<SubjectInfo> aList) {
boolean enterable = true;
if ((inputName.getText().toString().equals(""))) {
enterable = false;
Toast.makeText(
getActivity().getApplicationContext(), "Enter a class name.", Toast.LENGTH_SHORT).show();
}
if ((inputGrade.getText().toString().equals(""))) { // I don't think hint is picked up
enterable = false;
Toast.makeText(
getActivity().getApplicationContext(), "Enter a grade.", Toast.LENGTH_SHORT).show();
}
for (int go = 0; go < aList.size(); go++) {
if (inputName.getText().toString().equals(aList.get(go).subjectName)) {
enterable = false;
Toast.makeText(
getActivity().getApplicationContext(), "You've already saved a class with that name.", Toast.LENGTH_LONG).show();
}
}
return enterable;
}
private class CrimeHolder extends SwappingHolder
implements View.OnClickListener, View.OnLongClickListener {
protected TextView vSubjectName;
protected EditText vSubjectGrade;
protected RelativeLayout vSubjectLayout;
private SubjectInfo sInfo;
public CrimeHolder(View itemView) {
super(itemView, mMultiSelector);
vSubjectName = (TextView) itemView.findViewById(R.id.subject_card_name_textView);
vSubjectGrade = (EditText) itemView.findViewById(R.id.subject_card_grade_editText);
vSubjectLayout = (RelativeLayout) itemView.findViewById(R.id.subject_card_relative_layout);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
itemView.setLongClickable(true);
}
public void bindCrime(SubjectInfo si) {
sInfo = si;
vSubjectName.setText(sInfo.subjectName);
vSubjectGrade.setText(Integer.toString(si.subjectGrade));
vSubjectLayout.setBackgroundColor(Color.parseColor(SubjectAdapter.giveSubjectHexValue((double) si.subjectGrade)));
}
@Override
public void onClick(View v) {
if (sInfo == null) {
return;
}
if (!mMultiSelector.tapSelection(this)) {
// This condition is the same as, if not in ActionMode, handle the click normally:
//getActionBar().startActionMode(mDeleteMode);
}
}
@Override
public boolean onLongClick(View v) {
//ActionBarActivity activity = (ActionBarActivity)getActivity();
getActionBar().startActionMode(mDeleteMode);
mMultiSelector.setSelected(this, true);
return true;
}
}
private class CrimeAdapter extends RecyclerView.Adapter<CrimeHolder> {
@Override
public CrimeHolder onCreateViewHolder(ViewGroup parent, int pos) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.subject_card_layout, parent, false);
return new CrimeHolder(view);
}
@Override
public void onBindViewHolder(CrimeHolder holder, int pos) {
SubjectInfo sInfo = subjectList.get(pos);
holder.bindCrime(sInfo);
}
@Override
public int getItemCount() {
return subjectList.size();
}
}
}
所以我的问题是:如何以编程方式或者remove/add编辑图标或 切换到另一个菜单(少一个选项),具体取决于项目的选择方式。
使用 ActionMode 实例来操作 ActionBar 菜单。
@Override
public boolean onLongClick(View v) {
this.actionMode = getActionBar().startActionMode(mDeleteMode);
mMultiSelector.setSelected(this, true);
return true;
}
下面是您的 menuItem
初始化的地方。请记住 onCreateActionMode
存在于 new ModalMultiSelectorCallback
.
的创建中
@Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
super.onCreateActionMode(actionMode, menu);getActivity().getMenuInflater().inflate(R.menu.menu_subject_manager, menu);
mEditItem = actionMode.getMenu().findItem(R.id.action_edit);
mActionMenu = actionMode.getMenu();
return true;
}
现在,mEditItem
可以轻松删除或替换,因为 mEditItem
是一个实例变量。我将在 onClick()
中提供我的实现
@Override
public void onClick(View v) {
if (sInfo == null) {
return;
}
if (!mMultiSelector.tapSelection(this)) {
// if not in selection mode, this is handled
}
if (mMultiSelector.tapSelection(this)) {
mMultiSelector.tapSelection(this);
switch (mMultiSelector.getSelectedPositions().size()) {
case 0:
actionMode.finish();
break;
case 1:
mEditItem.setVisible(true);
break;
case 2:
mEditItem.setVisible(false);
break;
default:
break;
}
}
}
我知道了。对我来说,我只需要根据在任何给定时刻选择的项目数来 disappear/reappear 一个项目。 .setVisible()
方法为我解决了这个问题。我希望这对遇到类似问题的人有所帮助!
如何根据 RecyclerView 中选择的项目数更改 ActionBar
菜单包含的内容?例如,当在 'selection mode,' 中选择一张卡片时,我希望编辑图标(铅笔)可见。一旦选择了多个项目,我希望“编辑”图标从选项中消失。
下面的代码: 我尝试创建一个条件,如果所选项目的数量为 [=13],mDeletionMode
创建一个带有编辑图标的菜单=] ,如果数字大于一,则创建一个没有铅笔的菜单。我的方法是愚蠢的,因为我意识到菜单是在一个项目经历 longClick
之后才创建的,当然那时候只会选择一个项目。我离开了 dumb-dumb code
我曾经尝试过这个只是为了展示我的方法,而我实际上正在寻找的是以下内容:
public class SubjectManagerFragment extends BaseFragment implements ActionMode.Callback {
public static ArrayList<SubjectInfo> subjectList = new ArrayList<SubjectInfo>();
public static FloatingActionButton fabCreateSubject;
private AlertDialog.Builder build;
private MultiSelector mMultiSelector = new MultiSelector();
public ActionMode actionMode;
public RecyclerView recList;
public CardView cardView;
public ItemClickSupport itemClick;
// currently an adaptation from:
// https://github.com/bignerdranch/recyclerview-multiselect#modal-multiselection-with-long-click
public ActionMode.Callback mDeleteMode = new ModalMultiSelectorCallback(mMultiSelector) {
@Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
super.onCreateActionMode(actionMode, menu);
if (mMultiSelector.getSelectedPositions().size() <= 1) {
getActivity().getMenuInflater().inflate(R.menu.menu_subject_manager, menu);
} else {
getActivity().getMenuInflater().inflate(R.menu.menu_subject_manager_multiple, menu);
}
return true;
}
@Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.action_select_all:
// Delete crimes from model
//actually do nothing.
mMultiSelector.clearSelections();
return true;
default:
break;
}
return false;
}
};
public static final String ARG_PARAM1 = "param1";
public static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
public static SubjectManagerFragment newInstance(String param1, String param2) {
SubjectManagerFragment fragment = new SubjectManagerFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public SubjectManagerFragment() {
// Required empty public constructor
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
//non graphical initialization
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(false);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View smFragmentView = inflater.inflate(R.layout.fragment_subject_manager, container, false);
recList = (RecyclerView) smFragmentView.findViewById(R.id.subject_card_list);
cardView = (CardView) smFragmentView.findViewById(R.id.subject_card);
recList.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
llm.setOrientation(LinearLayoutManager.VERTICAL);
subjectList = getSubjectInfoArrayList();
recList.setLayoutManager(llm);
recList.setAdapter(new CrimeAdapter());
fabCreateSubject = (FloatingActionButton) smFragmentView.findViewById(R.id.fab_create_subject);
fabCreateSubject.setOnClickListener (new View.OnClickListener() {
@Override
public void onClick(View v) {
build = new AlertDialog.Builder(getActivity());
LayoutInflater inflater1 = getActivity().getLayoutInflater();
View alertview = inflater1.inflate(R.layout.create_subject_dialog, null);
// Pass null as the parent view because its going in the dialog layout
build.setView(alertview);
final EditText inputSubjectName = (EditText) alertview.findViewById(R.id.dialog_edit_subject_card_name);
final EditText inputSubjectGrade = (EditText) alertview.findViewById(R.id.dialog_edit_subject_card_grade);
build.setTitle("Add Subject");
build.setPositiveButton("Save", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
String enteredSubjectName = inputSubjectName.getText().toString();
int enteredSubjectGrade = Integer.parseInt("0" + inputSubjectGrade.getText().toString()); //was getting stupid error from null value going to int?
boolean enteredSubjectIsArchived = false;
if (subjectCanBeEntered(inputSubjectName, inputSubjectGrade, subjectList)) {
SubjectInfo si = new SubjectInfo(enteredSubjectName, "Assignments", enteredSubjectGrade, enteredSubjectIsArchived, true);
si.save();
subjectList.add(si);
getActivity().recreate();
sa.notifyDataSetChanged();
recList.smoothScrollToPosition(subjectList.size()-1);
} //will need to check if subject already exists, but YOLO for now.
dialog.cancel();
}
});
build.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = build.create();
alert.show();
}
});
// Inflate the layout for this fragment
return smFragmentView;
}
public ArrayList<SubjectInfo> getSubjectInfoArrayList(){
ArrayList<SubjectInfo> sial= new ArrayList<SubjectInfo>();
List<SubjectInfo> sil = SubjectInfo.listAll(SubjectInfo.class);
sial.addAll(sil);
for (int go = 0; go <sial.size(); go++) {
if (sial.get(go).itemHeaderTitle.equals("Archived")) {
sial.remove(go);
}
}
return sial;
}
public boolean subjectCanBeEntered (EditText inputName, EditText inputGrade, ArrayList<SubjectInfo> aList) {
boolean enterable = true;
if ((inputName.getText().toString().equals(""))) {
enterable = false;
Toast.makeText(
getActivity().getApplicationContext(), "Enter a class name.", Toast.LENGTH_SHORT).show();
}
if ((inputGrade.getText().toString().equals(""))) { // I don't think hint is picked up
enterable = false;
Toast.makeText(
getActivity().getApplicationContext(), "Enter a grade.", Toast.LENGTH_SHORT).show();
}
for (int go = 0; go < aList.size(); go++) {
if (inputName.getText().toString().equals(aList.get(go).subjectName)) {
enterable = false;
Toast.makeText(
getActivity().getApplicationContext(), "You've already saved a class with that name.", Toast.LENGTH_LONG).show();
}
}
return enterable;
}
private class CrimeHolder extends SwappingHolder
implements View.OnClickListener, View.OnLongClickListener {
protected TextView vSubjectName;
protected EditText vSubjectGrade;
protected RelativeLayout vSubjectLayout;
private SubjectInfo sInfo;
public CrimeHolder(View itemView) {
super(itemView, mMultiSelector);
vSubjectName = (TextView) itemView.findViewById(R.id.subject_card_name_textView);
vSubjectGrade = (EditText) itemView.findViewById(R.id.subject_card_grade_editText);
vSubjectLayout = (RelativeLayout) itemView.findViewById(R.id.subject_card_relative_layout);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
itemView.setLongClickable(true);
}
public void bindCrime(SubjectInfo si) {
sInfo = si;
vSubjectName.setText(sInfo.subjectName);
vSubjectGrade.setText(Integer.toString(si.subjectGrade));
vSubjectLayout.setBackgroundColor(Color.parseColor(SubjectAdapter.giveSubjectHexValue((double) si.subjectGrade)));
}
@Override
public void onClick(View v) {
if (sInfo == null) {
return;
}
if (!mMultiSelector.tapSelection(this)) {
// This condition is the same as, if not in ActionMode, handle the click normally:
//getActionBar().startActionMode(mDeleteMode);
}
}
@Override
public boolean onLongClick(View v) {
//ActionBarActivity activity = (ActionBarActivity)getActivity();
getActionBar().startActionMode(mDeleteMode);
mMultiSelector.setSelected(this, true);
return true;
}
}
private class CrimeAdapter extends RecyclerView.Adapter<CrimeHolder> {
@Override
public CrimeHolder onCreateViewHolder(ViewGroup parent, int pos) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.subject_card_layout, parent, false);
return new CrimeHolder(view);
}
@Override
public void onBindViewHolder(CrimeHolder holder, int pos) {
SubjectInfo sInfo = subjectList.get(pos);
holder.bindCrime(sInfo);
}
@Override
public int getItemCount() {
return subjectList.size();
}
}
}
所以我的问题是:如何以编程方式或者remove/add编辑图标或 切换到另一个菜单(少一个选项),具体取决于项目的选择方式。
使用 ActionMode 实例来操作 ActionBar 菜单。
@Override
public boolean onLongClick(View v) {
this.actionMode = getActionBar().startActionMode(mDeleteMode);
mMultiSelector.setSelected(this, true);
return true;
}
下面是您的 menuItem
初始化的地方。请记住 onCreateActionMode
存在于 new ModalMultiSelectorCallback
.
@Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
super.onCreateActionMode(actionMode, menu);getActivity().getMenuInflater().inflate(R.menu.menu_subject_manager, menu);
mEditItem = actionMode.getMenu().findItem(R.id.action_edit);
mActionMenu = actionMode.getMenu();
return true;
}
现在,mEditItem
可以轻松删除或替换,因为 mEditItem
是一个实例变量。我将在 onClick()
@Override
public void onClick(View v) {
if (sInfo == null) {
return;
}
if (!mMultiSelector.tapSelection(this)) {
// if not in selection mode, this is handled
}
if (mMultiSelector.tapSelection(this)) {
mMultiSelector.tapSelection(this);
switch (mMultiSelector.getSelectedPositions().size()) {
case 0:
actionMode.finish();
break;
case 1:
mEditItem.setVisible(true);
break;
case 2:
mEditItem.setVisible(false);
break;
default:
break;
}
}
}
我知道了。对我来说,我只需要根据在任何给定时刻选择的项目数来 disappear/reappear 一个项目。 .setVisible()
方法为我解决了这个问题。我希望这对遇到类似问题的人有所帮助!