1 /* 2 * Copyright (C) 2016 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 17 package com.example.android.apis.view; 18 19 import android.content.Context; 20 import android.graphics.Bitmap; 21 import android.graphics.Canvas; 22 import android.graphics.Paint; 23 import android.util.AttributeSet; 24 import android.util.Log; 25 import android.view.MotionEvent; 26 import android.view.PointerIcon; 27 import android.widget.Button; 28 29 public class LivePointerIconButton extends Button { LivePointerIconButton(Context context)30 public LivePointerIconButton(Context context) { 31 this(context, null); 32 } 33 LivePointerIconButton(Context context, AttributeSet attrs)34 public LivePointerIconButton(Context context, AttributeSet attrs) { 35 super(context, attrs); 36 } 37 LivePointerIconButton(Context context, AttributeSet attrs, int defStyleAttr)38 public LivePointerIconButton(Context context, AttributeSet attrs, int defStyleAttr) { 39 super(context, attrs, defStyleAttr); 40 } 41 LivePointerIconButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)42 public LivePointerIconButton(Context context, AttributeSet attrs, 43 int defStyleAttr, int defStyleRes) { 44 super(context, attrs, defStyleAttr, defStyleRes); 45 } 46 47 @Override onResolvePointerIcon(MotionEvent event, int pointerIndex)48 public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) { 49 int cursorSize = getHeight(); 50 51 Bitmap bitmap = Bitmap.createBitmap(cursorSize, cursorSize, Bitmap.Config.ARGB_8888); 52 Canvas canvas = new Canvas(bitmap); 53 54 Paint paint = new Paint(); 55 paint.setARGB(255, 255, 255, 255); 56 paint.setStyle(Paint.Style.STROKE); 57 final int strokeWidth = 4; 58 paint.setStrokeWidth(strokeWidth); 59 60 // Draw a large circle filling the bitmap. 61 final int outerCenterX = cursorSize / 2; 62 final int outerCenterY = cursorSize / 2; 63 final int outerRadius = cursorSize / 2 - strokeWidth; 64 canvas.drawCircle(outerCenterX, outerCenterY, outerRadius, paint); 65 66 // Compute relative offset of the mouse pointer from the view center. 67 // It should be between -0.5 and 0.5. 68 final float relativeX = (event.getX(pointerIndex) / getWidth()) - 0.5f; 69 final float relativeY = (event.getY(pointerIndex) / getHeight()) - 0.5f; 70 71 // Draw a smaller circle inside the large circle, offset towards the center of the view. 72 final int innerCenterX = (int) (cursorSize * (1 - relativeX) / 2); 73 final int innerCenterY = (int) (cursorSize * (1 - relativeY) / 2); 74 final int innerRadius = cursorSize / 6; 75 if (event.getAction() == MotionEvent.ACTION_MOVE) { 76 // Fill the inner circle if the mouse button is down. 77 paint.setStyle(Paint.Style.FILL); 78 } 79 canvas.drawCircle(innerCenterX, innerCenterY, innerRadius, paint); 80 81 final int hotSpotX = bitmap.getWidth() / 2; 82 final int hotSpotY = bitmap.getHeight() / 2; 83 return PointerIcon.create(bitmap, hotSpotX, hotSpotY); 84 } 85 } 86