自定义使用Adapter的组件(二)

上篇只实现了效果但是图片不能随手势滑动,要想实现这个效果,需要实现接口GestureDetector.OnGestureListener。

实现GestureDetector.OnGestureListener接口需要实现以下方法

  • onDown
  • onShowPress
  • onSingleTapUp
  • onScroll
  • onLongPress
  • onFling
在这个组件中,我们只需要实现onDown、onScroll就可以了,onDown返回true时才会响应触屏手势事件。onScroll中实现图片的滑动。
接下来,我们说下图片随手势滑动的 原理其实,不是图片滑动,是组件在滑动,屏幕沿X轴运动,看起来就像图片在随着手势滑动。
接下来,我们看下代码:
public class ImageWallView extends AdapterView<ListAdapter> implements GestureDetector.OnGestureListener{ private ListAdapter mAdapter; private GestureDetector gestureDetector; //监听屏幕事件 private float offset=0; // 相对于(0,0)点水平方向滑动的距离 private int unitWidth; //每个单元的宽 private int numColumns; //屏幕展示的孩子的数目 /** * 构造方法 */ public ImageWallView(Context context) { super(context); init(); } public ImageWallView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public ImageWallView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init(){ gestureDetector = new GestureDetector(this.getContext(),this); gestureDetector.setIsLongpressEnabled(true); //监听长按事件 } /** * 继承AdapterView需要实现以下四个方法 * getAdapter() * setAdapter(ListAdapter adapter) * getSelectedView() * setSelection(int position) */ @Override public ListAdapter getAdapter() { return mAdapter; } @Override public void setAdapter(ListAdapter adapter) { this.mAdapter = adapter; //把所有的child添加到布局中 for(int i=0;i<mAdapter.getCount();i++){ View child = mAdapter.getView(i,null,this); addViewInLayout(child,i,child.getLayoutParams()); } } @Override public View getSelectedView() { return null; } @Override public void setSelection(int position) { } /** * 实现GestureDetector.OnGestureListener接口需要实现以下方法 * onDown //响应触屏事件 这个必须返回true * onShowPress * onSingleTapUp * onScroll * onLongPress * onFling */ public boolean onDown(MotionEvent e) { return true; } public void onShowPress(MotionEvent e) { } /** * 单击松开时响应 */ public boolean onSingleTapUp(MotionEvent e) { return false; } /** * 图片顺手势滑动 * @param distanceX 往右滑动是负值 往左滑动是正值 */ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { offset = offset- distanceX; //确保不滑出界 if(offset>0){ offset=0; } else if(offset < (getChildCount()-numColumns)*unitWidth*-1) { offset = (getChildCount()-numColumns)*unitWidth*-1; } //重绘布局 requestLayout(); return true; } public void onLongPress(MotionEvent e) { } public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {; return true; } /** * 设置布局 */ @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { int childCount = getChildCount(); int pLeft = 0; int pTop = 0; int childWidth=0; int childHeight=0; if(childCount>0){ View child = getChildAt(0); LayoutParams p = child.getLayoutParams(); childWidth = p.width + child.getPaddingLeft() + child.getPaddingRight() ; // child 的宽 childHeight = p.height + child.getPaddingTop() + child.getPaddingBottom(); // child 的高 numColumns = (getMeasuredWidth() - getPaddingLeft() - getPaddingRight())/childWidth; //计算屏幕中可以放置几个child int spacing = (getMeasuredWidth() - getPaddingLeft() - getPaddingRight() - numColumns * childWidth)/numColumns; //计算child之间的平均空隙 int spacingLR = (getPaddingLeft() + getPaddingRight() )/2;//组件左右边的平均空隙 if(spacing > spacingLR){ int outSpacing = spacing - spacingLR; setPadding(spacingLR+outSpacing,getPaddingTop(),spacingLR+outSpacing,getPaddingBottom()); } unitWidth = childWidth + spacing ; } for(int i=0;i<childCount;i++){ View child = getChildAt(i); pLeft = getPaddingLeft() + i * unitWidth+(int)offset; //child距离左端的距离 pTop = getPaddingTop(); //child距离顶端的距离 child.layout(pLeft,pTop,pLeft + childWidth,pTop + childHeight); } } /** * 设置大小 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //设置宽度和高度 setMeasuredDimension( getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec), getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec) ); } /** * 响应触屏事件 */ @Override public boolean onTouchEvent(MotionEvent event) { if(mAdapter == null){ return true; } boolean touchValue = gestureDetector.onTouchEvent(event); if(event.getAction() == MotionEvent.ACTION_UP ){ //在手指抬起时调用onUp方法 onUp(); } return touchValue; } /** * 实现屏幕只显示整章的商品图片 */ private void onUp(){ int index = (int) (Math.abs(offset) / unitWidth); index += (Math.abs(offset) - index*unitWidth) > unitWidth/2 ? 1:0; offset = offset>0? index*unitWidth : -1*index*unitWidth; requestLayout(); } }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值