引言
现如今很多app中都有可以轮播的图片墙,虽然github上有很多的开源库可以使用,但不引用库你会不会实现Banner轮播图?这就不得不推出ViewPager了,本期我们就来利用ViewPager实现各种图片轮播,从0到1,从基础版到升级版再到完整版。给你的app做图片轮播Banner,看这一篇就够了!
效果预览
轮播Banner图.gif介绍
README:我做了三个ViewPager的示例,分别适用于以下场景:
第一个:切换有限个fragment。
第二个:简单的图片无限轮播。
第三个:图片无限轮播+动态切换+小圆点切换+透明标题(功能齐全)。
用法
第一步:主布局文件
主activity的layout布局文件:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:background="@android:color/darker_gray"
tools:ignore="MissingConstraints">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager.widget.ViewPager
android:background="@color/white"
android:id="@+id/view_pager1"
android:layout_margin="5dp"
android:layout_width="match_parent"
android:layout_height="250dp"
app:layout_constraintTop_toTopOf="parent" />
<androidx.viewpager.widget.ViewPager
android:background="@color/white"
android:id="@+id/view_pager2"
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_margin="5dp"
app:layout_constraintTop_toBottomOf="@+id/view_pager1" />
<FrameLayout
app:layout_constraintTop_toBottomOf="@id/view_pager2"
android:layout_width="match_parent"
android:background="@color/white"
android:layout_margin="5dp"
android:layout_height="250dp">
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager3"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="35dip"
android:layout_gravity="bottom"
android:background="#33000000"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="图片标题"
android:textColor="@android:color/white" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dip"
android:orientation="horizontal">
<View
android:id="@+id/dot_0"
android:layout_width="5dip"
android:layout_height="5dip"
android:layout_marginLeft="2dip"
android:layout_marginRight="2dip"
android:background="@drawable/dot_focused" />
<View
android:id="@+id/dot_1"
android:layout_width="5dip"
android:layout_height="5dip"
android:layout_marginLeft="2dip"
android:layout_marginRight="2dip"
android:background="@drawable/dot_normal" />
<View
android:id="@+id/dot_2"
android:layout_width="5dip"
android:layout_height="5dip"
android:layout_marginLeft="2dip"
android:layout_marginRight="2dip"
android:background="@drawable/dot_normal" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
第二步:第一个ViewPager的布局文件(其他2,3不用此)
layout下创建文件viewpager_view_item1
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:ignore="MissingConstraints">
<ImageView
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:id="@+id/viewpager_img"
android:src="@drawable/lunbo1"
android:layout_width="match_parent"
android:scaleType="fitCenter"
android:layout_height="200dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
创建三个fragment对应的三个布局文件:R.layout.viewpager_view_item1,……2,……3。
三个类似布局,唯一不同就是引用android:src="@drawable/lunbo1"图片资源不同。
图片名称分别是lunbo1,lunbo2,lunbo3
第三步:创建viewPager的适配器类(看清楚再使用,3个适配器类分别对应3个主布局中的viewPager1,viewPager2,viewPager3)
第1个viewPager的适配器类:
public class ViewPagerAdapterOne extends PagerAdapter {
List<View> viewPagerList;
public ViewPagerAdapterOne(List<View> imgList) {
this.viewPagerList = imgList;
}
@Override
public int getCount() {
return viewPagerList.size();
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup view, int position) {
view.addView(viewPagerList.get(position));
return viewPagerList.get(position);
}
@Override
public void destroyItem(@NonNull ViewGroup view, int position, @NonNull Object object) {
view.removeView(viewPagerList.get(position));
}
}
第2个viewPager的适配器类:
public class ViewPagerAdapterTwo extends PagerAdapter {
private ArrayList<ImageView> listviews;
public ViewPagerAdapterTwo(ArrayList<ImageView> views) {
this.listviews = views;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (listviews.get(position % listviews.size()).getParent() != null) {
container.removeView(listviews.get(position % listviews.size()));
}
container.addView(listviews.get(position % listviews.size()), 0);
return listviews.get(position % listviews.size());
}
@Override
public int getCount() {
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View view, Object o) {
return view == o;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
}
}
第3个viewPager的适配器类:
public class ViewPagerAdapterThree extends PagerAdapter {
ArrayList<ImageView> images;
private int maxValue = Integer.MAX_VALUE;
public ViewPagerAdapterThree(ArrayList<ImageView> images) {
this.images = images;
}
@Override
public int getCount() {
return maxValue;
}
//是否是同一张图片
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public Object instantiateItem(ViewGroup view, int position) {
// 在父布局中添加View前先判断父布局中是否已经存在View
// 如果父布局中已经有了需要在添加前做remove操作
// 否则会报错Android-The specified child already has a parent. You must call removeView() on the child's parent first.
int currentPosition = (position % images.size());
ImageView iv = images.get(currentPosition);
if (iv.getParent()!=null){
((ViewPager)iv.getParent()).removeView(iv);
}
view.addView(iv);
return iv;
}
@Override
public void destroyItem(ViewGroup view, int position, Object object) {
}
}
第四步:activity中使用
//viewpager使用实现轮播图
public class Case8 extends AppCompatActivity {
//初始化viewpager1
private ViewPager viewPager1;
private ViewPagerAdapterOne bannerAdapter;
private ArrayList<View> pageviewList;
//初始化viewpager2
private ViewPager viewPager2;
private ArrayList<ImageView> listviews;
private ViewPagerAdapterTwo viewPagerAdapterTwo;
int[] pics = {R.drawable.lunbo1, R.drawable.lunbo2, R.drawable.lunbo3};
@SuppressLint("HandlerLeak")
private MyHandler myHandler = new MyHandler();
//初始化viewpager3
private ViewPager viewPager3;
private int imageIds[];
private String[] titles;
private ArrayList<ImageView> images;
private ArrayList<View> dots;
private TextView title;
private ViewPagerAdapterThree viewPagerAdapterThree;
private int oldPosition = 0;//记录上一次点的位置
private int currentItem; //当前页面
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_case8);
initViewPager1(); //简单切换图片
inintViewPager2(); //图片动态切换
initViewPager3(); //切换+动态+小点+标题
}
private void initViewPager1() {
viewPager1 = findViewById(R.id.view_pager1);
//查找布局文件用LayoutInflater.inflate
LayoutInflater inflater = getLayoutInflater();
View view1 = inflater.inflate(R.layout.viewpager_view_item1, null);
View view2 = inflater.inflate(R.layout.viewpager_view_item2, null);
View view3 = inflater.inflate(R.layout.viewpager_view_item3, null);
//将view装入数组
pageviewList = new ArrayList<View>();
pageviewList.add(view1);
pageviewList.add(view2);
pageviewList.add(view3);
//绑定适配器
bannerAdapter = new ViewPagerAdapterOne(pageviewList);
viewPager1.setAdapter(bannerAdapter);
}
private void inintViewPager2() {
viewPager2 = findViewById(R.id.view_pager2);
//处理
listviews = new ArrayList<ImageView>();
for (int i = 0; i < pics.length; i++) {
ImageView imageView = new ImageView(this);
ViewGroup.LayoutParams viewPagerImageViewParams = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
imageView.setLayoutParams(viewPagerImageViewParams);
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.setImageResource(pics[i]);
listviews.add(imageView);
}
viewPagerAdapterTwo = new ViewPagerAdapterTwo(listviews);
viewPager2.setAdapter(viewPagerAdapterTwo);
viewPager2.setCurrentItem(1);
myHandler.sendEmptyMessageDelayed(0, 1500);// 间隔一秒切换一次
}
//viewPager2使用
@SuppressLint("HandlerLeak")
class MyHandler extends Handler {
@Override
public void handleMessage(@NonNull Message msg) {
viewPager2.setCurrentItem(viewPager2.getCurrentItem() + 1);
myHandler.sendEmptyMessageDelayed(0, 2000);
}
}
private void initViewPager3() {
//图片ID
imageIds = new int[]{
R.drawable.lunbo1,
R.drawable.lunbo2,
R.drawable.lunbo3
};
//图片标题
titles = new String[]{
"巩俐不低俗,我就不能低俗",
"乐视网TV版大派送",
"热血屌丝的反杀"
};
//显示的图片
images = new ArrayList<ImageView>();
for (int i = 0; i < imageIds.length; i++) {
ImageView imageView = new ImageView(this);
imageView.setBackgroundResource(imageIds[i]);
images.add(imageView);
}
//显示的点
dots = new ArrayList<View>();
dots.add(findViewById(R.id.dot_0));
dots.add(findViewById(R.id.dot_1));
dots.add(findViewById(R.id.dot_2));
title = (TextView) findViewById(R.id.title);
title.setText(titles[0]);
viewPager3 = (ViewPager) findViewById(R.id.view_pager3);
viewPagerAdapterThree = new ViewPagerAdapterThree(images);
viewPager3.setAdapter(viewPagerAdapterThree);
viewPager3.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
int currentPosition = position % (images.size());
title.setText(titles[currentPosition]);
dots.get(oldPosition).setBackgroundResource(R.drawable.dot_normal);
dots.get(currentPosition).setBackgroundResource(R.drawable.dot_focused);
oldPosition = currentPosition;
currentItem = currentPosition;
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
handler.sendEmptyMessage(1);
initViewPagerTouchEvent();
setFirstLocation();
}
@SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
//设置当前页面
currentItem = viewPager3.getCurrentItem();
viewPager3.setCurrentItem(currentItem + 1);
handler.sendEmptyMessageDelayed(1, 2000);
}
};
@Override
protected void onStop() {
super.onStop();
}
@SuppressLint("ClickableViewAccessibility")
private void initViewPagerTouchEvent() {
viewPager3.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
//按下
handler.removeCallbacksAndMessages(null);
}
break;
case MotionEvent.ACTION_UP: {
//抬起
handler.sendEmptyMessageDelayed(1, 2000);
}
break;
}
return false;
}
});
}
private void setFirstLocation() {
// mTvPagerTitle.setText(mImageTitles[previousPosition]);
// 把ViewPager设置为默认选中Integer.MAX_VALUE / 2,从十几亿次开始轮播图片,达到无限循环目的;
int m = (Integer.MAX_VALUE / 2) % images.size();
int currentPosition = Integer.MAX_VALUE / 2 - m - 1;
viewPager3.setCurrentItem(currentPosition);
}
}
网友评论