轮播图的组合控件、自定义属性、自动轮播

  昨天到今天写的是轮播的自动播放、无限循环、点击事件、也可以自己滑动。

  这个轮播图是进行过封装的,把一些简单的数据设置页面交互去提取出来。让以后用的时候直接可以用。

  自动播放的话可以通过自定义属性来进行时间延迟设置。点击事件只是写了一个Toast,具体的内容可以根据自己的业务交互去写。

  还有标题,它的内容自己去可以进行设置,显不显示也可以在MainActivity.xml中进行设置,用的也是一个自定义属性。

  点击和移动时间事件是由=有判断的,当移动的位置小于5像素时,并且时间小于1秒的话就会判定为点击事件,进行点击事件的的操作。

  动态添加圆点indicator,页面切换的话也会动态切换治指示器焦点,让焦点聚集到当前显示的图片。当然指示器圆点的形状都是自己可以设置的。

  自定义ViewPager+自定义属性

 

 

 

 

 

LuBo包中的:

 

 

package com.example.lunbo2.LuBo;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

import com.example.lunbo2.R;


public class LYLooperPager extends LinearLayout {

    private LyViewPager mviewPager;
    private LinearLayout mPointContainer;
    private TextView mTitleTv;
    private BindTitleListener mTitleSetListener=null;
    private InnerAdapter mInnerAdapter=null;
    private OnItemClickListener mOnItemClickListener=null;
    private boolean isTitleShow;
    //private int mPagerShowCount;
    private int mSwitchTime;


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

    public LYLooperPager(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public LYLooperPager(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        LayoutInflater.from(context).inflate(R.layout.looper_pager_layout,this,true);
        //自定义属性
        TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.looper_style);
        //从TypeArray中读取属性
        isTitleShow = ta.getBoolean(R.styleable.looper_style_is_title_show,true);
        //mPagerShowCount = ta.getInteger(R.styleable.looper_style_show_pager_count, 1);
        mSwitchTime = ta.getInteger(R.styleable.looper_style_switch_time, -1);
        ta.recycle();
        init();
    }

    private void init() {
        initView();
        initEvent();
    }

    private void initEvent() {
        mviewPager.setPagerItemClickListener(new LyViewPager.OnPagerItemClickListener() {
            @Override
            public void onItemClick(int position) {
                if (mOnItemClickListener != null&&mInnerAdapter!=null) {
                    int realPostion=position%mInnerAdapter.getDataSize();
                    mOnItemClickListener.onItemClick(realPostion);
                }
            }
        });


        mviewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                //切换的一个回代调
            }

            @Override
            public void onPageSelected(int position) {
                //切换停下来的回调
                if (mInnerAdapter !=null) {
                    //停下来以后设置标题
                    int realPosition=position%mInnerAdapter.getDataSize();

                    if (mTitleSetListener!=null) {
                        mTitleTv.setText(mTitleSetListener.getTitle(realPosition));
                    }
                    //切换指示器焦点
                    updateIndication();
                }

            }

            @Override
            public void onPageScrollStateChanged(int state) {
                //切换状态改变的回调


            }
        });
    }



    public interface BindTitleListener{
        String getTitle(int
                                ion);
    }

    //设置数据
    public  void setData(InnerAdapter innerAdapter,BindTitleListener listener){
        this.mTitleSetListener=listener;
        mviewPager.setAdapter(innerAdapter);
        //设置所处的位置为中间+1,只有加一,显示的才是第一个图片。
        mviewPager.setCurrentItem(Integer.MAX_VALUE/2+1);
        this.mInnerAdapter=innerAdapter;
        if (listener!=null) {
            mTitleTv.setText(listener.getTitle(mviewPager.getCurrentItem()%mInnerAdapter.getDataSize()));
        }
        //根据数据的个数,来动态船创建圆点
        updateIndication();


    }
    public abstract static class InnerAdapter extends PagerAdapter{


        @Override
        public int getCount() {
            return Integer.MAX_VALUE;
        }

        @Override
        public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
            return view==object;
        }

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



        @NonNull
        @Override
        public Object instantiateItem(@NonNull ViewGroup container,int position) {
            final int realPosition=position%getDataSize();
           View itemView= getSubView(container,realPosition);

            container.addView(itemView);

            return itemView;
        }

        protected abstract int getDataSize();

        protected abstract View getSubView(ViewGroup container, int position);



    }

    public void setOnItemClickListener(OnItemClickListener listener){
        this.mOnItemClickListener=listener;
    }
