Android专题Android控件使用篇

用ViewPager实现轮播图:图片无限轮播+动态切换+小圆点切

2020-09-21  本文已影响0人  千夜零一

引言

  现如今很多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);
    }
}
效果图
viewPager轮播图.jpeg
上一篇下一篇

猜你喜欢

热点阅读