我可以使用视图分页器与视图(而不是片段)

我正在使用ViewPager b / w Fragments ,但我可以使用ViewPager轻扫b / w Views简单的xml布局?

这是我的页面Adapter用于在片段之间滑动的ViewPager:

 import java.util.List; import com.app.name.fragments.TipsFragment; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.app.FragmentTransaction; import android.view.ViewGroup; public class PageAdapter extends FragmentPagerAdapter { /** * */ List<Fragment> fragments; public PageAdapter(FragmentManager fm,List<Fragment> frags) { super(fm); fragments = frags; } @Override public Fragment getItem(int arg0) { // TODO Auto-generated method stub return TipsFragment.newInstance(0, 0); } @Override public int getCount() { // TODO Auto-generated method stub return 4; } @Override public void destroyItem(ViewGroup container, int position, Object object) { FragmentManager manager = ((Fragment) object).getFragmentManager(); FragmentTransaction trans = manager.beginTransaction(); trans.remove((Fragment) object); trans.commit(); super.destroyItem(container, position, object); } } 

这是我的小费片段:

 public class TipsFragment extends Fragment { public static TipsFragment newInstance(int image,int content) { TipsFragment fragment = new TipsFragment(); return fragment; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.tip_layout, null); return view; } } 

我怎样才能修改我的代码来使用视图而不是片段?

你需要重写这两个方法,而不是getItem()

 @Override public Object instantiateItem(ViewGroup collection, int position) { View v = layoutInflater.inflate(...); ... collection.addView(v,0); return v; } @Override public void destroyItem(ViewGroup collection, int position, Object view) { collection.removeView((View) view); } 

使用这个例子

您可以使用嵌套子视图的单个XML布局。

  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/page_one" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:text="PAGE ONE IN" android:layout_width="match_parent" android:layout_height="match_parent" android:textColor="#fff" android:textSize="24dp"/> </LinearLayout> <LinearLayout android:id="@+id/page_two" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:text="PAGE TWO IN" android:layout_width="match_parent" android:layout_height="match_parent" android:textColor="#fff" android:textSize="24dp"/> </LinearLayout> </android.support.v4.view.ViewPager> </LinearLayout> 

但是…你需要用适配器来处理这个。 在这里,我们返回finded视图ID而不用膨胀任何其他布局。

 class WizardPagerAdapter extends PagerAdapter { public Object instantiateItem(ViewGroup collection, int position) { int resId = 0; switch (position) { case 0: resId = R.id.page_one; break; case 1: resId = R.id.page_two; break; } return findViewById(resId); } @Override public int getCount() { return 2; } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == ((View) arg1); } } 

//设置ViewPager适配器

 WizardPagerAdapter adapter = new WizardPagerAdapter(); ViewPager pager = (ViewPager) findViewById(R.id.pager); pager.setAdapter(adapter); 

