原文:http://www.linuxidc.com/Linux/2011-10/44305.htm

PointerLocation多点触控代码在Android系统源码中的位置分别为:

android\development\apps\Development\src\com\android\development\PointerLocation.java

android\frameworks\base\core\java\com\android\internal\widget\PointerLocationView.java

PointerLocation.java

package com.ckl.PointerLocation;import android.app.Activity;
import android.os.Bundle;
import android.view.WindowManager;/*** Demonstrates wrapping a layout in a ScrollView.**/
public class PointerLocation extends Activity {@Overrideprotected void onCreate(Bundle icicle) {super.onCreate(icicle);setContentView(new PointerLocationView(this));// Make the screen full bright for this activity.WindowManager.LayoutParams lp = getWindow().getAttributes();lp.screenBrightness = 1.0f;getWindow().setAttributes(lp);}
}

PointerLocationView .java

/** Copyright (C) 2010 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package com.ckl.PointerLocation;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.FontMetricsInt;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;import java.util.ArrayList;public class PointerLocationView extends View {public static class PointerState {private final ArrayList<Float> mXs = new ArrayList<Float>();private final ArrayList<Float> mYs = new ArrayList<Float>();private boolean mCurDown;private int mCurX;private int mCurY;private float mCurPressure;private float mCurSize;private int mCurWidth;private VelocityTracker mVelocity;}private final ViewConfiguration mVC;private final Paint mTextPaint;private final Paint mTextBackgroundPaint;private final Paint mTextLevelPaint;private final Paint mPaint;private final Paint mTargetPaint;private final Paint mPathPaint;private final FontMetricsInt mTextMetrics = new FontMetricsInt();private int mHeaderBottom;private boolean mCurDown;private int mCurNumPointers;private int mMaxNumPointers;private final ArrayList<PointerState> mPointers= new ArrayList<PointerState>();private boolean mPrintCoords = true;public PointerLocationView(Context c) {super(c);setFocusable(true);mVC = ViewConfiguration.get(c);mTextPaint = new Paint();mTextPaint.setAntiAlias(true);mTextPaint.setTextSize(10* getResources().getDisplayMetrics().density);mTextPaint.setARGB(255, 0, 0, 0);mTextBackgroundPaint = new Paint();mTextBackgroundPaint.setAntiAlias(false);mTextBackgroundPaint.setARGB(128, 255, 255, 255);mTextLevelPaint = new Paint();mTextLevelPaint.setAntiAlias(false);mTextLevelPaint.setARGB(192, 255, 0, 0);mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setARGB(255, 255, 255, 255);mPaint.setStyle(Paint.Style.STROKE);mPaint.setStrokeWidth(2);mTargetPaint = new Paint();mTargetPaint.setAntiAlias(false);mTargetPaint.setARGB(255, 0, 0, 192);mPathPaint = new Paint();mPathPaint.setAntiAlias(false);mPathPaint.setARGB(255, 0, 96, 255);mPaint.setStyle(Paint.Style.STROKE);mPaint.setStrokeWidth(1);PointerState ps = new PointerState();ps.mVelocity = VelocityTracker.obtain();mPointers.add(ps);}public void setPrintCoords(boolean state) {mPrintCoords = state;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mTextPaint.getFontMetricsInt(mTextMetrics);mHeaderBottom = -mTextMetrics.ascent+mTextMetrics.descent+2;if (false) {Log.i("foo", "Metrics: ascent=" + mTextMetrics.ascent+ " descent=" + mTextMetrics.descent+ " leading=" + mTextMetrics.leading+ " top=" + mTextMetrics.top+ " bottom=" + mTextMetrics.bottom);}}@Overrideprotected void onDraw(Canvas canvas) {synchronized (mPointers) {final int w = getWidth();final int itemW = w/7;final int base = -mTextMetrics.ascent+1;final int bottom = mHeaderBottom;final int NP = mPointers.size();if (NP > 0) {final PointerState ps = mPointers.get(0);canvas.drawRect(0, 0, itemW-1, bottom,mTextBackgroundPaint);canvas.drawText("P: " + mCurNumPointers + " / " + mMaxNumPointers,1, base, mTextPaint);final int N = ps.mXs.size();if ((mCurDown && ps.mCurDown) || N == 0) {canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom, mTextBackgroundPaint);canvas.drawText("X: " + ps.mCurX, 1 + itemW, base, mTextPaint);canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1, bottom, mTextBackgroundPaint);canvas.drawText("Y: " + ps.mCurY, 1 + itemW * 2, base, mTextPaint);} else {float dx = ps.mXs.get(N-1) - ps.mXs.get(0);float dy = ps.mYs.get(N-1) - ps.mYs.get(0);canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom,Math.abs(dx) < mVC.getScaledTouchSlop()? mTextBackgroundPaint : mTextLevelPaint);canvas.drawText("dX: " + String.format("%.1f", dx), 1 + itemW, base, mTextPaint);canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1, bottom,Math.abs(dy) < mVC.getScaledTouchSlop()? mTextBackgroundPaint : mTextLevelPaint);canvas.drawText("dY: " + String.format("%.1f", dy), 1 + itemW * 2, base, mTextPaint);}canvas.drawRect(itemW * 3, 0, (itemW * 4) - 1, bottom, mTextBackgroundPaint);int velocity = ps.mVelocity == null ? 0 : (int) (ps.mVelocity.getXVelocity() * 1000);canvas.drawText("Xv: " + velocity, 1 + itemW * 3, base, mTextPaint);canvas.drawRect(itemW * 4, 0, (itemW * 5) - 1, bottom, mTextBackgroundPaint);velocity = ps.mVelocity == null ? 0 : (int) (ps.mVelocity.getYVelocity() * 1000);canvas.drawText("Yv: " + velocity, 1 + itemW * 4, base, mTextPaint);canvas.drawRect(itemW * 5, 0, (itemW * 6) - 1, bottom, mTextBackgroundPaint);canvas.drawRect(itemW * 5, 0, (itemW * 5) + (ps.mCurPressure * itemW) - 1,bottom, mTextLevelPaint);canvas.drawText("Prs: " + String.format("%.2f", ps.mCurPressure), 1 + itemW * 5,base, mTextPaint);canvas.drawRect(itemW * 6, 0, w, bottom, mTextBackgroundPaint);canvas.drawRect(itemW * 6, 0, (itemW * 6) + (ps.mCurSize * itemW) - 1,bottom, mTextLevelPaint);canvas.drawText("Size: " + String.format("%.2f", ps.mCurSize), 1 + itemW * 6,base, mTextPaint);}for (int p=0; p<NP; p++) {final PointerState ps = mPointers.get(p);if (mCurDown && ps.mCurDown) {canvas.drawLine(0, (int)ps.mCurY, getWidth(), (int)ps.mCurY, mTargetPaint);canvas.drawLine((int)ps.mCurX, 0, (int)ps.mCurX, getHeight(), mTargetPaint);int pressureLevel = (int)(ps.mCurPressure*255);mPaint.setARGB(255, pressureLevel, 128, 255-pressureLevel);canvas.drawPoint(ps.mCurX, ps.mCurY, mPaint);canvas.drawCircle(ps.mCurX, ps.mCurY, ps.mCurWidth, mPaint);}}for (int p=0; p<NP; p++) {final PointerState ps = mPointers.get(p);final int N = ps.mXs.size();float lastX=0, lastY=0;boolean haveLast = false;boolean drawn = false;mPaint.setARGB(255, 128, 255, 255);for (int i=0; i<N; i++) {float x = ps.mXs.get(i);float y = ps.mYs.get(i);if (Float.isNaN(x)) {haveLast = false;continue;}if (haveLast) {canvas.drawLine(lastX, lastY, x, y, mPathPaint);canvas.drawPoint(lastX, lastY, mPaint);drawn = true;}lastX = x;lastY = y;haveLast = true;}if (drawn) {if (ps.mVelocity != null) {mPaint.setARGB(255, 255, 64, 128);float xVel = ps.mVelocity.getXVelocity() * (1000/60);float yVel = ps.mVelocity.getYVelocity() * (1000/60);canvas.drawLine(lastX, lastY, lastX+xVel, lastY+yVel, mPaint);} else {canvas.drawPoint(lastX, lastY, mPaint);}}}}}public void addTouchEvent(MotionEvent event) {synchronized (mPointers) {int action = event.getAction();//Log.i("Pointer", "Motion: action=0x" + Integer.toHexString(action)//        + " pointers=" + event.getPointerCount());int NP = mPointers.size();//mRect.set(0, 0, getWidth(), mHeaderBottom+1);//invalidate(mRect);//if (mCurDown) {//    mRect.set(mCurX-mCurWidth-3, mCurY-mCurWidth-3,//            mCurX+mCurWidth+3, mCurY+mCurWidth+3);//} else {//    mRect.setEmpty();//}if (action == MotionEvent.ACTION_DOWN) {for (int p=0; p<NP; p++) {final PointerState ps = mPointers.get(p);ps.mXs.clear();ps.mYs.clear();ps.mVelocity = VelocityTracker.obtain();ps.mCurDown = false;}mPointers.get(0).mCurDown = true;mMaxNumPointers = 0;if (mPrintCoords) {Log.i("Pointer", "Pointer 1: DOWN");}}if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN) {final int index = (action&MotionEvent.ACTION_POINTER_INDEX_MASK)>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;final int id = event.getPointerId(index);while (NP <= id) {PointerState ps = new PointerState();ps.mVelocity = VelocityTracker.obtain();mPointers.add(ps);NP++;}final PointerState ps = mPointers.get(id);ps.mVelocity = VelocityTracker.obtain();ps.mCurDown = true;if (mPrintCoords) {Log.i("Pointer", "Pointer " + (id+1) + ": DOWN");}}final int NI = event.getPointerCount();mCurDown = action != MotionEvent.ACTION_UP&& action != MotionEvent.ACTION_CANCEL;mCurNumPointers = mCurDown ? NI : 0;if (mMaxNumPointers < mCurNumPointers) {mMaxNumPointers = mCurNumPointers;}for (int i=0; i<NI; i++) {final int id = event.getPointerId(i);final PointerState ps = mPointers.get(id);ps.mVelocity.addMovement(event);ps.mVelocity.computeCurrentVelocity(1);final int N = event.getHistorySize();for (int j=0; j<N; j++) {if (mPrintCoords) {Log.i("Pointer", "Pointer " + (id+1) + ": ("+ event.getHistoricalX(i, j)+ ", " + event.getHistoricalY(i, j) + ")"+ " Prs=" + event.getHistoricalPressure(i, j)+ " Size=" + event.getHistoricalSize(i, j));}ps.mXs.add(event.getHistoricalX(i, j));ps.mYs.add(event.getHistoricalY(i, j));}if (mPrintCoords) {Log.i("Pointer", "Pointer " + (id+1) + ": ("+ event.getX(i) + ", " + event.getY(i) + ")"+ " Prs=" + event.getPressure(i)+ " Size=" + event.getSize(i));}ps.mXs.add(event.getX(i));ps.mYs.add(event.getY(i));ps.mCurX = (int)event.getX(i);ps.mCurY = (int)event.getY(i);//Log.i("Pointer", "Pointer #" + p + ": (" + ps.mCurX//        + "," + ps.mCurY + ")");ps.mCurPressure = event.getPressure(i);ps.mCurSize = event.getSize(i);ps.mCurWidth = (int)(ps.mCurSize*(getWidth()/3));}if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP) {final int index = (action&MotionEvent.ACTION_POINTER_INDEX_MASK)>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;final int id = event.getPointerId(index);final PointerState ps = mPointers.get(id);ps.mXs.add(Float.NaN);ps.mYs.add(Float.NaN);ps.mCurDown = false;if (mPrintCoords) {Log.i("Pointer", "Pointer " + (id+1) + ": UP");}}if (action == MotionEvent.ACTION_UP) {for (int i=0; i<NI; i++) {final int id = event.getPointerId(i);final PointerState ps = mPointers.get(id);if (ps.mCurDown) {ps.mCurDown = false;if (mPrintCoords) {Log.i("Pointer", "Pointer " + (id+1) + ": UP");}}}}//if (mCurDown) {//    mRect.union(mCurX-mCurWidth-3, mCurY-mCurWidth-3,//            mCurX+mCurWidth+3, mCurY+mCurWidth+3);//}//invalidate(mRect);postInvalidate();}}@Overridepublic boolean onTouchEvent(MotionEvent event) {addTouchEvent(event);return true;}@Overridepublic boolean onTrackballEvent(MotionEvent event) {Log.i("Pointer", "Trackball: " + event);return super.onTrackballEvent(event);}} 

【Android】android系统多点触控源码相关推荐

  1. android 电容屏多点触控协议

    多点触控协议 为了发挥新近的多点触摸和多用户设备的强大功能,为多点触摸定义一种上报详细数据的方法(比如有多个物体直接接触到设备的表面),是非常有必要的.多点触摸协议(multi-touch,MT),是 ...

  2. 10_10_安卓加linux命令,Scrcpy 1.11版支持Android 10及多点触控手势,附Linux下安装命令...

    Scrcpy 1.11版本增加了对Android 10的支持及多点触控手势,现在就可以在Linux系统下安装Scrcpy的更新版本,该工具可让你在PC上镜像Android手机. 更新说明 Scrcpy ...

  3. Android中的多点触控(装载)

    Android多点触控技术 1 简介 Android多点触控在本质上需要LCD驱动和程序本身设计上支持,目前市面上HTC.Motorola和Samsung等知名厂商只要使用电容屏触控原理的手机均可以支 ...

  4. android RecyclerView禁止多点触控

    是这样,原本有一个功能,是用RecyclerView实现的,点击每个item都会弹出一个PopupWindow. 好的,用正常的方法实现就好.(注意点就是各个popupwindow的位置) 然后有一天 ...

  5. Android多点触控MultiTouch浅析

    申明: 参考:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2013/0226/914.html 下面实现如何通过应用层支持多点触控操作, ...

  6. Iwfu-安卓Gesture手势(2)-实现多点触控控制图片的放大缩小。

    上一篇介绍安卓Gesture手势初步使用,这一篇用Gesture来实现多点触控达到控制图片放大缩小. 上文中写道,进行手势监听的Activity要实现对应的OnGestureListener接口,重写 ...

  7. Android App接管手势处理TouchEvnet中单点触摸和多点触控的讲解及实战(附源码 超简单实用)

    运行有问题或需要源码请点赞关注收藏后评论区留言~~~ 一.单点触摸 dispatchTouchEvent onInterceptTouchEvent onTouchEvent三个方法的输入参数都是手势 ...

  8. Android多点触控详解

    本文转载自GcsSloop的 安卓自定义View进阶-多点触控详解 的文章 Android 多点触控详解,在前面的几篇文章中我们大致了解了 Android 中的事件处理流程和一些简单的处理方案,本次带 ...

  9. 关于android多点触控

    最近项目需要一个多点触控缩放的功能.然后上网查了下资料 总结一下: 首先android sdk版本很重要,比如你在AndroidManifest.xml中指定android:minSdkVersion ...

最新文章

  1. OpenCV(十五)边缘检测1 -- Sobel算子(一阶微分算子,X、Y方向边缘检测)
  2. 【leetcode 简单】第三十一题 买卖股票的最佳时机
  3. 设置Tomcat字符集为utf-8
  4. GitHub 上有哪些好用的爬虫?
  5. U盘容量减少的解决办法
  6. switch注意事项和细节讨论
  7. zuul 网关的用途_Zuul网关
  8. 关于Android studio3.0的坑之butterknife 7.0.1(低版本)
  9. 实战06_SSM整合ActiveMQ支持多种类型消息
  10. FastDfs工作笔记002---SpringBoot集成FastDfs
  11. PhoneGap在Microsoft Visual Studio Express For Wi...
  12. Android学习之Android 5.0分享动画实现微信点击全屏效果
  13. Failed to find Build Tools revision 25.0.2
  14. 概率论速成-基于mooc
  15. 2_linux-常用命令1
  16. 2016-09-01[关于Paint笔触的了解]
  17. ASCII码作用简介
  18. 面试题—Mybatis动态sql是什么意思?常用的标签有哪些和用途?
  19. 了解数据的发展历程--大数据简史
  20. 开放式可插拔规范 (OPS)

热门文章

  1. Java垃圾回收笔记
  2. docker-compose(二):SpringBoot + Docker Compose
  3. 统计学之三大相关性系数(pearson、spearman、kendall)matlab实现
  4. 怎么在Arcgis中提取多个坐标点的dem值(高程)
  5. ubuntu 20.04 安装obs 录屏软件
  6. 图仓库-图片记忆23种设计模式
  7. 如何成为一名优秀的程序员(六)
  8. js实现正则表达式匹配
  9. p16panda合并concat
  10. layui 输入框添加自定义图标