Android 使用 ViewPager 实现左右滑动 Fragment
本章另一个要点:Fragment 之间通讯使用 setArguments TestFragment newFragment = new TestFragment(); Bundle bundle = new Bundle(); bundle.putString("hello", s); newFragment.setArguments(bundle); 使用 getArguments()进行获取 Bundle args = getArguments(); String tHello=args.getString("hello"); ViewPager 结合 Fragment 实现一个 Activity 里包含多个可滑动的标签页,每个标签页可以有独立的布局及响应。 activity_main.xml <!-- ViewPager + Fragment 滑动布局 --> <LinearLayout 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" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/tvGuid1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1.0" android:gravity="center" android:text="特性1" android:textSize="18sp" /> <TextView android:id="@+id/tvGuid2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1.0" android:gravity="center" android:text="特性2" android:textSize="18sp" /> <TextView android:id="@+id/tvGuid3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1.0" android:gravity="center" android:text="特性3 " android:textSize="18sp" /> <TextView android:id="@+id/tvGuid4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1.0" android:gravity="center" android:text="特性4" android:textSize="18sp" /> </LinearLayout> <ImageView android:id="@+id/ivCursor" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="matrix" android:src="@drawable/cursor" /> <android.support.v4.view.ViewPager android:id="@+id/vpSlideFragment" android:layout_width="fill_parent" android:layout_height="fill_parent" android:flipInterval="30" android:persistentDrawingCache="animation" /> </LinearLayout> /** * @ClassName: SlideFragmentActivity * @author Xiao JinLai * @Date 2015-4-5 下午5:55:09 * @Description:主 Activity */ public class SlideFragmentActivity extends FragmentActivity { private ViewPager mPager; private ArrayList<Fragment> mFragments; private ImageView mIvCursor; private TextView view1, view2, view3, view4; private int currIndex;// 当前页卡编号 private int bmpW;// 横线图片宽度 private int offset;// 图片移动的偏移量 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_slide_fragment); initTextView(); initImage(); initViewPager(); } /** * 初始化标签名 */ public void initTextView() { view1 = (TextView) findViewById(R.id.tvGuid1); view2 = (TextView) findViewById(R.id.tvGuid2); view3 = (TextView) findViewById(R.id.tvGuid3); view4 = (TextView) findViewById(R.id.tvGuid4); view1.setOnClickListener(new txListener(0)); view2.setOnClickListener(new txListener(1)); view3.setOnClickListener(new txListener(2)); view4.setOnClickListener(new txListener(3)); } public class txListener implements View.OnClickListener { private int index = 0; public txListener(int i) { index = i; } @Override public void onClick(View v) { // TODO Auto-generated method stub mPager.setCurrentItem(index); } } /** * 初始化图片的位移像素 */ public void initImage() { mIvCursor = (ImageView) findViewById(R.id.ivCursor); bmpW = BitmapFactory.decodeResource(getResources(), R.drawable.cursor) .getWidth(); DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); int screenW = dm.widthPixels; offset = (screenW / 4 - bmpW) / 2; // imgageview设置平移,使下划线平移到初始位置(平移一个offset) Matrix matrix = new Matrix(); matrix.postTranslate(offset, 0); mIvCursor.setImageMatrix(matrix); } /** * 初始化ViewPager */ public void initViewPager() { mPager = (ViewPager) findViewById(R.id.vpSlideFragment); mFragments = new ArrayList<Fragment>(); Fragment btFragment = new ButtonFragment(); Fragment secondFragment = TestFragment .newInstance("this is second fragment"); Fragment thirdFragment = TestFragment .newInstance("this is third fragment"); Fragment fourthFragment = TestFragment .newInstance("this is fourth fragment"); mFragments.add(btFragment); mFragments.add(secondFragment); mFragments.add(thirdFragment); mFragments.add(fourthFragment); // 给ViewPager设置适配器 mPager.setAdapter(new SlideFragmentAdapter(getSupportFragmentManager(), mFragments)); mPager.setCurrentItem(0);// 设置当前显示标签页为第一页 mPager.setOnPageChangeListener(new MyOnPageChangeListener());// 页面变化时的监听器 } public class MyOnPageChangeListener implements OnPageChangeListener { private int one = offset * 2 + bmpW;// 两个相邻页面的偏移量 @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { } @Override public void onPageSelected(int arg0) { Animation animation = new TranslateAnimation(currIndex * one, arg0 * one, 0, 0);// 平移动画 currIndex = arg0; animation.setFillAfter(true);// 动画终止时停留在最后一帧,不然会回到没有执行前的状态 animation.setDuration(200);// 动画持续时间0.2秒 mIvCursor.startAnimation(animation);// 是用ImageView来显示动画的 int i = currIndex + 1; Toast.makeText(SlideFragmentActivity.this, "您选择了第" + i + "个页卡", Toast.LENGTH_SHORT).show(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.fragment_menu, menu); return true; } } 谷歌官方认为,ViewPager 应该和 Fragment 一起使用时,此时 ViewPager 的适配器是 FragmentPagerAdapter,当你实现一个 FragmentPagerAdapter,你必须至少覆盖以下方法: getCount() getItem() 如果 ViewPager 没有和 Fragment 一起,ViewPager 的适配器是 PagerAdapter,它是基类提供适配器来填充页面ViewPager 内部,当你实现一个 PagerAdapter,你必须至少覆盖以下方法: instantiateItem(ViewGroup, int) destroyItem(ViewGroup, int, Object) getCount() isViewFromObject(View, Object) /** * @ClassName: SlideFragmentAdapter * @author Xiao JinLai * @Date 2015-4-5 下午6:15:37 * @Description:ViewPager与Fragment适配器 */ public class SlideFragmentAdapter extends FragmentPagerAdapter { ArrayList<Fragment> mList; public SlideFragmentAdapter(FragmentManager fm, ArrayList<Fragment> list) { super(fm); this.mList = list; } /** * 返回一个 Fragment */ @Override public Fragment getItem(int item) { return mList.get(item); } /** * Fragment 总数 */ @Override public int getCount() { return mList.size(); } } /** * @ClassName: ButtonFragment * @author Xiao JinLai * @Date 2015-4-5 下午6:17:15 * @Description:有按钮的Fragment */ public class ButtonFragment extends Fragment { private Button mBtnGuide; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_guide1, container, false);// 关联布局文件 mBtnGuide = (Button) rootView.findViewById(R.id.btnGuide);// 根据rootView找到button // 设置按键监听事件 mBtnGuide.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Toast.makeText(ButtonFragment.this.getActivity(), "button is click!", Toast.LENGTH_SHORT).show(); } }); return rootView; } } <!-- 带按钮的 Fragment 布局 --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ff0000ff" > <Button android:id="@+id/btnGuide" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="hit me" /> </RelativeLayout> /** * @ClassName: TestFragment * @author Xiao JinLai * @Date 2015-4-5 下午6:18:40 * @Description:创建多个 Fragment 用来测试 */ public class TestFragment extends Fragment { private static final String TAG = "TestFragment"; private String hello;// = "hello android"; private String defaultHello = "default value"; static TestFragment newInstance(String s) { TestFragment newFragment = new TestFragment(); Bundle bundle = new Bundle(); bundle.putString("hello", s); newFragment.setArguments(bundle); // bundle还可以在每个标签里传送数据 return newFragment; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.d(TAG, "TestFragment-----onCreateView"); Bundle args = getArguments(); hello = args != null ? args.getString("hello") : defaultHello; View view = inflater .inflate(R.layout.fragment_guide2, container, false); TextView viewhello = (TextView) view.findViewById(R.id.tvGuide2); viewhello.setText(hello); return view; } } <!-- 测试用的多个 Fragment 的界面 --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#158684" android:orientation="vertical" > <TextView android:id="@+id/tvGuide2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" /> </RelativeLayout>