码迷,mamicode.com
首页 > 其他好文 > 详细

AT-FragmentPagerAdapter

时间:2016-05-06 19:26:34      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:

关于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内部出错。具体原因不知。这便验证了上面的观点。

 

AT-FragmentPagerAdapter

标签:

原文地址:http://www.cnblogs.com/codekk/p/5466382.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!