上一篇我們實現了日記的保存,本篇我們就日記的刪除功能進行實現。
首先我們在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方法來達到相同的目的。