• android ListView 可缩放,支持左右上下手势


    public class ZoomListView extends ListView implements SwipeListener {
        
        public static enum Action {
            LeftToRight, 
            RightToLeft, 
            TopToBottom, 
            BottomToTop, 
            None
        }
        
        private List<SwipeListener> actionListeners = new ArrayList<SwipeListener>();
        private boolean SwipeFlag = false;
        
        private static final int HORIZONTAL_MIN_DISTANCE = 30; // The minimum
        private static final int VERTICAL_MIN_DISTANCE = 80; // The minimum distance
        private float downX, downY, upX, upY; // Coordinates
        
        private static final int INVALID_POINTER_ID = -1;
        private int mActivePointerId = INVALID_POINTER_ID;
        private ScaleGestureDetector mScaleDetector;
    
        private float mScaleFactor = 1.f;
        private float maxWidth = 0.0f;
        private float maxHeight = 0.0f;
        private float mLastTouchX;
        private float mLastTouchY;
        private float mPosX;
        private float mPosY;
        private float width;
        private float height;
    
    
        public ZoomListView(Context context) {
            super(context);
            mScaleDetector = new ScaleGestureDetector(getContext(), new ScaleListener());
        }
    
        public ZoomListView(Context context, AttributeSet attrs) {
            super(context, attrs);
            mScaleDetector = new ScaleGestureDetector(getContext(), new ScaleListener());
        }
    
        public ZoomListView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            mScaleDetector = new ScaleGestureDetector(getContext(), new ScaleListener());
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            width = MeasureSpec.getSize(widthMeasureSpec);
            height = MeasureSpec.getSize(heightMeasureSpec);
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    
        @Override
        public boolean onTouchEvent(@NonNull MotionEvent ev) {
            super.onTouchEvent(ev);
            final int action = ev.getAction();
            mScaleDetector.onTouchEvent(ev);
            switch (action & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN: {
                    final float x = ev.getX();
                    final float y = ev.getY();
    
                    mLastTouchX = x;
                    mLastTouchY = y;
    
                    mActivePointerId = ev.getPointerId(0);
                    
                    downX = ev.getX();
                    downY = ev.getY();
                    
                    SwipeFlag = true;
                    
                    break;
                }
    
                case MotionEvent.ACTION_MOVE: {
                    final int pointerIndex = ev.findPointerIndex(mActivePointerId);
                    final float x = ev.getX(pointerIndex);
                    final float y = ev.getY(pointerIndex);
                    final float dx = x - mLastTouchX;
                    final float dy = y - mLastTouchY;
    
                    float leftMargin = Math.abs(mPosX) / mScaleFactor;
                    float rightMargin = this.getMeasuredWidth() - Math.abs(mPosX) / mScaleFactor;
                    rightMargin -= this.getResources().getDisplayMetrics().widthPixels / mScaleFactor ;
                    
                    mPosX += dx;
                    mPosY += dy;
                    
                    if (mPosX > 0.0f)
                        mPosX = 0.0f;
                    else if (mPosX < maxWidth)
                        mPosX = maxWidth;
                    
                    if (mPosY > 0.0f)
                        mPosY = 0.0f;
                    else if (mPosY < maxHeight)
                        mPosY = maxHeight;
    
                    mLastTouchX = x;
                    mLastTouchY = y;
    
                    invalidate();
                    
                    upX = ev.getX();
                    upY = ev.getY();
                    
                    float deltaX = downX - upX;
                    float deltaY = downY - upY;
                    // horizontal swipe detection
                    if (Math.abs(deltaX) > HORIZONTAL_MIN_DISTANCE) {
                        // left or right
                        if (deltaX < 0 && SwipeFlag && leftMargin < 10) {
                            SwipeFlag = false;
                            OnAction(Action.LeftToRight);
                            break;
                        }
                        if (deltaX > 0 && SwipeFlag && rightMargin < 10) {
                            SwipeFlag = false;
                            OnAction(Action.RightToLeft);
                            break;
                        }
                    } else
                    {
                        // vertical swipe detection
                        if (Math.abs(deltaY) > VERTICAL_MIN_DISTANCE) {
                            // top or down
                            if (deltaY < 0 && SwipeFlag) {
                                SwipeFlag = false;
                                OnAction(Action.TopToBottom);
                                break;
                            }
                            if (deltaY > 0 && SwipeFlag) {
                                SwipeFlag = false;
                                OnAction(Action.BottomToTop);
                                break;
                            }
                        }
                    }
                    
                    break;
                }
    
                case MotionEvent.ACTION_UP: {
                    mActivePointerId = INVALID_POINTER_ID;
                    break;
                }
    
                case MotionEvent.ACTION_CANCEL: {
                    mActivePointerId = INVALID_POINTER_ID;
                    break;
                }
    
                case MotionEvent.ACTION_POINTER_UP: {
                    final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
                    final int pointerId = ev.getPointerId(pointerIndex);
                    if (pointerId == mActivePointerId) {
                        final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                        mLastTouchX = ev.getX(newPointerIndex);
                        mLastTouchY = ev.getY(newPointerIndex);
                        mActivePointerId = ev.getPointerId(newPointerIndex);
                    }
                    break;
                }
            }
    
            return true;
        }
    
        @Override
        public void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.save(Canvas.MATRIX_SAVE_FLAG);
            canvas.translate(mPosX, mPosY);
            canvas.scale(mScaleFactor, mScaleFactor);
            canvas.restore();
        }
    
        @Override
        protected void dispatchDraw(@NonNull Canvas canvas) {
            canvas.save(Canvas.MATRIX_SAVE_FLAG);
            if (mScaleFactor == 1.0f) {
                mPosX = 0.0f;
                mPosY = 0.0f;
            }
            canvas.translate(mPosX, mPosY);
            canvas.scale(mScaleFactor, mScaleFactor);
            super.dispatchDraw(canvas);
            canvas.restore();
            invalidate();
        }
    
        private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
            @Override
            public boolean onScale(ScaleGestureDetector detector) {
                mScaleFactor *= detector.getScaleFactor();
                mScaleFactor = Math.max(1.0f, Math.min(mScaleFactor, 3.0f));
                maxWidth = width - (width * mScaleFactor);
                maxHeight = height - (height * mScaleFactor);
                invalidate();
                return true;
            }
        }
        
        @Override
        public void OnAction(Action action) {
            for(SwipeListener listener : actionListeners){
                listener.OnAction(action);
            }
        }
        
        public void addActionListener(SwipeListener listener)
        {
            actionListeners.add(listener);
        }
    }
    public interface SwipeListener extends EventListener {
        public void OnAction(Action action);
    }

     如果想ListView中显示图片且自适应,需要设置 android:adjustViewBounds="true"

  • 相关阅读:
    多任务并行
    不同方法来移动数据库(更改磁盘时用)(转)
    ASP.NET执行SQL超时的解决方案
    SQL Server 简单模式下,误删除堆表记录如何恢复(绕过页眉校验) (转)
    关于跟踪标记
    .NET分布式事务处理
    安装SQL Server 2005时出现COM+的警告/错误,下面是微软给出的解决方法。
    PHP中如何获取多个checkbox的值
    C# 模拟post数据提交时 出现如下错误: System.Net.WebException: 远程服务器返回错误: (417) Expectation Failed 的解决办法
    winform出现"LC.exe"已退出,代码为1
  • 原文地址:https://www.cnblogs.com/nanfei/p/8675813.html
Copyright © 2020-2023  润新知