实现不添加任何依赖自己实现轮播图,使用ViewPager和布局容器来实现轮播的功能

综合了网上几位博主的文章,这里提供最直接最明了的实现。
实现效果如下,这里只是简单的实现,以后有机会再改进,也欢迎大家来指导我。

1. 万事先改布局呗,activity_main.xml:

<FrameLayout
    xmlns:android="http://schemas.android/apk/res/android"

    android:layout_width="match_parent"
    android:layout_height="225dp"
    android:layout_margin="15dp"
    android:orientation="vertical">

    <!--存放图片的ViewPager-->
    <android.support.v4.view.ViewPager
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/loopviewpager">
    </android.support.v4.view.ViewPager>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="25dp"
        android:layout_gravity="bottom"
        android:orientation="horizontal"
        android:gravity="center_vertical"
        android:background="#33000000">
        <!-- 标题-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/white"
            android:layout_marginLeft="10dp"
            android:layout_gravity="left"
            android:id="@+id/loop_dec"/>
        <!-- 小圆点-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/ll_dots_loop"
            android:orientation="horizontal"
            android:gravity="right"
            android:layout_marginRight="10dp"
            android:padding="10dp">
        </LinearLayout>
    </LinearLayout>
</FrameLayout>

这里可以看到我们要用三个ID,用于放图片的viewpager,标题和圆点指示器,这里用一个LinearLayout当做容器来加载圆点指示器。

2. 增加一张轮播图片,两张圆点指示器的png图,这里简单的用了一张图用五次来实现轮播,圆点大家可以用画图工具画一个像素小一点的圆点就行了,最后可以用padding来修正就好。如果还懒得话文末有demo地址自己去下载吧。


在drawable添加dot.xml文件,选中时是白色,未选中是灰色点。

<selector xmlns:android="http://schemas.android/apk/res/android">

    <item android:drawable="@drawable/white_dot" android:state_enabled="true"/>
    <item android:drawable="@drawable/gray_dot"  android:state_enabled="false"/>

</selector>

向value中新建一个pager_img.xml文件添加几个轮播图id值用来到时候引用监听用户点击动作。

<resources>
    <item name="pager_img1" type="id"></item>
    <item name="pager_img2" type="id"></item>
    <item name="pager_img3" type="id"></item>
    <item name="pager_img4" type="id"></item>
    <item name="pager_img5" type="id"></item>
</resources>

3. 新建LoopViewAdapter类继承PagerAdapter做ViewPager的适配器并重写其中的几个方法

class LoopViewAdapter extends PagerAdapter{

    private ArrayList<ImageView> imageViewList;

    public LoopViewAdapter(ArrayList<ImageView> mImgList){
        imageViewList = mImgList;
    }

    // 1. 返回要显示的条目内容, 创建条目
    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        // container: 容器: ViewPager
        // position: 当前要显示条目的位置 0 -> 4
        //newPosition = position % 5
        int newPosition = position % imageViewList.size();
        ImageView img = imageViewList.get(newPosition);
        // a. 把View对象添加到container中
        container.addView(img);
        // b. 把View对象返回给框架, 适配器
        return img;
    }

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView((View)object);
    }

    @Override
    public int getCount() {
        return Integer.MAX_VALUE;   //返回一个无限大的值,可以 无限循环!!!!!
    }

    /**
     * 判断是否使用缓存, 如果返回的是true, 使用缓存. 不去调用instantiateItem方法创建一个新的对象
     */
    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
        return view == o ;
    }
}

注意这个重写的getCount()方法,刚开始在其他博主的文章里这个方法返回的值可能是轮播图的个数,但是我实现的时候却发现不能实现无限轮播,只能轮播一次,最后我将这个值改为一个大的值发现实现了无限轮播,大家也可以试一下,看自己是不是也遇到了同样的问题。

4. 新建pagerOnClickListener类实现View.OnClickListener接口。

public class pagerOnClickListener implements View.OnClickListener{