//  暴露接口
    public interface OnItemClickListener{
        void onItemClick(int position);
    }


    private void updateIndication(){
        if (mInnerAdapter!=null&&mTitleSetListener!=null) {
            int count =mInnerAdapter.getDataSize();
            mPointContainer.removeAllViews();
            for (int i=0;i<count;i++){
                View point=new View(getContext());
                if (mviewPager.getCurrentItem()%mInnerAdapter.getDataSize()==i){
                    point.setBackground(getResources().getDrawable(R.drawable.shape_circle_red));
                   // point.setBackgroundColor(Color.parseColor("#ff0000"));
                }else{
                 //   point.setBackgroundColor(Color.parseColor("#ffffff"));
                    point.setBackground(getResources().getDrawable(R.drawable.shape_circle_white));
                }

                //设置大小
                LinearLayout.LayoutParams layoutParams=new LinearLayout.LayoutParams(SizeUtils.dip2px(getContext(),10)
                        ,SizeUtils.dip2px(getContext(),10));
                layoutParams.setMargins(SizeUtils.dip2px(getContext(),5),
                        0,SizeUtils.dip2px(getContext(),5),0);
                point.setLayoutParams(layoutParams);
                //添加到容器里去
                mPointContainer.addView(point);

            }
        }
    }


    private void initView() {
        mviewPager = findViewById(R.id.looper_pager_vp);
        if (mSwitchTime!=-1) {
            mviewPager.setDelayTime(mSwitchTime);
        }

        //进行预加载;
        mviewPager.setOffscreenPageLimit(3);
        mviewPager.setPageMargin(SizeUtils.dip2px(getContext(),10));
        mPointContainer = findViewById(R.id.looper_point_container_lv);
        mTitleTv = findViewById(R.id.looper_title_tv);
        if (!isTitleShow){
            mTitleTv.setVisibility(GONE);
        }
    }
}

 

package com.example.lunbo2.LuBo;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.ViewPager;

public class LyViewPager extends ViewPager {
    private static final String TAG="LyViewPager";

    //这个是默认的切换时间
    public static final int DEAFUL_SWITCH_TIME=1000;

    private long delayTime=DEAFUL_SWITCH_TIME;
    private OnPagerItemClickListener mItemClickListener=null;


    public LyViewPager(@NonNull Context context) {
        this(context,null);
    }

    private boolean isClick=false;
    private float downX;
    private float downY;
    private long downTime;

    public LyViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int action = event.getAction();
                switch (action){
                    case MotionEvent.ACTION_DOWN:
                        downX=event.getX();
                        downY=event.getY();
                        downTime=System.currentTimeMillis();
                        stopLooper();
                        break;
                     case MotionEvent.ACTION_CANCEL:
                     case MotionEvent.ACTION_UP:
                         float dx = Math.abs(event.getX() - downX);
                         float dy = Math.abs(event.getY() - downY);
                         long dTime=System.currentTimeMillis()-downTime;
                         isClick=dy<=5&&dx<=5&&dTime<=1000;
                         if (isClick&&mItemClickListener!=null){
                             mItemClickListener.onItemClick(getCurrentItem());
                         }
                         startLooper();
                         break;
                }
                return false;
            }
        });
    }
    //暴露一个方法
    public void setPagerItemClickListener(OnPagerItemClickListener itemClickListener){
        this.mItemClickListener=itemClickListener;
    }


    //暴露一个点击事件的接口
    public interface OnPagerItemClickListener{
        void onItemClick(int position);
    }

    public void setDelayTime(long delayTime){
        this.delayTime=delayTime;
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        Log.d(TAG,"onAttachedToWindow...");
        startLooper();
    }

    private void startLooper() {
        removeCallbacks(mTask);
        postDelayed(mTask,delayTime);
    }
    private Runnable mTask=new Runnable() {
        @Override
        public void run(){

                    int currentItem = getCurrentItem();
                    currentItem++;
                    setCurrentItem(currentItem);
                    postDelayed(this,delayTime);

        }
    };

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        Log.d(TAG,"onDetachedFromWindow...");
        stopLooper();
    }

    private void stopLooper() {
        removeCallbacks(mTask);
    }
}
package com.example.lunbo2.LuBo;

public class PagerItem {
    private String title;

