轮播图的组合控件、自定义属性、自动轮播
昨天到今天写的是轮播的自动播放、无限循环、点击事件、也可以自己滑动。
这个轮播图是进行过封装的,把一些简单的数据设置页面交互去提取出来。让以后用的时候直接可以用。
自动播放的话可以通过自定义属性来进行时间延迟设置。点击事件只是写了一个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>