一.ViewPager简介
ViewPger就是将多个View引用到Adapter中,在左右滑动时,切换不同的View视图
我们日常app中经常用到的滑动换页,大部分就是用它做的
ViewPager 直接继承了 ViewGroup,所以它是一个容器类,可以在其中添加其他的 view 类。
ViewPager 需要一个 PagerAdapter 适配器类给它提供数据。
ViewPager 经常和 Fragment 一起使用,并且提供了专门的 FragmentPagerAdapter 和 FragmentStatePagerAdapter 类供 Fragment 中的 ViewPager 使用。
二.ViewPager使用
1.在布局文件中引用
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v4.view.ViewPager
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</LinearLayout>
2.创建要加载的ViewPager布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/text_show"
android:text="12456"
android:textSize="30sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
3.创建适配器,自定义布局设置数据等
public class MyAdapater extends PagerAdapter {
private Context context;
private List<String> datas;
private LayoutInflater layoutInflater;
public MyAdapater(Context context, List<String> datas) {
this.context = context;
this.datas = datas;
this.layoutInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return datas.size();
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
return view == o;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
// super.destroyItem(container, position, object);必须删除,否则报错
container.removeView((View) object);
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
View view = layoutInflater.inflate(R.layout.vp_layout, null);
TextView text = view.findViewById(R.id.text_show);
text.setText(datas.get(position));
container.addView(view);//添加布局(***)
return view;
}
}
destroyItem()方法中的super()一定要删除,否则报错
instantiateItem()方法中,一定要将解析的View加入到视图组container中>
4.在Activity中添加数据,以及要完成的各种操作
public class MainActivity extends AppCompatActivity {
private ViewPager vp;
private MyAdapater myAdapater;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews() {
vp = (ViewPager) findViewById(R.id.vp);
List<String> datas = new ArrayList<>();
for (int i = 0; i < 4; i++) {
datas.add("第" + (i+1) + "个View");
}
myAdapater = new MyAdapater(MainActivity.this, datas);
vp.setAdapter(myAdapater);
}
}
效果展示
三.翻页监听
其中有三个方法
onPageSelected,onPageSelected,onPageScrollStateChanged
- onPageScrolled:在屏幕滑动过程中被调用。
- onPageSelected:代表哪个页面被选中。
- onPageScrollStateChanged:在手指操作屏幕时被调用。
第三个方法的参数
state:当前页面的状态
SCROLL_TATE_IDLE:空闲状态
SCROLL_STATE_DRAGGING:滑动状态
SCROLL_STATE_SETTLING:滑动后滑翔的状态
setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int i) {
}
@Override
public void onPageScrollStateChanged(int i) {
}
})
四.ViewPager与Fragment的结合使用
1.与Fragment结合使用就相当于用Fragment去替代之前的View
2.Fragment的Adapter有两种:
FragmentPagerAdapter和FragmentStatePagerAdapter。
两种适配器都是继承了PagerAdapter
适配器与Fragment的生命周期:
1.FragmentStatePagerAdapter
fragment的生命周期会执行
onDestoryView
onDestory
onCreate
onCreateView
fragment会被销毁
适用 图片预览等多个fragment的情况
2.FragmentPagerAdapter
onDestoryView
onCreateView
fragment不会被销毁
适用于引导页等少个fragment的情况
四.案例
一个小案例:需要实现
三个Fragment,其中1和2随意,第3个Fragment需要实现倒计时5秒功能,倒计时后跳转到另一个Activity或一个按钮在按下时直接跳转到另一个Activity
首先创建三个Fragment及其布局文件,由于1和2里仅有一个图片做展示,所以只展示第三个Fragment的代码及布局文件
public class ThreeFragment extends Fragment {
public ThreeFragment() {
// Required empty public constructor
}
private static TextView teTime;
private Button butGo;
private static Timer timer;
private static int index = 5;
private static Context context;
public static Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 1) {
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
handler.sendEmptyMessage(2);
}
}, 0, 1000);
} else if (msg.what == 2) {
teTime.setText("" + --index);
if (index == 0) {
context.startActivity(new Intent(context, MainActivity.class));
}
}
}
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_three, container, false);
initViews(view);
context = getActivity();//赋值上下文对象
return view;
}
private void initViews(View view) {
teTime = (TextView) view.findViewById(R.id.te_time);
butGo = (Button) view.findViewById(R.id.but_go);
// new Thread() {
// int index = 5;
//
// @Override
// public void run() {
// for (int i = 0; i < 5; i++) {//设置5秒
// handler.post(new Runnable() {
// @Override
// public void run() {
// teTime.setText("" + index);
// }
// });
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// index--;
// if (index <= 0) {
// startActivity(new Intent(getActivity(), MainActivity.class));
// }
// }
// }
// }.start();
butGo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(getActivity(), MainActivity.class));
timer.cancel();//取消定时器任务
}
});
}
}
在其中定义的handler,是用来判断页面是否滑动到第三个Fragment,及之后的倒计时操作
不可直接做子线程进行倒计时操作,因为在滑动到与其相邻的页面时,当前页面也会随之创建,这会导致页面没有滑动到第三个Fragment时,倒计时就已经开始
由于Fragment不能直接调用startActivity()方法,所以在一开始就定义了成员变量的上下文对象并进行赋值
在按按钮的时候,需要将倒计时任务取消,否则会发生第二次跳转
布局文件
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".test.ThreeFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView
android:layout_marginLeft="220dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="倒计时:"
android:textSize="20sp" />
<TextView
android:id="@+id/te_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="XXX"
android:textSize="20sp" />
<Button
android:id="@+id/but_go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="跳过" />
</LinearLayout>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/a" />
</LinearLayout>
Activity中的代码及布局文件
public class WelActivity extends AppCompatActivity {
private ViewPager vp;
private List<Fragment> datas = new ArrayList<>();
private Mydapter myAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wel);
initDatas();
initViews();
}
private void initDatas() {
datas.add(new OneFragment());
datas.add(new TwoFragment());
datas.add(new ThreeFragment());
}
private void initViews() {
vp = (ViewPager) findViewById(R.id.vp);
myAdapter = new Mydapter(getSupportFragmentManager(), datas);
vp.setAdapter(myAdapter);
vp.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int i) {
if (i == datas.size() - 1) {
ThreeFragment.handler.sendEmptyMessage(1);
}
}
@Override
public void onPageScrollStateChanged(int i) {
}
});
}
}
在Activity中给ViewPager设置了监听事件
onPageSelected()方法中判断是否滑动到第三个Fragment,然后调用Fragment中的静态handler发送空消息来开启倒计时操作
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".test.WelActivity">
<android.support.v4.view.ViewPager
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</LinearLayout>
适配器中的代码
其中的List的泛型是Fragment
public class Mydapter extends FragmentPagerAdapter {
private List<Fragment> datas;
public Mydapter(FragmentManager fm, List<Fragment> datas) {
super(fm);
this.datas = datas;
}
@Override
public Fragment getItem(int i) {
return datas.get(i);
}
@Override
public int getCount() {
return datas.size();
}
}
最后进行效果展示(图片是我女神)
要开心加油