Android 小工具--轮播图

1.导入Glide依赖

 compile 'com.github.bumptech.glide:glide:3.7.0'

2.BannerView类

public class BannerView extends FrameLayout implements ViewPager.OnPageChangeListener {
    
    
    private boolean isLoop=false;
    private ViewPager viewPager;
    private BannerAdapter adapter;
    private Handler handler;
    private LinearLayout points;
    private List<ImageView> tips;
    private ArrayList<?> dataList; //数据源
    private int pointsFocused;
    private int pointsUnFocused;
    private int defaultPic;
    private BannerOnClickListener bannerOnClickListener;
    private boolean isPositive = true; //是否正向循环
    private Runnable runnable;


    public BannerView(Context context) {
    
    
        super(context);
        init(context);
    }

    public BannerView(Context context, AttributeSet attrs) {
    
    
        super(context, attrs);
        init(context);
    }

    public BannerView(Context context, AttributeSet attrs, int defStyleAttr) {
    
    
        super(context, attrs, defStyleAttr);
        init(context);
    }
    private void init(Context context){
    
    
        LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        viewPager = new ViewPager(context);
        viewPager.setLayoutParams(params);
        viewPager.addOnPageChangeListener(this);

        addView(viewPager);
        handler = new Handler();

        points = new LinearLayout(context);
        //设置points的LayoutParams
        LinearLayout.LayoutParams pLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        points.setLayoutParams(pLayoutParams);
        points.setOrientation(LinearLayout.HORIZONTAL);
        //这里很重要 设置  layout_gravity  相对于父布局的位置
        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(points.getLayoutParams());
        layoutParams.gravity= (Gravity.BOTTOM|Gravity.CENTER);  //设置轮播点靠右下角展示
        layoutParams.bottomMargin=dip2px(context,5);
        layoutParams.rightMargin=dip2px(context,10);
        points.setLayoutParams(layoutParams);
        addView(points);

    }

    /**
     * 设置轮播点
     * @param number
     */
    private void setPoint(int number){
    
    

        for(int i=0; i<number; i++){
    
    
            ImageView imageView = new ImageView(getContext());
            imageView.setLayoutParams(new ViewGroup.LayoutParams(dip2px(getContext(),10),dip2px(getContext(),10)));
            tips.add(imageView);
            if(i == 0){
    
    
                tips.get(i).setBackgroundResource(pointsFocused);
            }else{
    
    
                tips.get(i).setBackgroundResource(pointsUnFocused);
            }
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(new ViewGroup.LayoutParams(30,
                    30));
            layoutParams.leftMargin = dip2px(getContext(),2);//轮播点左右间距
            layoutParams.rightMargin = dip2px(getContext(),2);//轮播点左右间距
            points.addView(imageView, layoutParams);
        }



    }


    /**
     * 初始化数据
     * @param list  传入的图片数据,本地图片id,网络图片地址都可以
     * @param defaultPic 默认的图片,在加载失败或者图片尚未加载完全时显示默认图片
     * @param needPoint 是否需要指示点
     * @param pointsUnFocused  指示点的未选中状态图片,不需要指示点设为0即可
     * @param pointsFocused  指示点的选中状态图片,不需要指示点设为0即可
     * @param isLoop 图片是否可以无限循环滑动
     */
    public void init(ArrayList<?> list,int defaultPic ,boolean needPoint,int pointsUnFocused,int pointsFocused,boolean isLoop){
    
    
        if(list==null)return;
        dataList =list;
        this.defaultPic=defaultPic;//默认图片
        this.isLoop=isLoop;//是否轮询

        adapter = new BannerAdapter(list);
        viewPager.setAdapter(adapter);


        //设置指示点
        if(list.size()<=1)needPoint=false;//如果只有一张图片就不显示指示点
        tips = new ArrayList<>();
        if(needPoint){
    
    
            this.pointsUnFocused=pointsUnFocused;
            this.pointsFocused=pointsFocused;
            setPoint(list.size());
        }

    }

    /**
     * 设置自动循环时间,不设置就不会自动循环
     * @param loopTime
     */
    public void setAutoLoop(int loopTime){
    
    
        autoLoop(loopTime);
    }


    //设置banner点击监听
    public void setBannerOnClickListener(BannerOnClickListener bannerOnClickListener){
    
    
        this.bannerOnClickListener=bannerOnClickListener;
    }
    //设置banner点击监听
    public interface BannerOnClickListener{
    
    
        void onClick(int position);
    }

    private void autoLoop(final int time) {
    
    

        runnable = new Runnable() {
    
    
            @Override
            public void run() {
    
    
                int item = viewPager.getCurrentItem();

                if (item >= adapter.getCount() - 1) {
    
      //判断循环到哪里了
                    isPositive = false;
                } else if (item <= 0) {
    
    
                    isPositive = true;
                }
                if (isPositive) {
    
    
                    item++;
                } else if (!isPositive) {
    
    
                    item--;
                }
                viewPager.setCurrentItem(item);
                handler.postDelayed(this, time);
            }
        };
        handler.postDelayed(runnable,time);
    }

