wloHolw 2015-08-29 16:55 采纳率: 0%
浏览 2755

android scrollview下的textview如何实现手势缩放并且可以长按出现上下文菜单

自己先自定义了一个scrollview,然后在xml相关的activity中写了一个ontouchevent,最后出现的结果是手势缩放与长按出现上下文菜单总不能同时实现!
代码如下:
自定义scrollview:
@Override
public boolean onInterceptTouchEvent( MotionEvent event)

{

        return super.onInterceptTouchEvent(event);

}

@Override
public boolean onTouchEvent(MotionEvent event)
{
    super.onTouchEvent(event);
    if(event.getPointerCount()==2)
    {
        return false;
    }
    else
    {
        return true;
    }
}
    与xml相关的activity
    手势缩放
    public boolean onTouchEvent(MotionEvent event) {
    int nCnt = event.getPointerCount();
    int n = event.getAction();
    if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN && 2 == nCnt)//2表示两个手指</span>
    {
        int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
        int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));
        nLenStart = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);
    }else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP  && 2 == nCnt)
    {
        int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
        int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));
        double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);
        DisplayMetrics dm = getResources().getDisplayMetrics();
        float value = dm.scaledDensity;
        if(nLenEnd > nLenStart)//通过两个手指开始距离和结束距离,来判断放大缩小
        {
            text.setTextSize((text.getTextSize()+(float)(0.1*(nLenEnd-nLenStart)))/value);
            Size=text.getTextSize();
            Toast.makeText(getApplicationContext(), "放大", 2000).show();
        }
        else
        {
            text.setTextSize((text.getTextSize()-(float)(0.1*(nLenStart-nLenEnd)))/value);
            Size=text.getTextSize();
            Toast.makeText(getApplicationContext(), "缩小",2000).show();
        }
    }
    return super.onTouchEvent(event);
            }
            出现上下文菜单:
            public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {

    if(v==text) {

        //v.getParent().requestDisallowInterceptTouchEvent(false);
        //if(menu.size()==0){
        menu.add(0, MENU_COPY, 0, "复制");
    }
    super.onCreateContextMenu(menu, v, menuInfo);
}

    出现的问题时,当自定义的onInterceptTouchEvent返回true时,缩放正常,没办法长按出上下文菜单,当其返回super.onInterceptTouchEvent(event)时,能出现上下文菜单,不能正常缩放!自己大概知道是什么问题,应该是手势拦截问题,又不是很清楚,希望各位大神能够指出问题,并能给个解决方案,或做过类似的demo可以给发一份,非常感谢!
  • 写回答

