自定义使用Adapter的组件(二)
来源:互联网 发布:大数据项目视频 编辑:程序博客网 时间:2024/05/05 19:38
上篇只实现了效果但是图片不能随手势滑动,要想实现这个效果,需要实现接口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(); }}
- 自定义使用Adapter的组件(二)
- 自定义使用Adapter的组件(一)
- Android中使用自定义Adapter(二)
- Android中使用自定义Adapter(二)
- 自定义Adapter的使用
- 自定义ListView使用的Adapter
- spinner使用自定义的Adapter
- android使用自定义的adapter
- listview自定义adapter的使用
- 自定义组件(二)------使用系统控件组合的自定义控件
- 自定义组件(二)
- 自定义组件(二)
- Android 自定义adapter(二)
- 自定义组件(二)------使用系统控件组合的自定义控件之二
- SimpleAdapter与自定义Adapter的使用。
- Android学习笔记--自定义Adapter的使用
- android自定义adapter和bundle的使用
- 使用自定义Adapter的ListView优化方式
- #ifndef __K9F2G08U0A_H__
- iframe IE FF高度自适应
- 将Qt集成到VS2008环境中(windows)
- s60各版本
- 柠檬汁的人生观-李嘉诚
- 自定义使用Adapter的组件(二)
- 顶部导航
- Filter(过滤器)
- android 动态设置全屏
- 贱人是怎样炼成的
- adb logcat 查看日志
- 分享贪吃蛇游戏源码
- 虚拟机RAC的ASM磁盘组坏块导致重建DB
- 添加文件到Sdcard出现Failed to push selection: Invalid argument问题