    /**
     * 移除掉handler
     */
    public void removeHandler(){
    
    
        handler.removeCallbacks(runnable);
        handler=null;
    }


    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    
    

    }

    @Override
    public void onPageSelected(int position) {
    
    
        position=position%dataList.size();
        for(int i=0; i<tips.size(); i++){
    
    
            if(i == position){
    
    
                tips.get(i).setBackgroundResource(pointsFocused);
            }else{
    
    
                tips.get(i).setBackgroundResource(pointsUnFocused);
            }
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    
    

    }
    class BannerAdapter extends PagerAdapter {
    
    
        private ArrayList<?> list;

        public BannerAdapter(ArrayList<?> url) {
    
    
            list=url;
        }
        @Override
        public int getCount() {
    
    
            if(!isLoop)return list.size();//不循环

            if(list.size()==1){
    
      //循环
                return 1;
            }else {
    
    
                return 500*list.size();
            }
        }
        @Override
        public boolean isViewFromObject(View view, Object object) {
    
    
            return view==object;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
    
    
            position=position%dataList.size();
            ImageView imageView = new ImageView(getContext());
            imageView.setBackground(getResources().getDrawable(defaultPic));
            imageView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            //此处用Glide加载图片,如果用的其他的,可以再这里更换
            Glide.with(getContext()).load(list.get(position)).error(defaultPic).centerCrop().into(imageView);//Glide加载图片
            container.addView(imageView);
            final int finalPosition = position;
            imageView.setOnClickListener(new OnClickListener() {
    
    
                @Override
                public void onClick(View v) {
    
    
                    bannerOnClickListener.onClick(finalPosition);//点击事件的回调
                }
            });
            imageView.setOnTouchListener(new OnTouchListener() {
    
    
                @Override
                public boolean onTouch(View v, MotionEvent event) {
    
    
                    if(event.getAction()==MotionEvent.ACTION_DOWN){
    
    
                        handler.removeCallbacks(runnable);  //手指触碰banner条后,停止循环
                    }
                    if(event.getAction()==MotionEvent.ACTION_UP){
    
    
                        handler.removeCallbacks(runnable);
                        handler.postDelayed(runnable,2000); //手指抬起后2秒后继续循环
                    }
                    if(event.getAction()==MotionEvent.ACTION_MOVE){
    
    
                        handler.removeCallbacks(runnable);
                        handler.postDelayed(runnable,2000); //手指抬起后2秒后继续循环
                    }
                    return false;
                }
            });
            return imageView;
        }
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
    
    
            container.removeView((View) object);
        }

    }
    private   int dip2px(Context context, float dipValue){
    
    
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int)(dipValue * scale + 0.5f);
    }
    private  int px2dip(Context context, float pxValue){
    
    
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int)(pxValue / scale + 0.5f);
    }

}

3.Activity


public class MainActivity extends AppCompatActivity {
    
    

    private BannerView bannerViewView;
    private ArrayList<Integer> images = new ArrayList<>(); //设置数据源
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //找到控件
        bannerViewView = (BannerView) findViewById(R.id.bannerView);
        images.add(R.mipmap.a1);
        images.add(R.mipmap.a2);
        images.add(R.mipmap.a3);
        //设置点击事件监听
        bannerViewView.setBannerOnClickListener(new BannerView.BannerOnClickListener() {
    
    
            @Override
            public void onClick(int position) {
    
    
            }
        });
       
     

        /**
         * 初始化数据
         * @param list  传入的图片数据,本地图片id,网络图片地址都可以
         * @param defaultPic 默认的图片,在加载失败或者图片尚未加载完全时显示默认图片
         * @param needPoint 是否需要指示点
         * @param pointsUnFocused  指示点的未选中状态图片,不需要指示点设为0即可
         * @param pointsFocused  指示点的选中状态图片,不需要指示点设为0即可
         * @param isLoop 图片是否可以无限循环滑动
         */
            bannerViewView.init(images,R.mipmap.a1,true,R.mipmap.y,R.mipmap.y2,false);


//设置循环播放的间隔时间,不设置就不会循环播放
        bannerViewView.setAutoLoop(2000);
    }

    @Override
    protected void onDestroy() {
    
    
        super.onDestroy();
        bannerViewView.removeHandler();//移除掉handler的Callbacks
    }
}

4.布局文件xml

<?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"
    tools:context=".MainActivity">

    <com.hnucm18jr.myapplication.BannerView
        android:id="@+id/bannerView"
        android:layout_width="0dp"
        android:layout_height="150dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

运行
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_46526828/article/details/109682383