多点触控监听,改变文字的字体大小

多点触控,改变文字的字体大小

事件描述: 当放下多个手指的时候,记录第一次和第二次触摸屏幕的手指的距离;当这两个手指移动的时候,记录此时两个手指的新距离,新距离除旧距离的比例即为字体放大或者缩小的比例

重点

    重写OnTouchEvent() 方法,重写手指按下和移动的方法
      public boolean onTouchEvent(MotionEvent event) {


    switch (event.getActionMasked()) {

        case MotionEvent.ACTION_POINTER_DOWN:
            // 当手指按下的时候,就去获取当前手指的间距
            oldDist = spacing(event);
            break;
        case MotionEvent.ACTION_MOVE:
            // 获取当前触摸点的个数
            if (event.getPointerCount() >= 2) {
                // 如果触摸点>=2 获取当前两个手指的距离,然后进行缩放
                float newDist = spacing(event);
                zoom(newDist / oldDist);
                //重新置位
                oldDist = newDist;
            }
            break;
    }
    return true;
}

注意:

 // 获取触摸事件的类型,如果是单点是event.getAction(),当涉及到多点触控时,就使用getActionMasked来获取触摸事件类型

两种方式

* 一种为 直接将原来的大小乘以比例
* 另一种为 将 px转为sp
float scale = getResources().getDisplayMetrics().density;

    网上别人的代码 用于px和dp相互转换

    import android.content.Context;  

    public class DensityUtil {  

        /**
         * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
         */
        public static int dip2px(Context context, float dpValue) {
            final float scale = context.getResources().getDisplayMetrics().density;
            return (int) (dpValue * scale + 0.5f);
        }  

        /**
         * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
             */
    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }
    }
    //这个得到的不应该叫做密度,应该是密度的一个比例。不是真实的屏幕密度,而是相对于某个值的屏幕密度。
    //也可以说是相对密度
    /**
     * The logical density of the display. This is a scaling factor for the
     * Density Independent Pixel unit, where one DIP is one pixel on an
     * approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen),
     * providing the baseline of the system's display. Thus on a 160dpi
     * screen this density value will be 1; on a 120 dpi screen it would be
     * .75; etc.
     *
     * This value does not exactly follow the real screen size (as given by
     * xdpi and ydpi, but rather is used to scale the size of the overall UI
     * in steps based on gross changes in the display dpi. For example, a
     * 240x320 screen will have a density of 1 even if its width is
     * 1.8", 1.3", etc. However, if the screen resolution is increased to
     * 320x480 but the screen size remained 1.5"x2" then the density would
     * be increased (probably to 1.5).
     */

    /**
     * 显示器的逻辑密度,这是【独立的像素密度单位(首先明白dip是个单位)】的一个缩放因子,
     * 在屏幕密度大约为160dpi的屏幕上,一个dip等于一个px,这个提供了系统显示器的一个基线(这句我实在翻译不了)。
     * 例如:屏幕为240*320的手机屏幕,其尺寸为 1.5"*2"  也就是1.5英寸乘2英寸的屏幕
     * 它的dpi(屏幕像素密度,也就是每英寸的像素数,dpi是dot per inch的缩写)大约就为160dpi,
     * 所以在这个手机上dp和px的长度(可以说是长度,最起码从你的视觉感官上来说是这样的)是相等的。
     * 因此在一个屏幕密度为160dpi的手机屏幕上density的值为1,而在120dpi的手机上为0.75等等
     * (这里有一句话没翻译,实在读不通顺,不过通过下面的举例应该能看懂)
     * 例如:一个240*320的屏幕尽管他的屏幕尺寸为1.8"*1.3",(我算了下这个的dpi大约为180dpi多点)
     * 但是它的density还是1(也就是说取了近似值)
     * 然而,如果屏幕分辨率增加到320*480 但是屏幕尺寸仍然保持1.5"*2" 的时候(和最开始的例子比较)
     * 这个手机的density将会增加(可能会增加到1.5)
     */

