Android基础教程8 ViewPager

本篇我们通过ViewPager来实现日记记录的左右滑动查看。

重命名NoteItemActivity类为NotePagerActivity,我们直接在这个基础上进行修改。

要想使用ViewPager首先我们的添加相关的依赖:
在这里插入图片描述
同样,我们这里选择的androidx下的ViewPager。

ViewPager是一种布局管理器,它能够允许用户在数据页面之间左右翻转。 ViewPager通常和Fragment结合使用,能够便捷的对管理每个页面生命周期进行管理。 ViewPager需要和准适配器一起协同工作,常见为FragmentPagerAdapterFragmentStatePagerAdapter。
`
``handlebars
创建ViewPager布局文件


新建布局文件activity_note_pager.xml,添加ViewPager:

```css
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/note_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
activity_note_pager布局与NotePagerActivity关联

修改NotePagerActivity使其继承BaseActivity,在getActivityLayout中返回ViewPager的资源id。


public class NotePagerActivity extends BaseActivity {

    private ViewPager viewPager;

    private List<NoteItem> noteItemList = new ArrayList<>();


    @Override
    protected void initActivityData() {
		for(int i = 0; i < 20; i++){
            NoteItem item = new NoteItem();
            item.setNoteTitle("标题".concat(String.valueOf(i)));
            item.setNoteTitle("日记内容".concat(String.valueOf(i)));
            noteItemList.add(item);
        }
    }

    @Override
    protected void initActivityListener() {

    }

    @Override
    protected void initActivityView() {

        viewPager = findViewById(R.id.note_pager);
    }

    @Override
    protected int getActivityLayout() {
        return R.layout.activity_note_pager;
    }
}

 NotePagerActivity中实现FragmentStatePagerAdapter
 private class NotePagerAdapter extends FragmentStatePagerAdapter {


        public NotePagerAdapter(@NonNull FragmentManager fm, int behavior) {
            super(fm, behavior);
        }

        @NonNull
        @Override
        public Fragment getItem(int position) {
            return NoteItemFragment.newInstance(noteItemList.get(position));
        }

        @Override
        public int getCount() {
            return noteItemList.size();
        }
    }

NotePagerAdapter 的两个方法简单直接。 getCount()方法返回数组列表中包含的列表项数目。getItem(int)方法才是神奇所在,它首先获取数据集中指定位置的NoteItem 实例,然后利用该NoteItem 实例返回一个经过有效配置的NoteItemFragment。

在实现FragmentStatePagerAdapter的时候,我们还需要提供一个构造方法,网上不少资料会使用

public FragmentStatePagerAdapter (FragmentManager fm)

在androdx中这个方法已经不推荐大家使用,替代方法是:

FragmentStatePagerAdapter(FragmentManager, int)

其中参数为BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT,该参数的意思是指定当前的fragment处于Lifecycle.State.RESUMED状态,其他的fragment处于Lifecycle.State STARTED状态。

FragmentStatePagerAdapter是负责管理与ViewPager的对话并协同工作。它首先将getItem(int)方法返回的fragment添加给activity,然后才能使用fragment完成自己的工作。这也就是创建FragmentStatePagerAdapter实例时,需要FragmentManager的原因。

接下我们需要创建NotePagerAdapter的实例:

    @Override
    protected void initActivityView() {

        viewPager = findViewById(R.id.note_pager);

        FragmentManager fragmentManager = getSupportFragmentManager();

        notePagerAdapter = new NotePagerAdapter(fragmentManager,FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);

        viewPager.setAdapter(notePagerAdapter);
    }

当然了,别忘了定义notePagerAdapter 变量:

 private NotePagerAdapter notePagerAdapter;

其中setAdapter方法如下;
在这里插入图片描述

ok,经过这么简单的配置我们的程序就能正确的左右滑动查看了。

运行程序,虽然基础工作做完了,但是这里又出来一个问题,那就是使用返回键返回日记记录页面后,不管点击哪一个列表项,进入NotePagerActivity始终显示的是第一个记录。

