歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android開發:多點觸控測試代碼 PointerLocation

Android開發:多點觸控測試代碼 PointerLocation

日期:2017/3/1 11:16:57   编辑:Linux編程

PointerLocation這個多點觸控測試程序,在Android的源碼中有,只包括下面的兩個文件,

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

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

新建個工程,只要將這兩個文件拷貝出來,修改下包名,就可以運行起來,真好用。

本文工程源碼下載地址:

免費下載地址在 http://linux.linuxidc.com/

用戶名與密碼都是www.linuxidc.com

具體下載目錄在 /pub/Android源碼集錦/2011年/10月/Android開發:多點觸控測試代碼 PointerLocation/

PointerLocation.java

  1. package com.ckl.PointerLocation;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.view.WindowManager;
  5. /**
  6. * Demonstrates wrapping a layout in a ScrollView.
  7. *
  8. */
  9. public class PointerLocation extends Activity {
  10. @Override
  11. protected void onCreate(Bundle icicle) {
  12. super.onCreate(icicle);
  13. setContentView(new PointerLocationView(this));
  14. // Make the screen full bright for this activity.
  15. WindowManager.LayoutParams lp = getWindow().getAttributes();
  16. lp.screenBrightness = 1.0f;
  17. getWindow().setAttributes(lp);
  18. }
  19. }
