ViewPager 的简单使用(二)
来源:互联网 发布:纽约 伦敦 知乎 编辑:程序博客网 时间:2024/05/17 23:58
ViewPager 的简单使用(一)中简单的使用了 ViewPager ,但是 ViewPager 常常和 Fragment 以前使用,这时需要的适配器为 FragmentPagerAdapter 或者 FragmentStatePagerAdapter。
下面只是一个简单的示例,效果如下(AndroidStudio1.5):
ListPagerAdapter.java :
package com.crazy.viewpagertest;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentPagerAdapter;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.ListView;import java.util.ArrayList;import java.util.List;public class ListPagerAdapter extends FragmentPagerAdapter { // 每个页面显示多少条目 private static final int ITEMS_PER_PAGE = 2; private List<String> mItems; public ListPagerAdapter(FragmentManager fm, List<String> items) { super(fm); mItems = items; } /** * 这个位置首次需要一个 Fragment 时,该方法才会被调用 */ @Override public Fragment getItem(int position) { int start = position * ITEMS_PER_PAGE; return ArrayListFragment.newInstance(getPageList(position), start); } @Override public int getCount() { // 得到的分页总数 int pages = mItems.size() / ITEMS_PER_PAGE; // 如果列表的大小不能整除页面的大小,就多添加一个页面来显示剩余的值 int excess = mItems.size() % ITEMS_PER_PAGE; if (excess > 0) { pages++ ; } return pages; } /** * 这个方法会在 getItem() 之后针对新的 Fragment 被调用,而且在超出页数限制部分的 * Fragment 再加回来时,也会调用该方法;要确保这些元素会被更新到列表中 */ @Override public Object instantiateItem(ViewGroup container, int position) { ArrayListFragment fragment = (ArrayListFragment)super.instantiateItem(container, position); fragment.updateListItems(getPageList(position)); return fragment; } /** * 当 notifyDataSetChanged() 被调用时,该方法也会被框架调用。必须决定如何为新的 * 数据集更改每个 Fragment 。如果某个位置的 Fragment 不在需要,会返回 POSITION_NONE, * 这样适配器就可以将其删除 */ @Override public int getItemPosition(Object object) { ArrayListFragment fragment = (ArrayListFragment)object; int position = fragment.getBaseIndex() / ITEMS_PER_PAGE; if (position >= getCount()) { // 不在需要这个页面 return POSITION_NONE; } else { // 刷新 Fragment 数据显示 fragment.updateListItems(getPageList(position)); return position; } } /** * 辅助方法,用于获取整个列表的某一部分,然后显示在给定的 Fragment 上。 */ private List<String> getPageList(int position) { int start = position * ITEMS_PER_PAGE; int end = Math.min(start + ITEMS_PER_PAGE, mItems.size()); List<String> itemPage = mItems.subList(start, end); return itemPage; } /** * 内部自定义 Fragment,它会通过 ListView 中显示列表的一个片段, * 并提供外部方法来更新列表 */ public static class ArrayListFragment extends Fragment { private ArrayList<String> mItems; private ArrayAdapter<String> mAdapter; private int mBaseIndex; // 使用工厂模式创建 Fragment static ArrayListFragment newInstance(List<String> page, int baseIndex) { ArrayListFragment fragment = new ArrayListFragment(); fragment.updateListItems(page); fragment.setBaseIndex(baseIndex); return fragment; } public ArrayListFragment(){ super(); mItems = new ArrayList<String>(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 为列表条目创建一个新的适配器 mAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, mItems); } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // 构造并返回一个 ListView,为它关联适配器 ListView listView = new ListView(getActivity()); listView.setAdapter(mAdapter); return listView; } /** * 在全局列表中保存一个索引,记录页面开始的地方 */ public void setBaseIndex(int index) { mBaseIndex = index; } /** * 在全局列表中检索索引,可以找到页面开始的地方 */ public int getBaseIndex(){ return mBaseIndex; } public void updateListItems(List<String> items) { mItems.clear(); for (String piece : items) { mItems.add(piece); } if (mAdapter != null) { mAdapter.notifyDataSetChanged(); } } }}
FragmentPagerAdapter 帮我们实现了 PagerAdapter 底层的很多功能。不必再实现 instantiateItem() ,destroyItem() 和 isViewFromObject() 方法,只需要重写 getItem() 来为每个页面位置提供相应的 Fragment 。这个例子让每个页面的条目显示数量为 2。在 getItem() 内创建 Fragment 时,会传入列表中的一部分数据,而这些数据是根据索引偏移和之前定义的常量来计算的。分页的数量由 getItem() 方法返回。
虽然 ViewPager 不会跟踪滚动出限定值之外的 Fragment ,但 FragmentManager 会继续跟踪。因此,当之前的 Fragment 回滚时,getItem() 不会被再次调用,因为 Fragment 已经存在了。但是正因为如此,如果一个数据集在这期间发生改变 Fragment 列表数据不会跟着更新。这就是重写 instantiateItem() 的原因。
MainActivity.java :
package com.crazy.viewpagertest;import android.os.Bundle;import android.support.v4.view.ViewPager;import android.support.v7.app.AppCompatActivity;import android.view.View;import java.util.ArrayList;import java.util.Date;public class MainActivity extends AppCompatActivity { private ArrayList<String> mListItems; private ListPagerAdapter mAdapter; private int count = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 创建初始数据集 mListItems = new ArrayList<>(); mListItems.add("北京"); mListItems.add("上海"); mListItems.add("广州"); mListItems.add("深圳"); mListItems.add("武汉"); mListItems.add("兰州"); mListItems.add("成都"); // 把数据关联到 ViewPager 上 ViewPager pager = (ViewPager)findViewById(R.id.ViewPager); mAdapter = new ListPagerAdapter(getSupportFragmentManager(), mListItems); pager.setAdapter(mAdapter); } public void onAddClick(View v) { // 在列表的末尾添加新的条目 mListItems.add("Crazy boy: " + countData() +"," + new Date()); mAdapter.notifyDataSetChanged(); } // 该方法是纯粹为了显示时方便观察效果,无其他意义 private int countData(){ return count++; } public void onRemoveClick(View v) { // 从列表中删除一个条目 if (!mListItems.isEmpty()) { mListItems.remove(0); } mAdapter.notifyDataSetChanged(); }}
content_main.xml :
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="com.crazy.viewpagertest.MainActivity" tools:showIn="@layout/activity_main"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="添加 item" android:onClick="onAddClick" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="删除 item" android:onClick="onRemoveClick" /> <android.support.v4.view.ViewPager android:id="@+id/ViewPager" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v4.view.ViewPager></LinearLayout>
ViewPager 中还有几个其他的方法:
1. setPageMargin() 和 setPageMarginDrawable() 允许在页面之间设置一些额外的间隔,并且使用一个 Drawable (可选)来填充间隔的内容。
2. setCurrentItem() 允许以编程的方式设置要显示的页面,并提供一个选项来禁用页面的切换时的滚动画面。
3. OnPageChangeListener 用于将滚动和变更动作通知给应用程序。
----> onPageSelected() 会在显示一个新页面时被调用。
----> 当发生滚动操作时会连续调用 onPageSelected() 。
----> onPageScrollStateChanged() 在 ViewPager 处于以下状态时会被调用:闲置时,用户主动滚动 ViewPager时,自动滚动对齐到最近的页面时。
- ViewPager 的简单使用(二)
- ViewPager组合其他View的简单使用(二)
- ViewPager(1):简单的使用ViewPager
- ViewPager的使用<二>
- ViewPager的简单使用
- viewpager的简单使用
- viewpager的简单使用
- ViewPager的简单使用
- ViewPager的简单使用
- viewpager的简单使用
- viewPager的简单使用
- ViewPager的简单使用
- ViewPager的简单使用
- Viewpager的简单使用
- ViewPager的简单使用
- 简单的ViewPager使用
- ViewPager的简单使用
- ViewPager的简单使用
- 第十六周--项目5算法验证基数排序
- 第十五周 用哈希法组织关键字2
- 第十六章-基数排序
- 第十三周项目1 prim算法
- 第6周项目4——数制转换
- ViewPager 的简单使用(二)
- 验证算法(5)直接选择排序
- 第十四周项目2-分块查找算法
- Java之美[从菜鸟到高手演变]之Exception
- 第十六周项目1 直接插入排序
- 学期末总结——我体会的翻转课堂
- 第16周项目插入排序之排序中输出每一趟的中间结果
- 第十周 项目三 利用二叉树遍历思想解决问题(5)
- 第十二周项目三----广度优先遍历