上一篇我们实现了日记的保存,本篇我们就日记的删除功能进行实现。
首先我们在NoteItemFragment中定义一个接口,用来实现日记保存与删除的功能。
private NoteItemListener noteItemListener;
/**
* @param noteItemListener 传入Activity的context
*/
public void setNoteItemListener(NoteItemListener noteItemListener) {
this.noteItemListener = noteItemListener;
}
/**
* 日记保存和删除接口
*/
public interface NoteItemListener {
public void onNoteItemSaveListener(NoteItem noteItem);
public void onNoteItemDeleteListener(NoteItem noteItem);
}
在接收到用户点击保存或者删除事件后转发至NotePagerActivity进行处理:
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_note_save:
noteItemListener.onNoteItemSaveListener(noteItem);
return true;
case R.id.menu_note_delete:
noteItemListener.onNoteItemDeleteListener(noteItem);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
在NotePagerActivity中我们需要修改实例化NoteItemFragment的代码,需要在该Activity中实现上面的接口。
public class NotePagerActivity extends BaseActivity implements NoteItemFragment.NoteItemListener {
@Override
public void onNoteItemSaveListener(NoteItem noteItem) {
int position = viewPager.getCurrentItem();
noteItemList.remove(position);
noteItemList.add(position, noteItem);
notePagerAdapter.notifyDataSetChanged();
viewPager.setCurrentItem(position);
noteListSave();
}
@Override
public void onNoteItemDeleteListener(NoteItem noteItem) {
int position = viewPager.getCurrentItem();
noteItemList.remove(position);
noteListSave();
if (noteItemList.size() == 0) {
setResult(Activity.RESULT_OK, new Intent());
finish();
}
notePagerAdapter.notifyDataSetChanged();
viewPager.setCurrentItem(position);
}
在NotePagerAdapter中我们需要修改getItem方法,在生成fragment实例的时候,设置NoteItemListener:
public Fragment getItem(int position) {
NoteItemFragment noteItemFragment = NoteItemFragment.newInstance(noteItemList.get(position));
noteItemFragment.setNoteItemListener(NotePagerActivity.this);
return noteItemFragment;
}
代码本身十分简单,没什么需要注意的,不过有一点这里需要说明一下,那就是使用ViewPager视图刷新的问题。
在使用过程中很可能会碰到ViewPager中使用FragmentStatePagerAdapter的notifyDataSetChanged后,视图并没有更新的问题,
网上有教程说需要重写下面的方法:
@Override
public int getItemPosition(@NonNull Object object) {
return POSITION_NONE;
}
如果重写方法后还没有作用的话,那么就在重写该方法:
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
super.destroyItem(container, position, object);
}
这里我并有重写destroyItem方法,仅仅重写了getItemPosition方法,然后在发出notifyDataSetChanged后,重新设置ViewPager显示的视图,也达到了刷新视图的效果。
最后还需要修改NoteListFragment下面方法:
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (resultCode == Activity.RESULT_OK) {
switch (requestCode) {
case 1:
initFragmentData();
adapter.notifyDataSetChanged();
if (noteItemList.size() == 0) {
tvEmpty.setVisibility(View.VISIBLE);
}
break;
case 2:
NoteItem newNote = data.getParcelableExtra(NoteCreateActivity.NOTE_CREATE);
noteItemList.add(noteItemList.size(), newNote);
adapter.notifyItemChanged(noteItemList.size());
SharedPreferences sharedPreferences = getActivity().getSharedPreferences("notelist", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("notelist", new Gson().toJson(noteItemList));
editor.apply();
if (tvEmpty.getVisibility() == View.VISIBLE) {
tvEmpty.setVisibility(View.GONE);
}
break;
default:
}
}
}
这里我们接收NotePagerActivity返回结果后,同样需要刷新视图,这里有需要注意的一点就是,如果我们需要重新给noteItemList进行赋值,那么请使用下面的方式:
protected void initFragmentData() {
SharedPreferences sharedPreferences = getActivity().getSharedPreferences("notelist", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
String noteString = sharedPreferences.getString("notelist", "");
if (!noteString.equals("")) {
List<NoteItem> list = new Gson().fromJson(noteString, new TypeToken<List<NoteItem>>() {
}.getType());
noteItemList.clear();
noteItemList.addAll(list);
} else {
noteItemList.clear();
}
}
替代使用noteItemLis=newlist
这种方式,这是因为如果使用这种方式,相当于noteItemList重新有了一个新的地址,会破坏原来数据和RecyclerView中适配器和数据的绑定,同样会导致数据无法刷新的问题。
接下来我们就需要修改下菜单项的显示了。
这是新建日记页面的菜单,大家可以看到这里同样显示了删除菜单,这是因为我们和NoteItemFragment一样使用了同样的菜单。
这里我们并不希望出现删除菜单,最简单的方法就是新建和编辑完全做成两个独立的页面,这样各自互不干涉。当然了,这里我们使用了同一个fragment,就自己控制下菜单是否隐藏吧。
我们在NoteItemFragment中在onPrepareOptionsMenu方法中进行判断即可。
如需根据在 Activity 生命周期中发生的事件修改选项菜单,则可通过onPrepareOptionsMenu() 方法执行此操作。此方法会传递 Menu 对象(因为该对象目前存在),以便对其进行修改,如添加、移除或停用项目。(此外,片段还提供 onPrepareOptionsMenu() 回调。)
@Override
public void onPrepareOptionsMenu(@NonNull Menu menu) {
super.onPrepareOptionsMenu(menu);
if (getActivity() instanceof NoteCreateActivity) {
((NoteCreateActivity) getActivity()).getSupportActionBar().setTitle("新建日记");
MenuItem menuItem = menu.findItem(R.id.menu_note_delete);
menuItem.setVisible(false);
menuItem.setEnabled(false);
} else if (getActivity() instanceof NotePagerActivity) {
((NotePagerActivity) getActivity()).getSupportActionBar().setTitle("编辑日记");
}
}
这里唯一的知识点就是通过findItem获取菜单项。注意不要使用findViewById方法。同时通过getSupportActionBar方法获取actionbar进行标题的设置。
目前我们在NotePagerActivity中要返回NoteListActivity必须要不断地使用后退键才能达到这个目的。这个十分的不方便,所以我们可以为其添加一个层级导航。
这个我们在AndroidManifest.xml中为目标Activity指定父Activity即可。
当然了,我们也可以通过在NotePagerActivity中重写onBackPressed方法来达到相同的目的。