PointerLocationView.java
  1. /*
  2. * Copyright (C) 2010 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.ckl.PointerLocation;
  17. import android.content.Context;
  18. import android.graphics.Canvas;
  19. import android.graphics.Paint;
  20. import android.graphics.Paint.FontMetricsInt;
  21. import android.util.Log;
  22. import android.view.MotionEvent;
  23. import android.view.VelocityTracker;
  24. import android.view.View;
  25. import android.view.ViewConfiguration;
  26. import java.util.ArrayList;
  27. public class PointerLocationView extends View {
  28. public static class PointerState {
  29. private final ArrayList<Float> mXs = new ArrayList<Float>();
  30. private final ArrayList<Float> mYs = new ArrayList<Float>();
  31. private boolean mCurDown;
  32. private int mCurX;
  33. private int mCurY;
  34. private float mCurPressure;
  35. private float mCurSize;
  36. private int mCurWidth;
  37. private VelocityTracker mVelocity;
  38. }
  39. private final ViewConfiguration mVC;
  40. private final Paint mTextPaint;
  41. private final Paint mTextBackgroundPaint;
  42. private final Paint mTextLevelPaint;
  43. private final Paint mPaint;
  44. private final Paint mTargetPaint;
  45. private final Paint mPathPaint;
  46. private final FontMetricsInt mTextMetrics = new FontMetricsInt();
  47. private int mHeaderBottom;
  48. private boolean mCurDown;
  49. private int mCurNumPointers;
  50. private int mMaxNumPointers;
  51. private final ArrayList<PointerState> mPointers
  52. = new ArrayList<PointerState>();
  53. private boolean mPrintCoords = true;
  54. public PointerLocationView(Context c) {
  55. super(c);
  56. setFocusable(true);
  57. mVC = ViewConfiguration.get(c);
  58. mTextPaint = new Paint();
  59. mTextPaint.setAntiAlias(true);
  60. mTextPaint.setTextSize(10
  61. * getResources().getDisplayMetrics().density);
  62. mTextPaint.setARGB(255, 0, 0, 0);
  63. mTextBackgroundPaint = new Paint();
  64. mTextBackgroundPaint.setAntiAlias(false);
  65. mTextBackgroundPaint.setARGB(128, 255, 255, 255);
  66. mTextLevelPaint = new Paint();
  67. mTextLevelPaint.setAntiAlias(false);
  68. mTextLevelPaint.setARGB(192, 255, 0, 0);
  69. mPaint = new Paint();
  70. mPaint.setAntiAlias(true);
  71. mPaint.setARGB(255, 255, 255, 255);
  72. mPaint.setStyle(Paint.Style.STROKE);
  73. mPaint.setStrokeWidth(2);
  74. mTargetPaint = new Paint();
  75. mTargetPaint.setAntiAlias(false);
  76. mTargetPaint.setARGB(255, 0, 0, 192);
  77. mPathPaint = new Paint();
  78. mPathPaint.setAntiAlias(false);
  79. mPathPaint.setARGB(255, 0, 96, 255);
  80. mPaint.setStyle(Paint.Style.STROKE);
  81. mPaint.setStrokeWidth(1);
  82. PointerState ps = new PointerState();
  83. ps.mVelocity = VelocityTracker.obtain();
  84. mPointers.add(ps);
  85. }
  86. public void setPrintCoords(boolean state) {
  87. mPrintCoords = state;
  88. }
  89. @Override
  90. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  91. super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  92. mTextPaint.getFontMetricsInt(mTextMetrics);
  93. mHeaderBottom = -mTextMetrics.ascent+mTextMetrics.descent+2;
  94. if (false) {
  95. Log.i("foo", "Metrics: ascent=" + mTextMetrics.ascent
  96. + " descent=" + mTextMetrics.descent
  97. + " leading=" + mTextMetrics.leading
  98. + " top=" + mTextMetrics.top
  99. + " bottom=" + mTextMetrics.bottom);
  100. }
  101. }
  102. @Override
  103. protected void onDraw(Canvas canvas) {
  104. synchronized (mPointers) {
  105. final int w = getWidth();
  106. final int itemW = w/7;
  107. final int base = -mTextMetrics.ascent+1;
  108. final int bottom = mHeaderBottom;
  109. final int NP = mPointers.size();
  110. if (NP > 0) {
  111. final PointerState ps = mPointers.get(0);
  112. canvas.drawRect(0, 0, itemW-1, bottom,mTextBackgroundPaint);
  113. canvas.drawText("P: " + mCurNumPointers + " / " + mMaxNumPointers,
  114. 1, base, mTextPaint);
  115. final int N = ps.mXs.size();
  116. if ((mCurDown && ps.mCurDown) || N == 0) {
  117. canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom, mTextBackgroundPaint);
  118. canvas.drawText("X: " + ps.mCurX, 1 + itemW, base, mTextPaint);
  119. canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1, bottom, mTextBackgroundPaint);
  120. canvas.drawText("Y: " + ps.mCurY, 1 + itemW * 2, base, mTextPaint);
  121. } else {
  122. float dx = ps.mXs.get(N-1) - ps.mXs.get(0);
  123. float dy = ps.mYs.get(N-1) - ps.mYs.get(0);
  124. canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom,
  125. Math.abs(dx) < mVC.getScaledTouchSlop()
  126. ? mTextBackgroundPaint : mTextLevelPaint);
  127. canvas.drawText("dX: " + String.format("%.1f", dx), 1 + itemW, base, mTextPaint);
  128. canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1, bottom,
  129. Math.abs(dy) < mVC.getScaledTouchSlop()
  130. ? mTextBackgroundPaint : mTextLevelPaint);
  131. canvas.drawText("dY: " + String.format("%.1f", dy), 1 + itemW * 2, base, mTextPaint);
  132. }
  133. canvas.drawRect(itemW * 3, 0, (itemW * 4) - 1, bottom, mTextBackgroundPaint);
  134. int velocity = ps.mVelocity == null ? 0 : (int) (ps.mVelocity.getXVelocity() * 1000);
  135. canvas.drawText("Xv: " + velocity, 1 + itemW * 3, base, mTextPaint);
  136. canvas.drawRect(itemW * 4, 0, (itemW * 5) - 1, bottom, mTextBackgroundPaint);
  137. velocity = ps.mVelocity == null ? 0 : (int) (ps.mVelocity.getYVelocity() * 1000);
  138. canvas.drawText("Yv: " + velocity, 1 + itemW * 4, base, mTextPaint);
  139. canvas.drawRect(itemW * 5, 0, (itemW * 6) - 1, bottom, mTextBackgroundPaint);
  140. canvas.drawRect(itemW * 5, 0, (itemW * 5) + (ps.mCurPressure * itemW) - 1,
  141. bottom, mTextLevelPaint);
  142. canvas.drawText("Prs: " + String.format("%.2f", ps.mCurPressure), 1 + itemW * 5,
  143. base, mTextPaint);
  144. canvas.drawRect(itemW * 6, 0, w, bottom, mTextBackgroundPaint);
  145. canvas.drawRect(itemW * 6, 0, (itemW * 6) + (ps.mCurSize * itemW) - 1,
  146. bottom, mTextLevelPaint);
  147. canvas.drawText("Size: " + String.format("%.2f", ps.mCurSize), 1 + itemW * 6,
  148. base, mTextPaint);
  149. }
  150. for (int p=0; p<NP; p++) {
  151. final PointerState ps = mPointers.get(p);
  152. if (mCurDown && ps.mCurDown) {
  153. canvas.drawLine(0, (int)ps.mCurY, getWidth(), (int)ps.mCurY, mTargetPaint);
  154. canvas.drawLine((int)ps.mCurX, 0, (int)ps.mCurX, getHeight(), mTargetPaint);
  155. int pressureLevel = (int)(ps.mCurPressure*255);
  156. mPaint.setARGB(255, pressureLevel, 128, 255-pressureLevel);
  157. canvas.drawPoint(ps.mCurX, ps.mCurY, mPaint);
  158. canvas.drawCircle(ps.mCurX, ps.mCurY, ps.mCurWidth, mPaint);
  159. }
  160. }
  161. for (int p=0; p<NP; p++) {
  162. final PointerState ps = mPointers.get(p);
  163. final int N = ps.mXs.size();
  164. float lastX=0, lastY=0;
  165. boolean haveLast = false;
  166. boolean drawn = false;
  167. mPaint.setARGB(255, 128, 255, 255);
  168. for (int i=0; i<N; i++) {
  169. float x = ps.mXs.get(i);
  170. float y = ps.mYs.get(i);
  171. if (Float.isNaN(x)) {
  172. haveLast = false;
  173. continue;
  174. }
  175. if (haveLast) {
  176. canvas.drawLine(lastX, lastY, x, y, mPathPaint);
  177. canvas.drawPoint(lastX, lastY, mPaint);
  178. drawn = true;
  179. }
  180. lastX = x;
  181. lastY = y;
  182. haveLast = true;
  183. }
  184. if (drawn) {
  185. if (ps.mVelocity != null) {
  186. mPaint.setARGB(255, 255, 64, 128);
  187. float xVel = ps.mVelocity.getXVelocity() * (1000/60);
  188. float yVel = ps.mVelocity.getYVelocity() * (1000/60);
  189. canvas.drawLine(lastX, lastY, lastX+xVel, lastY+yVel, mPaint);
  190. } else {
  191. canvas.drawPoint(lastX, lastY, mPaint);
  192. }
  193. }
  194. }
  195. }
  196. }
  197. public void addTouchEvent(MotionEvent event) {
  198. synchronized (mPointers) {
  199. int action = event.getAction();
  200. //Log.i("Pointer", "Motion: action=0x" + Integer.toHexString(action)
  201. // + " pointers=" + event.getPointerCount());
  202. int NP = mPointers.size();
  203. //mRect.set(0, 0, getWidth(), mHeaderBottom+1);
  204. //invalidate(mRect);
  205. //if (mCurDown) {
  206. // mRect.set(mCurX-mCurWidth-3, mCurY-mCurWidth-3,
  207. // mCurX+mCurWidth+3, mCurY+mCurWidth+3);
  208. //} else {
  209. // mRect.setEmpty();
  210. //}
  211. if (action == MotionEvent.ACTION_DOWN) {
  212. for (int p=0; p<NP; p++) {
  213. final PointerState ps = mPointers.get(p);
  214. ps.mXs.clear();
  215. ps.mYs.clear();
  216. ps.mVelocity = VelocityTracker.obtain();
  217. ps.mCurDown = false;
  218. }
  219. mPointers.get(0).mCurDown = true;
  220. mMaxNumPointers = 0;
  221. if (mPrintCoords) {
  222. Log.i("Pointer", "Pointer 1: DOWN");
  223. }
  224. }
  225. if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN) {
  226. final int index = (action&MotionEvent.ACTION_POINTER_INDEX_MASK)
  227. >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
  228. final int id = event.getPointerId(index);
  229. while (NP <= id) {
  230. PointerState ps = new PointerState();
  231. ps.mVelocity = VelocityTracker.obtain();
  232. mPointers.add(ps);
  233. NP++;
  234. }
  235. final PointerState ps = mPointers.get(id);
  236. ps.mVelocity = VelocityTracker.obtain();
  237. ps.mCurDown = true;
  238. if (mPrintCoords) {
  239. Log.i("Pointer", "Pointer " + (id+1) + ": DOWN");
  240. }
  241. }
  242. final int NI = event.getPointerCount();
  243. mCurDown = action != MotionEvent.ACTION_UP
  244. && action != MotionEvent.ACTION_CANCEL;
  245. mCurNumPointers = mCurDown ? NI : 0;
  246. if (mMaxNumPointers < mCurNumPointers) {
  247. mMaxNumPointers = mCurNumPointers;
  248. }
  249. for (int i=0; i<NI; i++) {
  250. final int id = event.getPointerId(i);
  251. final PointerState ps = mPointers.get(id);
  252. ps.mVelocity.addMovement(event);
  253. ps.mVelocity.computeCurrentVelocity(1);
  254. final int N = event.getHistorySize();
  255. for (int j=0; j<N; j++) {
  256. if (mPrintCoords) {
  257. Log.i("Pointer", "Pointer " + (id+1) + ": ("
  258. + event.getHistoricalX(i, j)
  259. + ", " + event.getHistoricalY(i, j) + ")"
  260. + " Prs=" + event.getHistoricalPressure(i, j)
  261. + " Size=" + event.getHistoricalSize(i, j));
  262. }
  263. ps.mXs.add(event.getHistoricalX(i, j));
  264. ps.mYs.add(event.getHistoricalY(i, j));
  265. }
  266. if (mPrintCoords) {
  267. Log.i("Pointer", "Pointer " + (id+1) + ": ("
  268. + event.getX(i) + ", " + event.getY(i) + ")"
  269. + " Prs=" + event.getPressure(i)
  270. + " Size=" + event.getSize(i));
  271. }
  272. ps.mXs.add(event.getX(i));
  273. ps.mYs.add(event.getY(i));
  274. ps.mCurX = (int)event.getX(i);
  275. ps.mCurY = (int)event.getY(i);
  276. //Log.i("Pointer", "Pointer #" + p + ": (" + ps.mCurX
  277. // + "," + ps.mCurY + ")");
  278. ps.mCurPressure = event.getPressure(i);
  279. ps.mCurSize = event.getSize(i);
  280. ps.mCurWidth = (int)(ps.mCurSize*(getWidth()/3));
  281. }
  282. if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP) {
  283. final int index = (action&MotionEvent.ACTION_POINTER_INDEX_MASK)
  284. >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
  285. final int id = event.getPointerId(index);
  286. final PointerState ps = mPointers.get(id);
  287. ps.mXs.add(Float.NaN);
  288. ps.mYs.add(Float.NaN);
  289. ps.mCurDown = false;
  290. if (mPrintCoords) {
  291. Log.i("Pointer", "Pointer " + (id+1) + ": UP");
  292. }
  293. }
  294. if (action == MotionEvent.ACTION_UP) {
  295. for (int i=0; i<NI; i++) {
  296. final int id = event.getPointerId(i);
  297. final PointerState ps = mPointers.get(id);
  298. if (ps.mCurDown) {
  299. ps.mCurDown = false;
  300. if (mPrintCoords) {
  301. Log.i("Pointer", "Pointer " + (id+1) + ": UP");
  302. }
  303. }
  304. }
  305. }
  306. //if (mCurDown) {
  307. // mRect.union(mCurX-mCurWidth-3, mCurY-mCurWidth-3,
  308. // mCurX+mCurWidth+3, mCurY+mCurWidth+3);
  309. //}
  310. //invalidate(mRect);
  311. postInvalidate();
  312. }
  313. }
  314. @Override
  315. public boolean onTouchEvent(MotionEvent event) {
  316. addTouchEvent(event);
  317. return true;
  318. }
  319. @Override
  320. public boolean onTrackballEvent(MotionEvent event) {
  321. Log.i("Pointer", "Trackball: " + event);
  322. return super.onTrackballEvent(event);
  323. }
  324. }
Copyright © Linux教程網 All Rights Reserved