打造好用的App首页轮播图~~

我们在项目中首页经常会有一个轮播图模块
是利用viewpager实现的 每次都要重新写一遍所有的逻辑没有复用的效果
所以就把这个东西封装好来达到复用的效果使用起来也特别简单
这篇博客会先给一个简单使用的例子之后再分析实现的过程
虽然写的很烂
看到后面应该会有一点点东西的
吧~

先看一个效果图:
这里写图片描述

好单调~~~~不过能看到
就是个基本的轮播图
和别的控件配合起来就会很好多
我已经封装好了
先说说怎么用

第一步:

在git上把我写好的这个类下载下来Git_ViewPagerClass
git上是一个完整的例子啊

在你的项目里面加入这个类就是这个ViewPagerClass ~~~~我一般就直接复制了因为别的我也不会
然后项目结构就大概是这样:
这里写图片描述

第二步:

在你要使用的xml文件中直接使用这个类:
这里写图片描述

因为我的包名是com.example.katherine_qj.viewpagerdemo
所以控件的名字是这样
那你的肯定就是你的包名加类名这样子
我也
不知道我说的清楚不

大概就是在xml中引用你项目中的这个类~~~
ViewPagerClass

第三步:

这里写图片描述

很清楚吧
就是实例化viewPager之后给他暴露出来的setViewPagerViews( )方法中传入一个list集合就好了
集合里面是你要轮播的图片 底部指示物会根据你添加的图片自动生成相应的个数
~~

如果你只是想使用一个现成的轮播图 以上就可以了

—————————————————————

以下
来分析一下这个轮播图是如何封装的:

我想把我大概的思路写一下
首先想一下写一个轮播图需要什么?

需要装图片
需要小圆点显示播放到哪一张了
还需要把viewpager和小圆点联系起来
跑的时候图片轮播小圆点也要动

所以我们先画一张图这样子
这里写图片描述

我们第一步就是要把这些小控件组在一起
把他们都放到RelativeLayout中

第二步 我们采用线程的方式让他们跑起来
这样分为两步就清楚很多

这个类的创建思路我先画图表示出来

是怎么把控件放在一起的
这里写图片描述

看一下这部分的代码

  • 这是初始化viewpager和小圆点部分 可以看到就是把viewpager和linearLayout放到Relativelayout中

 public void initViewPager() {
        viewPager = new ViewPager(getContext());
        LayoutParams viewPagerLp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        addView(viewPager,viewPagerLp);
    }
   /* 初始化LinearLayout*/
    public void initLinearLayout(){
        viewDots = new LinearLayout(getContext());
        LayoutParams viewDotsLp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        viewDotsLp.addRule(ALIGN_PARENT_BOTTOM);
        viewDotsLp.bottomMargin = dpTopx(5);
        viewDots.setGravity(gravity);
        addView(viewDots,viewDotsLp);
    }
  • 这是我们为Viewpager构造的适配器
    继承自pagerAdapter重载了四个方法 方法的解释代码中都有
class ViewPagerAdapter extends PagerAdapter{
    /*以下四个方法是必须被重载的*/
        @Override
        public int getCount() {
           if (views==null){
               return 0;
           }
            return views.size();
        }
         /*
        该函数用来判断instantiateItem(ViewGroup, int)函数所返回来的Key
        与一个页面视图是否是代表的同一个视图(即它俩是否是对应的,对应的表示同一个View)
         */
        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view==object;
        }
        /*为即将展示页做操作*/
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            if (views.get(position).getParent()!=null){
                ((ViewGroup)views.get(position).getParent()).removeView(views.get(position));
            }
            container.addView(views.get(position));
            return views.get(position);
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView(views.get(position));
        }
    }
  • 根据图片数量生成圆点 圆点的两种样式可以 自己设置放在drawable文件夹下
 /*根据图片数量生成圆点*/
    private void addDots(int size){
        dots = new ArrayList<ImageView>();
        for (int i = 0; i < size; i++) {
            ImageView dot = new ImageView(getContext());
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    dpTopx(dotsRedio), dpTopx(dotsRedio));
            params.setMargins(dpTopx(dotsSpacing), 0, dpTopx(dotsSpacing), 0);
            dot.setLayoutParams(params);
            if (i == 0) {
                dot.setBackgroundResource(R.drawable.dot_focused);
            } else {
                dot.setBackgroundResource(R.drawable.dot_normal);
            }
            dots.add(dot);
            viewDots.addView(dot);
        }
    }
  • 下面就是我们暴露出来的一个方法 传入一个图片集合我们 在里面通过 设置适配生成圆点 设置滑动事件等把之前的准备联系在一起
 public void setViewPagerViews(List<View> views){
        this.views = views;
        addDots(views.size());
        viewPager.setAdapter(new ViewPagerAdapter());
        /*滑动的时候要改变圆点的颜色*/
        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int positiona) {
             position = positiona;
                for (int i = 0; i < dots.size(); i++) {
                    if (position == i) {
                        dots.get(i).setBackgroundResource(
                                R.drawable.dot_focused);
                    } else {
                        dots.get(i)
                                .setBackgroundResource(R.drawable.dot_normal);
                    }
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
        viewPager.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                    case MotionEvent.ACTION_MOVE:
                        isContinue = false;
                        break;
                    case MotionEvent.ACTION_UP:
                        isContinue = true;
                        break;
                    default:
                        isContinue = true;
                        break;
                }
                return false;
            }
        });
        new Thread(this).start();
    }
  • 最后可以看见有一个线程开始执行的语句 那就是当我们都设置好 了之后就可以通过线程让他轮播起来
 @Override
    public void run() {
        while (isAlive) {
            if (isContinue) {
                pagerHandler.sendEmptyMessage(position);
                position = (position + 1) % views.size();
                try {
                    Thread.sleep(changeTime);
                } catch (InterruptedException e) {
                }
            }
        }
    }

    Handler pagerHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            viewPager.setCurrentItem(msg.what);
           /* setCurrentItem(int index)方法主要用来制定初始化的页面。
            例如加入3个页面通过setCurrentItem(0)制定第一个页面为当前页面*/
            super.handleMessage(msg);
        }
    };

