自定义view,实现轮播图及点击事件
一、效果:手动轮播、自动轮播皆可。
二、设计思路:
1、自定义view,继承viewGroup类
2、求出子视图的个数,子视图高度,子视图宽度。假设轮播图的每一张图片大小相等根据第一个子视图的宽度和子视图的个数求出并设置viewGroup的宽高。
3、在onLayout方法中动态设置viewGroup的布局(绘制)。
4、事件设置:让onInterceptTouchEvent返回true,让onTouchEvent来处理事件,按下、移动、抬起需要做的事情。
5、使用Scroller来完成自动轮播。(当按下没有移动时停止自动轮播,抬起是重新开始轮播)。
6、通过一个接口实现单击事件和参数传递(用一个布尔变量表示是否是单击事件在按下时设置为true,移动时设置为false,在抬起时判断是否需要处理单击事件)。
三、代码
自定义的ViewGroup:
package com.me.androidstudy2.view; import android.annotation.SuppressLint; import android.content.Context; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.Scroller; import androidx.annotation.NonNull; import com.me.androidstudy2.jk.ImgViewGroupLister; import java.util.Timer; import java.util.TimerTask; public class ImgViewGroup extends ViewGroup { private int child; //子视图个数 private int childWidth; // 子视图宽 private int childHeight; //子视图高 private int x; private int index = 0; private Scroller scroller; private Timer timer = new Timer(); private TimerTask timerTask ; private boolean isAtuo = true; //默认开启自动轮播 private ImgViewGroupLister lister ; private boolean isClick; public ImgViewGroupLister getLister() { return lister; } public void setLister(ImgViewGroupLister lister) { this.lister = lister; } @SuppressLint("HandlerLeak") private Handler handler = new Handler(){ @Override public void handleMessage(@NonNull Message msg) { super.handleMessage(msg); switch (msg.what){ case 0: if (++index >= child ){ //到达最后一张图时,从初开始 index = 0; } scrollTo(childWidth * index,0); break; } } }; public ImgViewGroup(Context context) { super(context); InitObj(); } public ImgViewGroup(Context context, AttributeSet attrs) { super(context, attrs); InitObj(); } public ImgViewGroup(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); InitObj(); } public void InitObj(){ scroller = new Scroller(getContext()); timerTask = new TimerTask() { @Override public void run() { if(isAtuo){ handler.sendEmptyMessage(0); } } }; timer.schedule(timerTask,100,2000); } @Override public void computeScroll() { super.computeScroll(); if (scroller.computeScrollOffset()){ scrollTo(scroller.getCurrX(),0); invalidate(); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //1、求出子视图的个数 child = getChildCount(); if (child == 0){ setMeasuredDimension(0,0); }else{ measureChildren(widthMeasureSpec,heightMeasureSpec); View view = getChildAt(0); childHeight = view.getMeasuredHeight(); childWidth = view.getMeasuredWidth(); int width = childWidth * child; int height = childHeight; //设置viewGroup的高度和宽度 setMeasuredDimension(width,height); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { if (changed){ int left = 0; for (int i = 0; i < child; i++) { View view = getChildAt(i); view.layout(left, 0, left+childWidth, childHeight); left += childWidth; } } } /** * 事件的传递 * 事件拦截 : */ @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return true; } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: //按下 isAtuo = false; if (!scroller.isFinished()){ scroller.abortAnimation(); } x = (int) event.getX(); isClick = true; break; case MotionEvent.ACTION_MOVE: //移动 int moveX = (int) event.getX(); int d = moveX - x; scrollBy(-d,0); x = moveX; isClick = false; break; case MotionEvent.ACTION_UP: //抬起 int scrollX = getScrollX(); index = (scrollX + childWidth / 2) /childWidth; //求下标,四舍五入 Log.e("xw",index + ""); if(index < 0){ //最左边 index = 0; }else if(index > child - 1){ //最右边 index = child - 1; } if (isClick){ lister.clickImg("http://u" + index + ".php"); }else{ // scrollTo(index * childWidth,0); int dx = index * childWidth -scrollX; scroller.startScroll(scrollX,0,dx,0); postInvalidate(); } isAtuo = true; break; default: break; } return true; } }
单击事件的接口:
package com.me.androidstudy2.jk; public interface ImgViewGroupLister { void clickImg(String url); }
active:
package com.me.androidstudy2; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.widget.ImageView; import android.widget.Toast; import com.me.androidstudy2.jk.ImgViewGroupLister; import com.me.androidstudy2.view.ImgViewGroup; public class MainActivity extends AppCompatActivity implements ImgViewGroupLister { private ImgViewGroup imgViewGroup ; public void initView(){ imgViewGroup = findViewById(R.id.img_view_group); } public void action(){ imgViewGroup.setLister(this); int [] ids = new int[] { R.drawable.xw7, R.drawable.xw4, R.drawable.xw2 }; for (int i = 0; i < ids.length; i++) { ImageView img = new ImageView(this); img.setBackgroundResource(ids[i]); imgViewGroup.addView(img); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); action(); } @Override public void clickImg(String url) { Toast.makeText(this,"url = " + url,Toast.LENGTH_SHORT).show(); } }