如何实现一个ViewPager与不同的碎片/布局

当我开始一个实现viewpager的活动时,viewpager创build了各种片段。 我想为每个片段使用不同的布局,但问题是,viewpager只显示最大的两个布局(1之后的所有剩余片段的第二个布局)。

以下是实现viewpager的SwipeActivity的代码:

public class SwipeActivity extends FragmentActivity { MyPageAdapter pageAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_swipe); pageAdapter = new MyPageAdapter(getSupportFragmentManager()); ViewPager pager=(ViewPager)findViewById(R.id.pager); pager.setAdapter(pageAdapter); ActionBar bar = getActionBar(); bar.setDisplayHomeAsUpEnabled(true); } /** * Custom Page adapter */ private class MyPageAdapter extends FragmentPagerAdapter { public MyPageAdapter(FragmentManager fm) { super(fm); } @Override public int getCount() { return 5; } @Override public Fragment getItem(int position) { switch(position) { case 0: return new MyFragment(); case 1: return SecondFragment.newInstance("asdasd"); default : return RamFragment.newInstance("s"); } } } } 

这是碎片的代码

 public class MyFragment extends Fragment { @Override public View onCreateView(LayoutInflater paramLayoutInflater, ViewGroup paramViewGroup, Bundle paramBundle) { return paramLayoutInflater.inflate(R.layout.processorlayout, paramViewGroup, false); } } 

我用这样的5个片段,都有不同的布局,但viewpager只显示最多2个。

编辑 :SecondFragment的代码

 public class SecondFragment extends Fragment { public static final String EXTRA_MESSAGE = "EXTRA_MESSAGE"; public static final SecondFragment newInstance(String paramString) { SecondFragment f = new SecondFragment(); Bundle localBundle = new Bundle(1); localBundle.putString("EXTRA_MESSAGE", paramString); f.setArguments(localBundle); return f; } @Override public View onCreateView(LayoutInflater paramLayoutInflater, ViewGroup paramViewGroup, Bundle paramBundle) { return paramLayoutInflater.inflate(R.layout.motherboardlayout, paramViewGroup, false); } } 

由于这是一个非常常见的问题,我想花时间和精力详细解释ViewPager的多个碎片和布局。 干得好。

具有多个碎片和布局文件的ViewPager – 如何

以下是如何实现具有不同片段types和不同布局文件的ViewPager的完整示例。

在这种情况下,我有3个片段类,每个类有不同的布局文件。 为了简单起见, 片段布局只在背景颜色上有所不同 。 当然,任何布局文件都可以用于碎片。

FirstFragment.java具有橙色背景布局,SecondFragment.java具有绿色背景布局,ThirdFragment.java具有红色背景布局。 此外,每个片段显示不同的文本,这取决于它来自哪个类别以及哪个类别。

另外请注意,我正在使用support-library的Fragment: android.support.v4.app.Fragment

MainActivity.java (初始化Viewpager并将其作为内部类的适配器)。 再看看import 。 我正在使用android.support.v4包。

 import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; public class MainActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ViewPager pager = (ViewPager) findViewById(R.id.viewPager); pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager())); } private class MyPagerAdapter extends FragmentPagerAdapter { public MyPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int pos) { switch(pos) { case 0: return FirstFragment.newInstance("FirstFragment, Instance 1"); case 1: return SecondFragment.newInstance("SecondFragment, Instance 1"); case 2: return ThirdFragment.newInstance("ThirdFragment, Instance 1"); case 3: return ThirdFragment.newInstance("ThirdFragment, Instance 2"); case 4: return ThirdFragment.newInstance("ThirdFragment, Instance 3"); default: return ThirdFragment.newInstance("ThirdFragment, Default"); } } @Override public int getCount() { return 5; } } } 

activity_main.xml (MainActivitys .xml文件) – 一个简单的布局文件,只包含填充整个屏幕的ViewPager。

 <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/viewPager" android:layout_width="fill_parent" android:layout_height="fill_parent" /> 

