AT-FragmentPagerAdapter

关于FragmentPagerAdapter的粗略翻译

英文版api地址:FragmentPagerAdapter(自备梯子)

FragmentPagerAdapter

   类概述(Class Overview):

     是PagerAdapter的实现类,展示的每一页是Fragment,并且可以长时间持续保存在fragment manager中,以供用户返回到以前的页面。

这种PagerAdapter(即FragmentPagerAdapter)的最佳用法就是用在:少数的、静态的Fragment上,比如一系列的标签。每一页被用户浏览过的的Fragment都会被保存在内存中,尽管此时视图层次(view hieratchy)因为不可见而已经被销毁了。这便导致会有一些内存被占用,因为这些内存中要被用来保存保存fragment的实例状态之类的呀。所以说,你想要使用ViewPager来展示比较多的页面时,请你考虑使用FragmentStatePagerAdapter

当使用FragmentPagerAdapter时,要注意:和FragmentPagerAdapter搭配使用的ViewPager时,Adapter中必须使用有效的ID集合(我的理解是往Adapter里面传的List<Fragment>中添加的不能是同一个Fragment的引用,尽管每个页面有可能相同,但也请多new几个Fragment然后添加进List中去)

子类实现时,只需要实现getItem(int) 和 getCount() 就可以啦!

这里有一个例子来示范怎样使用FragmentPagerAdapter:

  1 public class FragmentPagerSupport extends FragmentActivity {
  2     static final int NUM_ITEMS = 10;
  3
  4     MyAdapter mAdapter;
  5
  6     ViewPager mPager;
  7
  8     @Override
  9     protected void onCreate(Bundle savedInstanceState) {
 10         super.onCreate(savedInstanceState);
 11         setContentView(R.layout.fragment_pager);
 12
 13         mAdapter = new MyAdapter(getSupportFragmentManager());
 14
 15         mPager = (ViewPager)findViewById(R.id.pager);
 16         mPager.setAdapter(mAdapter);
 17
 18         // Watch for button clicks.
 19         Button button = (Button)findViewById(R.id.goto_first);
 20         button.setOnClickListener(new OnClickListener() {
 21             public void onClick(View v) {
 22                 mPager.setCurrentItem(0);
 23             }
 24         });
 25         button = (Button)findViewById(R.id.goto_last);
 26         button.setOnClickListener(new OnClickListener() {
 27             public void onClick(View v) {
 28                 mPager.setCurrentItem(NUM_ITEMS-1);
 29             }
 30         });
 31     }
 32
 33     public static class MyAdapter extends FragmentPagerAdapter {
 34         public MyAdapter(FragmentManager fm) {
 35             super(fm);
 36         }
 37
 38         @Override
 39         public int getCount() {
 40             return NUM_ITEMS;
 41         }
 42
 43         @Override
 44         public Fragment getItem(int position) {
 45             return ArrayListFragment.newInstance(position);
 46         }
 47     }
 48
 49     public static class ArrayListFragment extends ListFragment {
 50         int mNum;
 51
 52         /**
 53          * Create a new instance of CountingFragment, providing "num"
 54          * as an argument.
 55          */
 56         static ArrayListFragment newInstance(int num) {
 57             ArrayListFragment f = new ArrayListFragment();
 58
 59             // Supply num input as an argument.
 60             Bundle args = new Bundle();
 61             args.putInt("num", num);
 62             f.setArguments(args);
 63
 64             return f;
 65         }
 66
 67         /**
 68          * When creating, retrieve this instance‘s number from its arguments.
 69          */
 70         @Override
 71         public void onCreate(Bundle savedInstanceState) {
 72             super.onCreate(savedInstanceState);
 73             mNum = getArguments() != null ? getArguments().getInt("num") : 1;
 74         }
 75
 76         /**
 77          * The Fragment‘s UI is just a simple text view showing its
 78          * instance number.
 79          */
 80         @Override
 81         public View onCreateView(LayoutInflater inflater, ViewGroup container,
 82                 Bundle savedInstanceState) {
 83             View v = inflater.inflate(R.layout.fragment_pager_list, container, false);
 84             View tv = v.findViewById(R.id.text);
 85             ((TextView)tv).setText("Fragment #" + mNum);
 86             return v;
 87         }
 88
 89         @Override
 90         public void onActivityCreated(Bundle savedInstanceState) {
 91             super.onActivityCreated(savedInstanceState);
 92             setListAdapter(new ArrayAdapter<String>(getActivity(),
 93                     android.R.layout.simple_list_item_1, Cheeses.sCheeseStrings));
 94         }
 95
 96         @Override
 97         public void onListItemClick(ListView l, View v, int position, long id) {
 98             Log.i("FragmentList", "Item clicked: " + id);
 99         }
100     }
101 }