写到这里突然觉得BaseActivity好像又有点不太对,边做边改吧。。

这里我们在BaseActivity中新增一个抽象方法initViewOptions(),用来在组件初始化后执行一些和组件有关的数据绑定等等。如果有小伙伴真的再看我写的东西,别见怪。。。

在NotePagerActivity中实现initViewOptions方法,在其中使用setCurrentItem方法设置ViewPaper当前显示的fragment。

androidx.viewpager.widget.ViewPager 

public void setCurrentItem(int item)
@Override
    protected void initViewOptions() {
        NoteItem extraItem = getIntent().getParcelableExtra(NoteItemFragment.EXTRA_NOTE);
        for(int i = 0; i< noteItemList.size();i++){
            if(noteItemList.get(i).getUid().toString().equals(extraItem.getUid().toString())){
                viewPager.setCurrentItem(i);
                break;
            }
        }
    }

这里我们获取Activity的intent中传递的数据,根据NoteItem的uid查找对应的NoteItem索引,然后设置为ViewPaper的显示页面。

看看效果:
在这里插入图片描述
我们选择第六个日记记录,结果发现还是第一页面。那么问题出在哪里呢?

如果真有人是一篇篇看过来的,那么应该很快就能找到问题了,程序中使用的数据都是独立分开的,并没有使用同一份数据。

回忆下前面我们讲过添加Gson,但是却没有使用。这里我们就重新维护下我们的数据,当然了这也是临时的,后面还是要和数据库打交道的。

修改NoteListFragment中initFragmentData方法如下:

    protected void initFragmentData() {

        SharedPreferences.Editor editor = getActivity().getSharedPreferences("notelist", Context.MODE_PRIVATE).edit();
        for (int i = 0; i < 20; i++) {
            NoteItem noteItem = new NoteItem();
            noteItem.setNoteTitle("标题".concat(String.valueOf(i)));
            noteItem.setNoteContent("内容".concat(String.valueOf(i)));
            noteItem.setDateCreate(new Date());
            noteItemList.add(noteItem);
        }
        editor.putString("notelist", new Gson().toJson(noteItemList));
        editor.apply();
    }

这里我们利用Gson将list对象数组转化为字符串,然后保存在SharedPreferences中,其本质上是一个xml文件,让我们看看其存储路径:

/data/data/包名/shared_prefs/文件名.xml
/data/data/com.qiushangge.likenotes/shared_prefs/notelist.xml

当然了,获取SharedPreferences还有两种方式,可能文件的名称会有所差异。

这里需要注意的使用editor完成数据的添加后,必须要调用 editor.apply()进行提交,从而完成数据的存储工作。

同理,我们还需要修改NotePagerActivity中获取日记列表的代码:


    @Override
    protected void initActivityData() {
        SharedPreferences preferences = getSharedPreferences("notelist", MODE_PRIVATE);

        String noteString = preferences.getString("notelist", "");

        noteItemList = new Gson().fromJson(noteString, new TypeToken<List<NoteItem>>() {
        }.getType());
    }

运行程序:
在这里插入图片描述

在这里插入图片描述

ok,到这里就算完成了。

不过呢,还有一个问题这里我们也提出来,那就是用户使用返回键的时候,比如目前页面如下:
在这里插入图片描述
按下返回键:
在这里插入图片描述
页面尽然返回了列表页,显然这和我们的期望有点差异,按道理来讲,我们是希望返回上一篇日记内容的。

此时我们需要重载onBackPressed方法来处理用户返回键:

    /**
     * 重载onBackPressed,处理页面
     */
    @Override
    public void onBackPressed() {
        if (viewPager.getCurrentItem() == 0) {
            //如果当前页面为起始页面,销毁页面,相当于finish调用
            super.onBackPressed();
        } else {
            // 不是起始页面,返回上一个页面
            viewPager.setCurrentItem(viewPager.getCurrentItem() - 1);
        }
    }

此时运行程序,一切就如我们预期的一样工作了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值