    private Integer picResId;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Integer getPicResId() {
        return picResId;
    }

    public void setPicResId(Integer picResId) {
        this.picResId = picResId;
    }

    public PagerItem(String title, Integer picResId) {
        this.title = title;
        this.picResId = picResId;
    }
}
package com.example.lunbo2.LuBo;

import android.content.Context;

public class SizeUtils {

    public static int dip2px(Context context, float dpValue) {
        float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}

MainActivity(这是唯一一创建的一个Activity)

 

 

 

package com.example.lunbo2;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;

import com.example.lunbo2.LuBo.LYLooperPager;
import com.example.lunbo2.LuBo.PagerItem;

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

public class MainActivity extends AppCompatActivity {

    private LYLooperPager mLooperPager;
    private List<PagerItem> mData=new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        initView();
        //设置点击事件;
        initEvent();

    }

    private void initEvent() {
        if (mLooperPager!=null){
            mLooperPager.setOnItemClickListener(new LYLooperPager.OnItemClickListener() {
                @Override
                public void onItemClick(int position) {
                    Toast.makeText(MainActivity.this,"点击了第"+(position+1)+"个item",Toast.LENGTH_SHORT).show();
                    //根据交互业务去实现具体逻辑;
                }
            });

        }
    }

    private void initData() {
        mData.add(new PagerItem("第一个图片",R.mipmap.one));
        mData.add(new PagerItem("第二个图片",R.mipmap.two));
        mData.add(new PagerItem("第三个图片",R.mipmap.three));
        mData.add(new PagerItem("第四个图片",R.mipmap.four));
    }
    private LYLooperPager.InnerAdapter mInnerAdapter=new LYLooperPager.InnerAdapter() {

        @Override
        protected int getDataSize() {
            return mData.size();
        }

        @Override
        protected View getSubView(ViewGroup container, int position) {
            ImageView iv=new ImageView(container.getContext());
            iv.setImageResource(mData.get(position).getPicResId());
            iv.setScaleType(ImageView.ScaleType.FIT_XY);


            return iv;
        }
    };

    private void initView() {
        mLooperPager = findViewById(R.id.Ly_looper_pager);
        mLooperPager.setData(mInnerAdapter, new LYLooperPager.BindTitleListener(){
            @Override
            public String getTitle(int position) {
                return mData.get(position).getTitle();
            }


        });
    }
}

shape_circle_red.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval"
    >
    <size android:width="5dp"
        android:height="5dp"/>
    <solid android:color="#ff0000"/>

</shape>

shape_circle_white.xml

 

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval"
    >
    <size android:width="5dp"
        android:height="5dp"/>
    <solid android:color="#ffffff"/>

</shape>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:Ly="http://schemas.android.com/apk/res-auto"
    tools:context=".MainActivity">


    <com.example.lunbo2.LuBo.LYLooperPager
        android:id="@+id/Ly_looper_pager"
        android:layout_width="match_parent"
        Ly:is_title_show="false"
        Ly:switch_time="4000"

        android:layout_height="120dp"/>



</RelativeLayout>

looper_pager_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipChildren="false"
    android:orientation="vertical"
    >

    <com.example.lunbo2.LuBo.LyViewPager
        android:id="@+id/looper_pager_vp"
        android:layout_marginLeft="40dp"
        android:layout_marginRight="40dp"
        android:clipChildren="false"
        android:layout_width="match_parent"
        android:layout_height="150dp" />

    <!--标题控件-->
    <TextView
        android:id="@+id/looper_title_tv"
        android:layout_width="match_parent"
        android:background="#66ffffff"
        android:layout_height="wrap_content"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:paddingTop="2dp"
        android:paddingBottom="2dp"
        android:gravity="center"
        android:text="这是标题内容..." />


    <!--用来放圆点-->
    <LinearLayout
        android:id="@+id/looper_point_container_lv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="5dp"
        android:orientation="horizontal" >

    </LinearLayout>


</RelativeLayout>

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="looper_style">
    <attr name="is_title_show"
        format="boolean"/>
    <!-- <attr name="show_pager_count"
         format="enum">
         <enum name="single" value="1"/>
         <enum name="multi" value="3"/>
     </attr>-->
    <attr name="switch_time" format="integer"/>

</declare-styleable>
</resources>

 

 

posted on 2020-08-19 12:52  沫戏回首  阅读(437)  评论(0编辑  收藏  举报

导航