R.layout.fragment_pager的代码:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2         android:orientation="vertical" android:padding="4dip"
 3         android:gravity="center_horizontal"
 4         android:layout_width="match_parent" android:layout_height="match_parent">
 5
 6     <android.support.v4.view.ViewPager
 7             android:id="@+id/pager"
 8             android:layout_width="match_parent"
 9             android:layout_height="0px"
10             android:layout_weight="1">
11     </android.support.v4.view.ViewPager>
12
13     <LinearLayout android:orientation="horizontal"
14             android:gravity="center" android:measureWithLargestChild="true"
15             android:layout_width="match_parent" android:layout_height="wrap_content"
16             android:layout_weight="0">
17         <Button android:id="@+id/goto_first"
18             android:layout_width="wrap_content" android:layout_height="wrap_content"
19             android:text="@string/first">
20         </Button>
21         <Button android:id="@+id/goto_last"
22             android:layout_width="wrap_content" android:layout_height="wrap_content"
23             android:text="@string/last">
24         </Button>
25     </LinearLayout>
26 </LinearLayout>

R.layout.fragment_pager_list的源代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:drawable/gallery_thumb">

    <TextView android:id="@+id/text"
        android:layout_width="match_parent" android:layout_height="wrap_content"
        android:gravity="center_vertical|center_horizontal"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="@string/hello_world"/>

    <!-- The frame layout is here since we will be showing either
    the empty view or the list view.  -->
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1" >
        <!-- Here is the list. Since we are using a ListActivity, we
             have to call it "@android:id/list" so ListActivity will
             find it -->
        <ListView android:id="@android:id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:drawSelectorOnTop="false"/>

        <!-- Here is the view to show if the list is emtpy -->
        <TextView android:id="@android:id/empty"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="No items."/>

    </FrameLayout>

</LinearLayout>

公有构造方法(Public Constructors):

公有方法(Public Methods):

public void destroyItem(ViewGroup container,int position,Object object)

移除对应指定位置(position)的页面。适配器负责从container中移除这些视图,尽管它唯一保证在finishUpdate(ViewGroup)之前执行完!

    public void finishUpdate(ViewGroup container)

当展示页面变化成功时调用该方法。此时应该确保所有的页面在适当的时候已经完成了添加、移除工作。

public abstract Fragment getItem(int position)

     返回已经和特定位置有联系的Fragment

  public long getItemId(int position)

     返回指定位置的页面的标示,该标示是唯一的

     默认的实现是返回指定位置的序号(即position),如果你的需求实现中,子页面的位置可以变化,你可以尝试通过重写该方法来实现

  

     public Object instantiateItem(ViewGroup container,int position)

创建指定页。适配器负责添加视图到父布局中去。该方法只确保它会在finishUpdate(ViewGroup)调用之前完成

     Returns:

Object:返回的这个对象代表了新的一个页面(Page)。它不一定是一个视图View,有可能是一些其他的父布局(Container)。

     public boolean isViewFromObject(View view,Object object)

判断一个页面(Page)是否对应产生了一个唯一的键对象,而产生唯一键对象的过程是通过instantiateItem(ViewGroup,int)方法的调用和完成实现的。本方法保证了                 PagerAdapter能够运行正常。

     public void restoreState(Parcelable state,ClassLoader loader)

恢复和当前适配器相关的任何实例状态,前提是你要在之前就通过saveState()方法保存了实例状态

     public Parcelable saveState()

保存任何和当前适配器有关的数据,以供在之后UI状态发生重建时的实例状态恢复

public void setPrimaryItem(ViewGroup container,int position,Object object)

调用该方法是为了告知适配器哪个子页面目前被视为主要的子页面。它对应的是给用户展示的当前页。

     public void startUpdate(ViewGroup container)

当展示页有变化并且将要开始更新时会调用该方法。

PS:

关于上面的:Adapter中必须使用有效的ID集合。我的理解如下:

当我在给FragmentAdapter(我自己定义的实现了FragmentPagerAdapter的Adapter类)传入List<Fragment>参数时,

当我给List里面同时添加同一个FragmentContent(自己定义的一个继承Fragment的类)多次时,如下图“

跑起来会报错,如下图:

具体报错内容为:java.lang.IllegalStateException: Can‘t change tag of fragment FragmentContent{421fbc80 id=0x7f0c006a android:switcher:2131492970:0}: was android:switcher:2131492970:0 now android:switcher:2131492970:1

不难看出,就是因为在引用了同一个Fragment传入才导致Adapter内部出错。具体原因不知。这便验证了上面的观点。

时间: 2024-08-08 01:56:04

AT-FragmentPagerAdapter的相关文章

FragmentPagerAdapter+ViewPager实现Tab切换效果

