1. 程式人生 > 實用技巧 >輪播圖的組合控制元件、自定義屬性、自動輪播

輪播圖的組合控制元件、自定義屬性、自動輪播

  昨天到今天寫的是輪播的自動播放、無限迴圈、點選事件、也可以自己滑動。

  這個輪播圖是進行過封裝的,把一些簡單的資料設定頁面互動去提取出來。讓以後用的時候直接可以用。

  自動播放的話可以通過自定義屬性來進行時間延遲設定。點選事件只是寫了一個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>