Android 記事本7

上一篇我們實現了日記的保存,本篇我們就日記的刪除功能進行實現。

首先我們在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方法來達到相同的目的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章