计算公式

DisplayMetrics metric = new DisplayMetrics();
      getWindowManager().getDefaultDisplay().getMetrics(metric);

      int width = metric.widthPixels;  // 宽度(PX)
      int height = metric.heightPixels;  // 高度(PX)

      float density = metric.density;  // 密度(0.75 / 1.0 / 1.5)
      int densityDpi = metric.densityDpi;  // 密度DPI(120 / 160 / 240)

* 方式一

    package com.example.zoomtextview.view;
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.widget.TextView;

    public class ZoomTextView2 extends TextView {

    private float oldDistance;
    private float newDistance;
    float textSize = this.getTextSize();

    public ZoomTextView2(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public ZoomTextView2(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    public ZoomTextView2(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getActionMasked()) {
        case MotionEvent.ACTION_POINTER_DOWN:
            oldDistance = spacing(event);

            break;

        case MotionEvent.ACTION_MOVE:

            if (event.getPointerCount() >= 2) {
                newDistance = spacing(event);
                zoomTex(newDistance/oldDistance);
                oldDistance = newDistance;
            }

            break;

        default:
            break;
        }
        return true;
    }

    private void zoomTex(float f) {
        textSize *= f;
        this.setTextSize(px2sp(getContext(),textSize));
    }

    private int px2sp(Context context, float textSize2) {
        // TODO Auto-generated method stub
        float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (textSize2/scaledDensity);
    }

    /**
     * 两指之间距离
     * @param event
     * @return
     */
    private float spacing(MotionEvent event) {
        // TODO Auto-generated method stub

        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);

        return (float) Math.sqrt(x*x + y*y);
    }

    }
  • 方式二:

    package com.example.zoomtextview;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.util.FloatMath;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.widget.TextView;
    
    /**
     * Created by Administrator on 2016/8/31.
     */
    public class ZoomTextView extends TextView {
        private float textSize = this.getTextSize();
        private float oldDist;
    
        public ZoomTextView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public ZoomTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public ZoomTextView(Context context) {
            super(context);
        }
    
        /**
         * 处理TextView的触摸事件
         */
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            //在一开始,计算当前字体的大小
            /*if (textSize == 0) {
                textSize = this.getTextSize();
                Log.i("text", ""+this.getTextSize());
            }*/
            // 获取触摸事件的类型,如果是单点是event.getAction(),当涉及到多点触控时,就使用getActionMasked来获取触摸事件类型
            switch (event.getActionMasked()) {
    
                case MotionEvent.ACTION_POINTER_DOWN:
                    // 当手指按下的时候,就去获取当前手指的间距
                    oldDist = spacing(event);
                    break;
                case MotionEvent.ACTION_MOVE:
                    // 获取当前触摸点的个数
                    if (event.getPointerCount() >= 2) {
                        // 如果触摸点>=2 获取当前两个手指的距离,然后进行缩放
                        float newDist = spacing(event);
                        zoom(newDist / oldDist);
                        //重新置位
                        oldDist = newDist;
                    }
                    break;
            }
            return true;
        }
    
        /**
         * 不断进行缩放
         *
         * @param f
         */
        private void zoom(float f) {
            textSize *= f;
            this.setTextSize(px2sp(getContext(), textSize));
        }
    
        /**
         * 将px值转换为sp值,保证文字大小不变
         *
         * @param pxValue
         *            (DisplayMetrics类中属性scaledDensity)
         * @return
         */
        public static int px2sp(Context context, float pxValue) {
            float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
            return (int) (pxValue / fontScale + 0.5f);
        }
    
        /**
         * 计算两个手指的大小
         *
         * @param event
         * @return
         */
        private float spacing(MotionEvent event) {
            //获取第一个点的x坐标和第二个点的x坐标
            float x = event.getX(0) - event.getX(1);
            //分别获取y坐标
            float y = event.getY(0) - event.getY(1);
            //使用勾股定理计算两点距离
            return (float) Math.sqrt(x*x+y*y);
        }
        }
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值