根据以前的答案,我做了下面这个class,以正确,清晰的方式达到这个目的(我希望):

 public class MyViewPagerAdapter extends PagerAdapter { ArrayList<ViewGroup> views; LayoutInflater inflater; public MyViewPagerAdapter(ActionBarActivity ctx){ inflater=LayoutInflater.from(ctx); //instantiate your views list views=new ArrayList<ViewGroup>(5); } /** * To be called by onStop * Clean the memory */ public void release(){ views.clear(); views=null; } /** * Return the number of views available. */ @Override public int getCount() { return 5; } /** * Create the page for the given position. The adapter is responsible * for adding the view to the container given here, although it only * must ensure this is done by the time it returns from * {@link #finishUpdate(ViewGroup)}. * * @param container The containing View in which the page will be shown. * @param position The page position to be instantiated. * @return Returns an Object representing the new page. This does not * need to be a View, but can be some other container of the page.,container */ public Object instantiateItem(ViewGroup container, int position) { ViewGroup currentView; Log.e("MyViewPagerAdapter","instantiateItem for "+position); if(views.size()>position&&views.get(position)!=null){ Log.e("MyViewPagerAdapter","instantiateItem views.get(position) "+views.get(position)); currentView=views.get(position); }else{ Log.e("MyViewPagerAdapter","instantiateItem need to create the View"); int rootLayout=R.layout.view_screen; currentView= (ViewGroup) inflater.inflate(rootLayout,container,false); ((TextView)currentView.findViewById(R.id.txvTitle)).setText("My Views "+position); ((TextView)currentView.findViewById(R.id.btnButton)).setText("Button"); ((ImageView)currentView.findViewById(R.id.imvPicture)).setBackgroundColor(0xFF00FF00); } container.addView(currentView); return currentView; } /** * Remove a page for the given position. The adapter is responsible * for removing the view from its container, although it only must ensure * this is done by the time it returns from {@link #finishUpdate(ViewGroup)}. * * @param container The containing View from which the page will be removed. * @param position The page position to be removed. * @param object The same object that was returned by * {@link #instantiateItem(View, int)}. */ @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View)object); } /** * Determines whether a page View is associated with a specific key object * as returned by {@link #instantiateItem(ViewGroup, int)}. This method is * required for a PagerAdapter to function properly. * * @param view Page View to check for association with <code>object</code> * @param object Object to check for association with <code>view</code> * @return true if <code>view</code> is associated with the key object <code>object</code> */ @Override public boolean isViewFromObject(View view, Object object) { return view==((View)object); } } 

你必须把它放在你的活动中:

 public class ActivityWithViewsPaged extends ActionBarActivity { /** * The page Adapter : Manage the list of views (in fact here, it's fragments) * And send them to the ViewPager */ private MyViewPagerAdapter pagerAdapter; /** * The ViewPager is a ViewGroup that manage the swipe from left to right to left * Like a listView with a gesture listener... */ private ViewPager viewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_with_views); //Find the viewPager viewPager = (ViewPager) super.findViewById(R.id.viewpager); //instanciate the PageAdapter pagerAdapter=new MyViewPagerAdapter(this); // Affectation de l'adapter au ViewPager viewPager.setAdapter(pagerAdapter); viewPager.setClipToPadding(false); viewPager.setPageMargin(12); //Add animation when the page are swiped //this instanciation only works with honeyComb and more //if you want it all version use AnimatorProxy of the nineoldAndroid lib //@see:http://stackoverflow.com/questions/15767729/backwards-compatible-pagetransformer if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB){ viewPager.setPageTransformer(true, new PageTransformer()); } } @Override protected void onStop() { super.onStop(); pagerAdapter.release(); } 

其中的XML文件是显而易见的view_screen.xml:

 <xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/screen" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/txvTitle" android:layout_width="wrap_content" android:layout_gravity="center" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_marginTop="5dp" android:shadowColor="#FF00FF" android:shadowDx="10" android:shadowDy="10" android:shadowRadius="5" android:textSize="32dp" android:textStyle="italic" android:background="#FFFFF000"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#FFFF00F0"> <TextView android:id="@+id/txvLeft" android:layout_width="wrap_content" android:layout_gravity="left" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_marginTop="5dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1"/> <TextView android:id="@+id/txvRight" android:layout_width="wrap_content" android:layout_gravity="right" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_marginTop="5dp"/> </LinearLayout> <Button android:id="@+id/btnButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"/> <ImageView android:id="@+id/imvPicture" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center"/> </LinearLayout> 

ActivtyMain具有以下布局:

 <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingLeft="24dp" android:paddingRight="24dp" android:id="@+id/viewpager" android:background="#FF00F0F0"> </android.support.v4.view.ViewPager> 

非常感谢Brian和Nicholas的回答,希望我能为这个function添加一些最清晰的信息,并且提供一些很好的实践。

我们已经构build了一个我们有时使用的ViewPager的非常简单的子类。

 /** * View pager used for a finite, low number of pages, where there is no need for * optimization. */ public class StaticViewPager extends ViewPager { /** * Initialize the view. * * @param context * The application context. */ public StaticViewPager(final Context context) { super(context); } /** * Initialize the view. * * @param context * The application context. * @param attrs * The requested attributes. */ public StaticViewPager(final Context context, final AttributeSet attrs) { super(context, attrs); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); // Make sure all are loaded at once final int childrenCount = getChildCount(); setOffscreenPageLimit(childrenCount - 1); // Attach the adapter setAdapter(new PagerAdapter() { @Override public Object instantiateItem(final ViewGroup container, final int position) { return container.getChildAt(position); } @Override public boolean isViewFromObject(final View arg0, final Object arg1) { return arg0 == arg1; } @Override public int getCount() { return childrenCount; } @Override public void destroyItem(final View container, final int position, final Object object) {} }); } } 

该类不需要适配器,因为它将从布局加载视图。 为了使用它你的项目,只需使用它,而不是android.support.v4.view.ViewPager

所有的花哨的东西仍然可以工作,但是你不需要被适配器困扰。

我想阐述一下@Nicholas的答案,你可以通过id获得视图,或者如果它们是dynamic添加的,只需直接给定它的位置

 class WizardPagerAdapter extends PagerAdapter { public Object instantiateItem(View collection, int position) { View v = pager.getChildAt(position); return v; } @Override public int getCount() { return 3; } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == ((View) arg1); } } 

我想在这里添加我的解决scheme。 鉴于你不需要使用片段,你仍然可以创build一个PagerAdapter ,它将views而不是fragments附加到ViewPager

扩展PagerAdapter而不是FragmentPagerAdapter

 public class CustomPagerAdapter extends PagerAdapter { private Context context; public CustomPagerAdapter(Context context) { super(); this.context = context; } @Override public Object instantiateItem(ViewGroup collection, int position) { LayoutInflater inflater = LayoutInflater.from(context); View view = null; switch (position){ case 0: view = MemoryView.getView(context, collection); break; case 1: view = NetworkView.getView(context, collection); break; case 2: view = CpuView.getView(context, collection); break; } collection.addView(view); return view; } @Override public int getCount() { return 3; } @Override public boolean isViewFromObject(View view, Object object) { return view==object; } @Override public void destroyItem(ViewGroup collection, int position, Object view) { collection.removeView((View) view); } } 

现在你需要定义三个类,它们将返回viewpager膨胀views 。 与CpuView类似,您将拥有MemoryViewNetworkView类。 他们每个人将膨胀他们各自的布局。

 public class CpuView { public static View getView(Context context, ViewGroup collection) { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context .LAYOUT_INFLATER_SERVICE); return inflater.inflate(R.layout.debugger_cpu_layout, collection, false); } } 

最后在每个视图中都会有一个膨胀的布局

  <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#000000" android:text="CPU"/> </LinearLayout> 

PS:我写这个答案的原因是因为在这里提供的所有解决scheme似乎工作正常,但他们正在膨胀PagerAdapter类本身的布局。 对于大型项目来说,如果他们有很多与膨胀的布局相关的代码,就很难维护。 现在在这个例子中,所有的视图都有独立的类和独立的布局。 所以这个项目很容易维护。