1.Activity  加载布局文件,获取Viewpager控件   给ViewPager填充适配器. import android.app.ActionBar; import android.app.ActionBar.Tab; import android.app.Activity; import android.app.Fragment; import android.app.FragmentTransaction; import android.content.Context; impo

Tab系列 03 FragmentPagerAdapter + Fragment + ViewPager

使用ViewPager + Fragment  + FragmentPagerAdapter 实现tab内容切换 创建一个Activity继承FragmentActivity 适配器: FragmentPagerAdapter 与tab系列01 ViewPager + xml 的区别, ViewPager + Fragment 的区别 Adapter 加载数据 package com.example.tabdemo01; import java.util.ArrayList; import ja

FragmentPagerAdapter与FragmentStatePagerAdapter区别

在一个 Android 应用中,我使用 FragmentPagerAdapter 来处理多 Fragment 页面的横向滑动.不过我碰到了一个问题,即当 Fragment 对应的数据集发生改变时,我希望能够通过调用 mAdapter.notifyDataSetChanged() 来触发 Fragment 页面使用新的数据调整或重新生成其内容,可是当我调用 notifyDataSetChanged() 后,发现什么都没发生. 搜索之后发现不止我一个人碰到这个问题,大家给出的解决办法五花八门,有些确

关于FragmentPagerAdapter.notifyDataSetChanged刷新页面无效果,貌似是个bug?求高手指导。。

============问题描述============ 网上查了很多,貌似还找不到解决方案,google"FragmentPagerAdapter notifyDataSetChanged" 发现以前还是个bug 有谁用过FragmentPagerAdapter 然后要刷新页面的,请指导一下 ============解决方案1============ 是没有回应吗,看看这个能帮到你不 http://kwazico.com/2011/10/fragmentpageradapter-do

FragmentPagerAdapter和FragmentStatePagerAdapter区别?

FragmentPagerAdapter:对于不再需要的fragment,选择调用detach方法,仅销毁视图,并不会销毁fragment实例.FragmentStatePagerAdapter:会销毁不再需要的fragment,当当前事务提交以后,会彻底的将fragmeng从当前Activity的FragmentManager中移除,state标明,销毁时,会将其onSaveInstanceState(Bundle outState)中的bundle信息保存下来,当用户切换回来,可以通过该bu

Android FragmentPagerAdapter 更新数据

在使用ViewPager+FragmentPagerAdapter时候,更新Fragment里数据是不起作用,FragmentPagerAdapter添加或减少Fragment时,前面的Fragment内容更新不起作用等等问题,有的做法是暴力删除fragment列表,如 List<Fragment> fragments = getSupportFragmentManager().getFragments(); for (int i = fragments.size() - 1; i >=

使用ViewPager和FragmentPagerAdapter实现Tab

前面我们分别利用ViewPager和Fragment实现了Tab效果.但是使用Fragment实现的Tab不能够左右滑动.如果我们既想使用Fragment又想让Tab能够滑动,那么怎么办呢?这 就是今天的方法,利用ViewPager和FragmentPagerAdapter来实现Tab. 没看过前两篇文章的读者可以点击下面的地址: http://www.cnblogs.com/fuly550871915/p/4850056.html 废话不多说了,效果还是之前的效果.由于有些代码我们已经写过了.

FragmentPagerAdapter与FragmentStatePagerAdapter差异

平常使用的FragmentPagerAdapter和FragmentStatePagerAdapter来自android.support.v4.app包用来构建ViewPager.FragmentPagerAdapter更多的用于少量界面的ViewPager,比如Tab.划过的fragment会保存在内存中,尽管已经划过.而FragmentStatePagerAdapter和ListView有点类似,会保存当前界面,以及下一个界面和上一个界面(如果有),最多保存3个,其他会被销毁掉.要注意的是F

FragmentPagerAdapter.notifyDataSetChanged()不能更新问题?

在一个 Android 应用中,我使用  FragmentPagerAdapter 来处理多 Fragment 页面的横向滑动.不过我碰到了一个问题,即当 Fragment 对应的数据集发生改变时,我希望能够通过调用 mAdapter.notifyDataSetChanged() 来触发 Fragment 页面使用新的数据调整或重新生成其内容,可是当我调用 notifyDataSetChanged() 后,发现什么都没发生. 搜索之后发现不止我一个人碰到这个问题,大家给出的解决办法五花八门,有些

FragmentStatePagerAdapter和FragmentPagerAdapter区别

1.如果ViewPager中加载的是Fragment,则提供的Adpater可以继承于具体的:FragmentStatePagerAdapter或FragmentPagerAdapter 2.FragmentStatePagerAdapter:适用于ViewPager中加载的Fragment过多,会根据最近最少使用算法,实现内存中Fragment的清理,避免溢出 3.FragmentPagerAdapter:适用于ViewPager中加载的Fragment不多时,系统不会清理已经加载的Fragm