adapterView实现GestureDetector.OnGestureListener来左右滑动!!!!
来源:互联网 发布:jsw windows x86 64 编辑:程序博客网 时间:2024/06/16 09:55
自定义使用Adapter的组件(一)
这次,我要实现个类似京东商城android客户端上商品图片展示的组件,如下图展示爱疯4的组件,注意,不包含小箭头。【由于不方便上传图片,就只能使用网上图片了】
首先,我先实现上图的效果,要实现这种组件就必须继承AdapterView<ListAdapter>,实现构造方法、onMeasure()、onLayout()、setAdapter()方法。看代码:
- public class ImageWallView extends AdapterView<ListAdapter>{
- private ListAdapter mAdapter;
- private int unitWidth; //每个child的宽
- private int numColumns; //屏幕展示的孩子的数目
- /**
- * 构造方法
- */
- public ImageWallView(Context context) {
- super(context);
- }
- public ImageWallView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public ImageWallView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
- /**
- * 继承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) { }
- /**
- * 设置布局
- */
- @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() ; //组件的宽度
- childHeight = p.height + child.getPaddingTop() + child.getPaddingBottom(); //组件的高度
- 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() 获取参数两个值中较大的那个
- getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec)
- );
- }
- }
onMeasure() 中设置了组件的大小
onLayout() 中设置了传进来的ListAdapter内容怎样在组件中分布
setAdapter() 中把ListAdapter的内容加入组件中
使用:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:demo="http://schemas.android.com/apk/res/com.wxg.activity"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <com.wxg.view.ImageWallView
- android:layout_width="fill_parent"
- android:layout_height="100dp"
- android:paddingLeft="10dp"
- android:paddingTop="5dp"
- android:paddingRight="10dp"
- android:id="@+id/imageWallView"
- android:background="#ffffff"
- />
- <TextView
- android:layout_height="fill_parent"
- android:layout_width="fill_parent"
- android:gravity="center"
- android:text="图片墙组件"
- android:textColor="#ffffff"
- android:textSize="25sp"/>
- </LinearLayout>
有个地方需要注意,使用组件时要自定义Adapter,不能使用系统自带的Adapter。
这样,就可以实现想要的样式了,但是现在图片还不能随着手势滑动,在下篇中会实现随手势滑动。自定义使用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();
- }
- }
- adapterView实现GestureDetector.OnGestureListener来左右滑动!!!!
- 使用GestureDetector实现手指左右滑动检测
- Android之OnGestureListener实现图片的左右滑动
- 【Android】滑动屏幕效果GestureDetector、OnGestureListener、ViewFlipper
- 滑动屏幕效果GestureDetector、OnGestureListener、ViewFlipper
- Android滑动屏幕效果GestureDetector、OnGestureListener、ViewFlipper
- 【Android】滑动屏幕效果GestureDetector、OnGestureListener、ViewFlipper
- 【Android】滑动屏幕效果GestureDetector、OnGestureListener、ViewFlipper
- 【Android】滑动屏幕效果GestureDetector、OnGestureListener、ViewFlipper
- Android手势滑动GestureDetector和OnGestureListener(二)
- Android手势滑动GestureDetector和OnGestureListener(一)
- Android 滑动屏幕效果GestureDetector、OnGestureListener、ViewFlipper
- 【Android】滑动屏幕效果GestureDetector、OnGestureListener、ViewFlipper
- GestureDetector的实现 (GestureDetector.OnDoubleTapListener GestureDetector.OnGestureListener)
- GestureDetector.OnGestureListener
- GestureDetector.OnGestureListener
- android - GestureDetector 实现界面左右滑动效果的优化
- 通过GestureDetector来实现左右滑屏事件
- 使用欧几里德距离构建简单的推荐系统计算用户相似度
- 探索ORACLE之ASM04_维护
- 《Oracle编程艺术》学习笔记(18)-REDO和UNDO
- 关于字符编码(linux终端显示中文)
- 利用Compass实现一个简单的搜索引擎
- adapterView实现GestureDetector.OnGestureListener来左右滑动!!!!
- ORACLE REDO--《深入浅出ORACLE第六章》
- INSERT C语言中,一个有序数组插入另一个无序数组,求插入次数。
- applicationContext.xml 配置说明
- 中断与函数调用的区别
- C++本地化得到语言代号,例如zh-cn,en-us
- Android Activity概要
- asp.net app_code
- Java线程:创建与启动