Android基础教程11 应用栏2

上一篇我们实现了日记的保存,本篇我们就日记的删除功能进行实现。

首先我们在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中适配器和数据的绑定,同样会导致数据无法刷新的问题。

接下来我们就需要修改下菜单项的显示了。
Android基础教程11 应用栏2_第1张图片
这是新建日记页面的菜单,大家可以看到这里同样显示了删除菜单,这是因为我们和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进行标题的设置。
Android基础教程11 应用栏2_第2张图片
Android基础教程11 应用栏2_第3张图片

Android基础教程11 应用栏2_第4张图片
目前我们在NotePagerActivity中要返回NoteListActivity必须要不断地使用后退键才能达到这个目的。这个十分的不方便,所以我们可以为其添加一个层级导航。
Android基础教程11 应用栏2_第5张图片
这个我们在AndroidManifest.xml中为目标Activity指定父Activity即可。
Android基础教程11 应用栏2_第6张图片
Android基础教程11 应用栏2_第7张图片
当然了,我们也可以通过在NotePagerActivity中重写onBackPressed方法来达到相同的目的。

你可能感兴趣的:(Android)