    Context mContext;
    public pagerOnClickListener(Context mContext){
        this.mContext=mContext;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.pager_img1:
                Toast.makeText(mContext, "图片1被点击", Toast.LENGTH_SHORT).show();
                break;
            case R.id.pager_img2:
                Toast.makeText(mContext, "图片2被点击", Toast.LENGTH_SHORT).show();
                break;
            case R.id.pager_img3:
                Toast.makeText(mContext, "图片3被点击", Toast.LENGTH_SHORT).show();
                break;
            case R.id.pager_img4:
                Toast.makeText(mContext, "图片4被点击", Toast.LENGTH_SHORT).show();
                break;
            case R.id.pager_img5:
                Toast.makeText(mContext, "图片5被点击", Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

5. 最后修改MainActivity中的代码就好啦

public class MainActivity extends AppCompatActivity {

    private ViewPager viewPager;  //轮播图模块
    private int[] mImg;
    private int[] mImg_id;
    private String[] mDec;
    private ArrayList<ImageView> mImgList;
    private LinearLayout ll_dots_container;
    private TextView loop_dec;
    private int previousSelectedPosition = 0;
    boolean isRunning = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initLoopView();  //实现轮播图
    }

    private void initLoopView() {
        viewPager = (ViewPager)findViewById(R.id.loopviewpager);
        ll_dots_container = (LinearLayout)findViewById(R.id.ll_dots_loop);
        loop_dec = (TextView)findViewById(R.id.loop_dec);

        // 图片资源id数组
        mImg = new int[]{
                R.drawable.test3,
                R.drawable.test3,
                R.drawable.test3,
                R.drawable.test3,
                R.drawable.test3
        };

        // 文本描述
        mDec = new String[]{
                "Test1",
                "Test2",
                "Test3",
                "Test4",
                "Test5"
        };

        mImg_id = new int[]{
                R.id.pager_img1,
                R.id.pager_img2,
                R.id.pager_img3,
                R.id.pager_img4,
                R.id.pager_img5
        };

        // 初始化要展示的5个ImageView
        mImgList = new ArrayList<ImageView>();
        ImageView imageView;
        View dotView;
        LinearLayout.LayoutParams layoutParams;
        for(int i=0;i<mImg.length;i++){
            //初始化要显示的图片对象
            imageView = new ImageView(this);
            imageView.setBackgroundResource(mImg[i]);
            imageView.setId(mImg_id[i]);
            imageView.setOnClickListener(new pagerOnClickListener(getApplicationContext()));
            mImgList.add(imageView);
            //加引导点
            dotView = new View(this);
            dotView.setBackgroundResource(R.drawable.dot);
            layoutParams = new LinearLayout.LayoutParams(10,10);
            if(i!=0){
                layoutParams.leftMargin=10;
            }
            //设置默认所有都不可用
            dotView.setEnabled(false);
            ll_dots_container.addView(dotView,layoutParams);
        }

        ll_dots_container.getChildAt(0).setEnabled(true);
        loop_dec.setText(mDec[0]);
        previousSelectedPosition=0;
        //设置适配器
        viewPager.setAdapter(new LoopViewAdapter(mImgList));
        // 把ViewPager设置为默认选中Integer.MAX_VALUE / t2,从十几亿次开始轮播图片,达到无限循环目的;
        int m = (Integer.MAX_VALUE / 2) %mImgList.size();
        int currentPosition = Integer.MAX_VALUE / 2 - m;
        viewPager.setCurrentItem(currentPosition);

        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int i, float v, int i1) {

            }

            @Override
            public void onPageSelected(int i) {
                int newPosition = i % mImgList.size();
                loop_dec.setText(mDec[newPosition]);
                ll_dots_container.getChildAt(previousSelectedPosition).setEnabled(false);
                ll_dots_container.getChildAt(newPosition).setEnabled(true);
                previousSelectedPosition = newPosition;
            }

            @Override
            public void onPageScrollStateChanged(int i) {

            }
        });

        // 开启轮询
        new Thread(){
            public void run(){
                isRunning = true;
                while(isRunning){
                    try{
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //下一条
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            viewPager.setCurrentItem(viewPager.getCurrentItem()+1);
                        }
                    });
                }
            }
        }.start();

    }
}

最后附上demo源码:https://github/GYongJia/LoopViewDemo

更多推荐

Android开发-轮播图的详细实现