片段类, FirstFragment.java import android.support.v4.app.Fragment;

 public class FirstFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.first_frag, container, false); TextView tv = (TextView) v.findViewById(R.id.tvFragFirst); tv.setText(getArguments().getString("msg")); return v; } public static FirstFragment newInstance(String text) { FirstFragment f = new FirstFragment(); Bundle b = new Bundle(); b.putString("msg", text); f.setArguments(b); return f; } } 

first_frag.xml

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/holo_orange_dark" > <TextView android:id="@+id/tvFragFirst" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:textSize="26dp" android:text="TextView" /> </RelativeLayout> 

SecondFragment.java

 public class SecondFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.second_frag, container, false); TextView tv = (TextView) v.findViewById(R.id.tvFragSecond); tv.setText(getArguments().getString("msg")); return v; } public static SecondFragment newInstance(String text) { SecondFragment f = new SecondFragment(); Bundle b = new Bundle(); b.putString("msg", text); f.setArguments(b); return f; } } 

second_frag.xml

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/holo_green_dark" > <TextView android:id="@+id/tvFragSecond" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:textSize="26dp" android:text="TextView" /> </RelativeLayout> 

ThirdFragment.java

 public class ThirdFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.third_frag, container, false); TextView tv = (TextView) v.findViewById(R.id.tvFragThird); tv.setText(getArguments().getString("msg")); return v; } public static ThirdFragment newInstance(String text) { ThirdFragment f = new ThirdFragment(); Bundle b = new Bundle(); b.putString("msg", text); f.setArguments(b); return f; } } 

third_frag.xml

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/holo_red_light" > <TextView android:id="@+id/tvFragThird" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:textSize="26dp" android:text="TextView" /> </RelativeLayout> 

最终结果如下:

Viewpager包含5个碎片,碎片1的types为FirstFragment,并显示first_frag.xml布局,碎片2的types为SecondFragment,显示的是second_frag.xml,碎片3-5的types为ThirdFragment,全部显示third_frag.xml 。

在这里输入图像描述

在上面你可以看到5个片段之间可以通过向左或向右滑动来切换。 当然,只能同时显示一个片段。

最后但并非最不重要的:

我build议你在每个Fragment类中使用一个空构造函数

而不是通过构造函数newInstance(...)潜在的参数,使用newInstance(...)方法和Bundle来移交参数。

这种方式如果分离和重新连接的对象状态可以通过参数存储。 就像Bundles Intents

创build一个视图数组,并将其应用于: container.addView(viewarr[position]);

 public class Layoutes extends PagerAdapter { private Context context; private LayoutInflater layoutInflater; Layoutes(Context context){ this.context=context; } int layoutes[]={R.layout.one,R.layout.two,R.layout.three}; @Override public int getCount() { return layoutes.length; } @Override public boolean isViewFromObject(View view, Object object) { return (view==(LinearLayout)object); } @Override public Object instantiateItem(ViewGroup container, int position){ layoutInflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View one=layoutInflater.inflate(R.layout.one,container,false); View two=layoutInflater.inflate(R.layout.two,container,false); View three=layoutInflater.inflate(R.layout.three,container,false); View viewarr[]={one,two,three}; container.addView(viewarr[position]); return viewarr[position]; } @Override public void destroyItem(ViewGroup container, int position, Object object){ container.removeView((LinearLayout) object); } } 

代码添加片段

 public Fragment getItem(int position) { switch (position){ case 0: return new Fragment1(); case 1: return new Fragment2(); case 2: return new Fragment3(); case 3: return new Fragment4(); default: break; } return null; } 

为每个片段创build一个xml文件,对于Fragment1,使用fragment_one.xml作为布局文件,在Fragment1 java文件中使用下面的代码。

 public class Fragment1 extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_one, container, false); return view; } } 

以后你可以做出必要的更正。它对我有效。