以上就是实现过程
还有一些小细节

可以看一下我这个类全部的代码

package com.example.katherine_qj.viewpagerdemo;

import android.content.Context;
import android.os.Handler;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.text.Layout;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;

import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Katherine-qj on 2016/11/20.
 */

public class ViewPagerClass extends RelativeLayout implements Runnable {
    /*定义初始变量*/
    /*定义关于ViewPager初始变量*/
    private ViewPager viewPager;
    private List<View> views;
    /*定义关于小圆点的初始变量*/
    private LinearLayout viewDots;
    private List<ImageView> dots;
    private int dotsSpacing = 2;
    private int dotsRedio = 15;
    /*定于关于轮播的初始变量*/
    private int position = 0;
    private boolean isContinue = true;
    private boolean isAlive = true;
    private  int gravity = Gravity.RIGHT;
    private  int changeTime = 1500;



    public ViewPagerClass(Context context) {
        this(context, null);
    }

    public ViewPagerClass(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ViewPagerClass(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initViewPager();
        initLinearLayout();
    }
    /*初始化viewPager*/
    public void initViewPager() {
        viewPager = new ViewPager(getContext());
        LayoutParams viewPagerLp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        addView(viewPager,viewPagerLp);
    }
   /* 初始化LinearLayout*/
    public void initLinearLayout(){
        viewDots = new LinearLayout(getContext());
        LayoutParams viewDotsLp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        viewDotsLp.addRule(ALIGN_PARENT_BOTTOM);
        viewDotsLp.bottomMargin = dpTopx(5);
        viewDots.setGravity(gravity);
        addView(viewDots,viewDotsLp);
    }
    /*为viewPager构造适配器*/
    class ViewPagerAdapter extends PagerAdapter{
    /*以下四个方法是必须被重载的*/
        @Override
        public int getCount() {
           if (views==null){
               return 0;
           }
            return views.size();
        }
         /*
        该函数用来判断instantiateItem(ViewGroup, int)函数所返回来的Key
        与一个页面视图是否是代表的同一个视图(即它俩是否是对应的,对应的表示同一个View)
         */
        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view==object;
        }
        /*为即将展示页做操作*/
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            if (views.get(position).getParent()!=null){
                ((ViewGroup)views.get(position).getParent()).removeView(views.get(position));
            }
            container.addView(views.get(position));
            return views.get(position);
        }

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


    /*根据图片数量生成圆点*/
    private void addDots(int size){
        dots = new ArrayList<ImageView>();
        for (int i = 0; i < size; i++) {
            ImageView dot = new ImageView(getContext());
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    dpTopx(dotsRedio), dpTopx(dotsRedio));
            params.setMargins(dpTopx(dotsSpacing), 0, dpTopx(dotsSpacing), 0);
            dot.setLayoutParams(params);
            if (i == 0) {
                dot.setBackgroundResource(R.drawable.dot_focused);
            } else {
                dot.setBackgroundResource(R.drawable.dot_normal);
            }
            dots.add(dot);
            viewDots.addView(dot);
        }
    }
    public void setViewPagerViews(List<View> views){
        this.views = views;
        addDots(views.size());
        viewPager.setAdapter(new ViewPagerAdapter());
        /*滑动的时候要改变圆点的颜色*/
        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int positiona) {
             position = positiona;
                for (int i = 0; i < dots.size(); i++) {
                    if (position == i) {
                        dots.get(i).setBackgroundResource(
                                R.drawable.dot_focused);
                    } else {
                        dots.get(i)
                                .setBackgroundResource(R.drawable.dot_normal);
                    }
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
        viewPager.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                    case MotionEvent.ACTION_MOVE:
                        isContinue = false;
                        break;
                    case MotionEvent.ACTION_UP:
                        isContinue = true;
                        break;
                    default:
                        isContinue = true;
                        break;
                }
                return false;
            }
        });
        new Thread(this).start();


    }
    @Override
    public void run() {
        while (isAlive) {
            if (isContinue) {
                pagerHandler.sendEmptyMessage(position);
                position = (position + 1) % views.size();
                try {
                    Thread.sleep(changeTime);
                } catch (InterruptedException e) {
                }
            }
        }
    }

    Handler pagerHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            viewPager.setCurrentItem(msg.what);
           /* setCurrentItem(int index)方法主要用来制定初始化的页面。
            例如加入3个页面通过setCurrentItem(0)制定第一个页面为当前页面*/
            super.handleMessage(msg);
        }
    };
    private int dpTopx(int dp) {
        float scale = getResources().getDisplayMetrics().density;
        return (int) (dp * scale + 0.5f);
    }
    /*当调到其他页面时 调用stop停止线程*/
    public void stop() {
        isAlive = false;
    }
}

好久好久都没写博客了~~~~~~~~~~~~~~~~~
要坚持坚持

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值