1条回答 默认 最新

  • 稀土掘金 2015-08-30 11:04
    关注

    分享一个以前做过的手势缩放 demo,希望对题主有帮助。给题主推荐一个技术干货的APP,里面有不少 Android 相关的学习资源,稀土掘金 http://gold.xitu.io/app

    主界面的activity:

     package test;
    import com.agehua.drag.R;
    
    import android.app.Activity; 
    import android.content.Context;
    import android.graphics.Bitmap; 
    import android.graphics.BitmapFactory; 
    import android.graphics.Matrix; 
    import android.graphics.PointF; 
    import android.hardware.SensorManager; 
    import android.os.Bundle; 
    import android.util.DisplayMetrics;
    import android.util.FloatMath; 
    import android.util.Log; 
    import android.view.MotionEvent; 
    import android.view.View; 
    import android.view.View.OnClickListener; 
    import android.view.View.OnTouchListener; 
    import android.widget.Button; 
    import android.widget.ImageView; 
    
    public class Touch extends Activity implements OnTouchListener, OnClickListener { 
        private static final String TAG = "Touch" ; 
    
        // These matrices will be used to move and zoom image 
        Matrix matrix = new Matrix(); 
        Matrix savedMatrix = new Matrix(); 
        PointF start = new PointF(); 
        PointF mid = new PointF(); 
        float  oldDist; 
        private ImageView view; 
        private MyScrollView scrollView;
        private Button zoomIn, zoomOut; 
        //button zoom 
        private float scaleWidth = 1; 
        private float scaleHeight = 1; 
        private Bitmap bmp, zoomedBMP; 
    
        private static final double ZOOM_IN_SCALE = 1.25;//放大系数 
        private static final double ZOOM_OUT_SCALE = 0.8;//缩小系数 
        // We can be in one of these 3 states 
        static final int NONE = 0; 
        static final int DRAG = 1; 
        static final int ZOOM = 2; 
        int mode = NONE; 
    
        int bmpWidth,bmpHeight;
        int imageHeight, imageWidth;
    
        @Override 
        public void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.main1); 
            view = (ImageView) findViewById(R.id.imageView); 
            view.setOnTouchListener(this); 
            scrollView = (MyScrollView)findViewById(R.id.scrollview);
    
            zoomIn = (Button)findViewById(R.id.btn_zoom_in);
            zoomOut = (Button)findViewById(R.id.btn_zoom_out);
            zoomOut.setOnClickListener(this);
            zoomIn.setOnClickListener(this);
            //取得drawable中图片,放大,缩小,多点触摸的作用对象 
            bmp = BitmapFactory.decodeResource(Touch.this.getResources(), R.drawable.aaa); 
            bmpWidth = bmp.getWidth(); 
            bmpHeight = bmp.getHeight(); 
        } 
    
    
        public boolean onTouch(View v, MotionEvent event) { 
            // Handle touch events here... 
            ImageView view = (ImageView) v; 
    
    //      imageWidth = v.getWidth();//屏幕宽度(像素数)
    //      imageHeight = v.getHeight();
    
            // Handle touch events here... 
            switch (event.getAction() & MotionEvent.ACTION_MASK) { 
            //设置拖拉模式 
            case MotionEvent.ACTION_DOWN: 
                savedMatrix.set(matrix); 
                start.set(event.getX(), event.getY()); 
                Log.d(TAG, "mode=DRAG" ); 
                mode = DRAG; 
                break; 
    
            case MotionEvent.ACTION_UP: 
            case MotionEvent.ACTION_POINTER_UP: 
                mode = NONE; 
                Log.d(TAG, "mode=NONE" ); 
                break; 
                //设置多点触摸模式 
            case MotionEvent.ACTION_POINTER_DOWN: 
                oldDist = spacing(event); 
                //          originalDist = oldDist;
                Log.d(TAG, "oldDist=" + oldDist); 
                if (oldDist > 10f) { 
                    savedMatrix.set(matrix); 
                    midPoint(mid, event); 
                    mode = ZOOM; 
                    Log.d(TAG, "mode=ZOOM" ); 
                } 
                break; 
                //若为DRAG模式,则点击移动图片 
            case MotionEvent.ACTION_MOVE: 
                if (mode == DRAG) { 
                    matrix.set(savedMatrix); 
                    // 设置位移 
                    matrix.postTranslate(event.getX() - start.x, 
                            event.getY() - start.y); 
                } 
                //若为ZOOM模式,则多点触摸缩放 
                else if (mode == ZOOM) { 
                    float newDist = spacing(event); 
                    Log.d(TAG, "newDist=" + newDist); 
                    if (newDist > 10f) { 
                        matrix.set(savedMatrix); 
                        float scale = newDist / oldDist; 
                        //设置缩放比例和图片中点位置 
                        matrix.postScale(scale, scale, mid.x, mid.y); 
                    } 
                } 
                break; 
            } 
    
            // Perform the transformation 
            view.setImageMatrix(matrix); 
    
            return true; // indicate event was handled 
        } 
    
    
    
        //计算移动距离 
        private float spacing(MotionEvent event) { 
            float x = event.getX(0) - event.getX(1); 
            float y = event.getY(0) - event.getY(1); 
            return FloatMath.sqrt(x * x + y * y); 
        } 
        //计算中点位置 
        private void midPoint(PointF point, MotionEvent event) { 
            float x = event.getX(0) + event.getX(1); 
            float y = event.getY(0) + event.getY(1); 
            point.set(x / 2, y / 2); 
        } 
    
        //放大,缩小按钮点击事件 
        @Override 
        public void onClick(View v) { 
            if(v == zoomIn){ 
                enlarge(); 
            }else if (v == zoomOut) { 
                small(); 
            } 
        } 
    
        //按钮点击缩小函数 
        private void small() { 
            int bmpWidth = bmp.getWidth(); 
            int bmpHeight = bmp.getHeight(); 
    
            scaleWidth = (float) (scaleWidth * ZOOM_OUT_SCALE); 
            scaleHeight = (float) (scaleHeight * ZOOM_OUT_SCALE); 
    
            Matrix matrix = new Matrix(); 
            matrix.postScale(scaleWidth, scaleHeight); 
            zoomedBMP = Bitmap.createBitmap(bmp, 0, 0, bmpWidth, bmpHeight, matrix, 
                    true); 
            view.setImageBitmap(zoomedBMP); 
        } 
    
        //按钮点击放大函数 
        private void enlarge() { 
            try { 
                int bmpWidth = bmp.getWidth(); 
                int bmpHeight = bmp.getHeight(); 
    
                scaleWidth = (float) (scaleWidth * ZOOM_IN_SCALE); 
                scaleHeight = (float) (scaleHeight * ZOOM_IN_SCALE); 
    
                Matrix matrix = new Matrix(); 
                matrix.postScale(scaleWidth, scaleHeight); 
                zoomedBMP = Bitmap.createBitmap(bmp, 0, 0, bmpWidth, bmpHeight, matrix, 
                        true); 
                view.setImageBitmap(zoomedBMP); //存在内存溢出问题
    
            } catch (Exception e) { 
                //can't zoom because of memory issue, just ignore, no big deal 
            } 
        }
    
        @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
            if (null != bmp && !bmp.isRecycled()) {
                bmp.recycle();
            }
            System.gc();
            super.onDestroy();
        } 
    
    
    }
    
    

    scrollview部分的代码:

     package test;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.GestureDetector;
    import android.view.GestureDetector.SimpleOnGestureListener;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.ScrollView;
    
    public class MyScrollView extends ScrollView {
        private boolean canScroll;
    
        private GestureDetector mGestureDetector;
        View.OnTouchListener mGestureListener;
    
        public MyScrollView(Context context, AttributeSet attrs) {
            super(context, attrs);
            mGestureDetector = new GestureDetector(context, new YScrollDetector());
            canScroll = true;
        }
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            if(ev.getAction() == MotionEvent.ACTION_UP)
                canScroll = true;
            return super.onInterceptTouchEvent(ev) && mGestureDetector.onTouchEvent(ev);
        }
    
        public class YScrollDetector extends SimpleOnGestureListener {
            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                if(canScroll)
                    if (Math.abs(distanceY) >= Math.abs(distanceX))
                        canScroll = true;
                    else
                        canScroll = false;
                return canScroll;
            }
        }
    }
    

    main1.xml内容为:

     <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center" 
        android:orientation="vertical">
    
        <test.MyScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center_horizontal"
            android:orientation="vertical" 
            android:layout_weight="1"
            android:id="@+id/scrollview">
    
            <ImageView
                android:id="@+id/imageView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:scaleType="matrix"
                android:src="@drawable/aaa" />
        </test.MyScrollView>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center_horizontal" >
    
            <Button
                android:id="@+id/btn_zoom_in"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="放大" />
    
            <Button
                android:id="@+id/btn_zoom_out"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="缩小" />
        </LinearLayout>
    
    </LinearLayout>
    

    注意问题:1.scrollview的layout_width属性最好设置为match_parent,如果设置为wrap_content,图片会滑动不到屏幕边界。
    2.imageview的scaleType属性一定要设置为matrix(矩阵模式),否则不能实现手势缩放。

                  3.不用按钮,直接手势放大缩放也基本能满足需求,这里只是作为方法记录下来。 
    

    希望能对题主解决问题有帮助。

    评论

报告相同问题?

悬赏问题

  • ¥15 maple软件,用solve求反函数出现rootof,怎么办?
  • ¥50 汇编语言除法溢出问题
  • ¥65 C++实现删除N个数据列表共有的元素
  • ¥15 Visual Studio问题
  • ¥15 state显示变量是字符串形式,但是仍然红色,无法引用,并显示类型不匹配
  • ¥20 求一个html代码,有偿
  • ¥100 关于使用MATLAB中copularnd函数的问题
  • ¥20 在虚拟机的pycharm上
  • ¥15 jupyterthemes 设置完毕后没有效果
  • ¥15 matlab图像高斯低通滤波