这也很好:

 <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/viewPager" android:layout_width="fill_parent" android:layout_height="fill_parent" /> 
 public class MainActivity extends FragmentActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); ViewPager pager = (ViewPager) findViewById(R.id.viewPager); pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager())); } } public class FragmentTab1 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragmenttab1, container, false); return rootView; } } class MyPagerAdapter extends FragmentPagerAdapter{ public MyPagerAdapter(FragmentManager fragmentManager){ super(fragmentManager); } @Override public android.support.v4.app.Fragment getItem(int position) { switch(position){ case 0: FragmentTab1 fm = new FragmentTab1(); return fm; case 1: return new FragmentTab2(); case 2: return new FragmentTab3(); } return null; } @Override public int getCount() { return 3; } } 
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="@string/Fragment1" /> </RelativeLayout> 

在您的片段中创build新的实例,并在您的活动中这样做

  private class SlidePagerAdapter extends FragmentStatePagerAdapter { public SlidePagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { switch(position){ case 0: return Fragment1.newInstance(); case 1: return Fragment2.newInstance(); case 2: return Fragment3.newInstance(); case 3: return Fragment4.newInstance(); default: break; } return null; } 

基本的ViewPager示例

这个答案是简化文档 , 本教程和接受的答案 。 目的是ViewPager启动并运行ViewPager 。 之后可以进一步编辑。

在这里输入图像描述

XML

为主要活动和每个页面(片段)添加xml布局。 在我们的情况下,我们只使用一个片段布局,但是如果在不同的页面上有不同的布局,那么就为每个布局做一个布局。

activity_main.xml中

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.verticalviewpager.MainActivity"> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout> 

fragment_one.xml

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/textview" android:textSize="30sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" /> </RelativeLayout> 

这是主要活动的代码。 它包含了PagerAdapterFragmentOne作为内部类。 如果这些变得太大或者你在其他地方重复使用,那么你可以把它们移到他们自己的课堂上。

 import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; public class MainActivity extends AppCompatActivity { static final int NUMBER_OF_PAGES = 2; MyAdapter mAdapter; ViewPager mPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mAdapter = new MyAdapter(getSupportFragmentManager()); mPager = findViewById(R.id.viewpager); mPager.setAdapter(mAdapter); } public static class MyAdapter extends FragmentPagerAdapter { public MyAdapter(FragmentManager fm) { super(fm); } @Override public int getCount() { return NUMBER_OF_PAGES; } @Override public Fragment getItem(int position) { switch (position) { case 0: return FragmentOne.newInstance(0, Color.WHITE); case 1: // return a different Fragment class here // if you want want a completely different layout return FragmentOne.newInstance(1, Color.CYAN); default: return null; } } } public static class FragmentOne extends Fragment { private static final String MY_NUM_KEY = "num"; private static final String MY_COLOR_KEY = "color"; private int mNum; private int mColor; // You can modify the parameters to pass in whatever you want static FragmentOne newInstance(int num, int color) { FragmentOne f = new FragmentOne(); Bundle args = new Bundle(); args.putInt(MY_NUM_KEY, num); args.putInt(MY_COLOR_KEY, color); f.setArguments(args); return f; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mNum = getArguments() != null ? getArguments().getInt(MY_NUM_KEY) : 0; mColor = getArguments() != null ? getArguments().getInt(MY_COLOR_KEY) : Color.BLACK; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_one, container, false); v.setBackgroundColor(mColor); TextView textView = v.findViewById(R.id.textview); textView.setText("Page " + mNum); return v; } } } 

成品

如果您将上述三个文件复制并粘贴到您的项目中,则应该可以运行该应用程序并在上面的animation中查看结果。

继续

ViewPagers可以做很多事情。 请参阅以下链接以开始使用:

  • 使用选项卡创build滑动视图
  • ViewPager与FragmentPagerAdapter (CodePath教程总是很好)