|
Android example source code file (TouchPaint.java)
The TouchPaint.java Android example source code/* * Copyright (C) 2007 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.example.android.apis.graphics; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; //Need the following import to get access to the app resources, since this //class is in a sub-package. /** * Demonstrates the handling of touch screen and trackball events to * implement a simple painting app. */ public class TouchPaint extends GraphicsActivity { /** Used as a pulse to gradually fade the contents of the window. */ private static final int FADE_MSG = 1; /** Menu ID for the command to clear the window. */ private static final int CLEAR_ID = Menu.FIRST; /** Menu ID for the command to toggle fading. */ private static final int FADE_ID = Menu.FIRST+1; /** How often to fade the contents of the window (in ms). */ private static final int FADE_DELAY = 100; /** The view responsible for drawing the window. */ MyView mView; /** Is fading mode enabled? */ boolean mFading; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create and attach the view that is responsible for painting. mView = new MyView(this); setContentView(mView); mView.requestFocus(); // Restore the fading option if we are being thawed from a // previously saved state. Note that we are not currently remembering // the contents of the bitmap. mFading = savedInstanceState != null ? savedInstanceState.getBoolean("fading", true) : true; } @Override public boolean onCreateOptionsMenu(Menu menu) { menu.add(0, CLEAR_ID, 0, "Clear"); menu.add(0, FADE_ID, 0, "Fade").setCheckable(true); return super.onCreateOptionsMenu(menu); } @Override public boolean onPrepareOptionsMenu(Menu menu) { menu.findItem(FADE_ID).setChecked(mFading); return super.onPrepareOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case CLEAR_ID: mView.clear(); return true; case FADE_ID: mFading = !mFading; if (mFading) { startFading(); } else { stopFading(); } return true; default: return super.onOptionsItemSelected(item); } } @Override protected void onResume() { super.onResume(); // If fading mode is enabled, then as long as we are resumed we want // to run pulse to fade the contents. if (mFading) { startFading(); } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // Save away the fading state to restore if needed later. Note that // we do not currently save the contents of the display. outState.putBoolean("fading", mFading); } @Override protected void onPause() { super.onPause(); // Make sure to never run the fading pulse while we are paused or // stopped. stopFading(); } /** * Start up the pulse to fade the screen, clearing any existing pulse to * ensure that we don't have multiple pulses running at a time. */ void startFading() { mHandler.removeMessages(FADE_MSG); mHandler.sendMessageDelayed( mHandler.obtainMessage(FADE_MSG), FADE_DELAY); } /** * Stop the pulse to fade the screen. */ void stopFading() { mHandler.removeMessages(FADE_MSG); } private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { // Upon receiving the fade pulse, we have the view perform a // fade and then enqueue a new message to pulse at the desired // next time. case FADE_MSG: { mView.fade(); mHandler.sendMessageDelayed( mHandler.obtainMessage(FADE_MSG), FADE_DELAY); break; } default: super.handleMessage(msg); } } }; public class MyView extends View { private static final int FADE_ALPHA = 0x06; private static final int MAX_FADE_STEPS = 256/FADE_ALPHA + 4; private static final int TRACKBALL_SCALE = 10; private Bitmap mBitmap; private Canvas mCanvas; private final Rect mRect = new Rect(); private final Paint mPaint; private final Paint mFadePaint; private float mCurX; private float mCurY; private int mFadeSteps = MAX_FADE_STEPS; public MyView(Context c) { super(c); setFocusable(true); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setARGB(255, 255, 255, 255); mFadePaint = new Paint(); mFadePaint.setDither(true); mFadePaint.setARGB(FADE_ALPHA, 0, 0, 0); } public void clear() { if (mCanvas != null) { mPaint.setARGB(0xff, 0, 0, 0); mCanvas.drawPaint(mPaint); invalidate(); mFadeSteps = MAX_FADE_STEPS; } } public void fade() { if (mCanvas != null && mFadeSteps < MAX_FADE_STEPS) { mCanvas.drawPaint(mFadePaint); invalidate(); mFadeSteps++; } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { int curW = mBitmap != null ? mBitmap.getWidth() : 0; int curH = mBitmap != null ? mBitmap.getHeight() : 0; if (curW >= w && curH >= h) { return; } if (curW < w) curW = w; if (curH < h) curH = h; Bitmap newBitmap = Bitmap.createBitmap(curW, curH, Bitmap.Config.RGB_565); Canvas newCanvas = new Canvas(); newCanvas.setBitmap(newBitmap); if (mBitmap != null) { newCanvas.drawBitmap(mBitmap, 0, 0, null); } mBitmap = newBitmap; mCanvas = newCanvas; mFadeSteps = MAX_FADE_STEPS; } @Override protected void onDraw(Canvas canvas) { if (mBitmap != null) { canvas.drawBitmap(mBitmap, 0, 0, null); } } @Override public boolean onTrackballEvent(MotionEvent event) { int N = event.getHistorySize(); final float scaleX = event.getXPrecision() * TRACKBALL_SCALE; final float scaleY = event.getYPrecision() * TRACKBALL_SCALE; for (int i=0; i<N; i++) { //Log.i("TouchPaint", "Intermediate trackball #" + i // + ": x=" + event.getHistoricalX(i) // + ", y=" + event.getHistoricalY(i)); mCurX += event.getHistoricalX(i) * scaleX; mCurY += event.getHistoricalY(i) * scaleY; drawPoint(mCurX, mCurY, 1.0f, 16.0f); } //Log.i("TouchPaint", "Trackball: x=" + event.getX() // + ", y=" + event.getY()); mCurX += event.getX() * scaleX; mCurY += event.getY() * scaleY; drawPoint(mCurX, mCurY, 1.0f, 16.0f); return true; } @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getActionMasked(); if (action != MotionEvent.ACTION_UP && action != MotionEvent.ACTION_CANCEL) { int N = event.getHistorySize(); int P = event.getPointerCount(); for (int i = 0; i < N; i++) { for (int j = 0; j < P; j++) { mCurX = event.getHistoricalX(j, i); mCurY = event.getHistoricalY(j, i); drawPoint(mCurX, mCurY, event.getHistoricalPressure(j, i), event.getHistoricalTouchMajor(j, i)); } } for (int j = 0; j < P; j++) { mCurX = event.getX(j); mCurY = event.getY(j); drawPoint(mCurX, mCurY, event.getPressure(j), event.getTouchMajor(j)); } } return true; } private void drawPoint(float x, float y, float pressure, float width) { //Log.i("TouchPaint", "Drawing: " + x + "x" + y + " p=" // + pressure + " width=" + width); if (width < 1) width = 1; if (mBitmap != null) { float radius = width / 2; int pressureLevel = (int)(pressure * 255); mPaint.setARGB(pressureLevel, 255, 255, 255); mCanvas.drawCircle(x, y, radius, mPaint); mRect.set((int) (x - radius - 2), (int) (y - radius - 2), (int) (x + radius + 2), (int) (y + radius + 2)); invalidate(mRect); } mFadeSteps = 0; } } } Other Android examples (source code examples)Here is a short list of links related to this Android TouchPaint.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.