blob: 7dc5a6531f2fd1bdd9c6fa7de9e6927971143b08 [file] [log] [blame]
The Android Open Source Project792a2202009-03-03 19:32:30 -08001/*
2 * Copyright (C) 2008 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
17package com.android.music;
18
19import android.content.Context;
20import android.os.SystemClock;
21import android.util.AttributeSet;
22import android.view.KeyEvent;
23import android.view.MotionEvent;
24import android.view.View;
25import android.widget.ImageButton;
26
27/**
28 * A button that will repeatedly call a 'listener' method
29 * as long as the button is pressed.
30 */
31public class RepeatingImageButton extends ImageButton {
The Android Open Source Project792a2202009-03-03 19:32:30 -080032 private long mStartTime;
33 private int mRepeatCount;
34 private RepeatListener mListener;
35 private long mInterval = 500;
Jack Heb0fba8b2017-01-26 15:54:38 -080036
The Android Open Source Project792a2202009-03-03 19:32:30 -080037 public RepeatingImageButton(Context context) {
38 this(context, null);
39 }
40
41 public RepeatingImageButton(Context context, AttributeSet attrs) {
42 this(context, attrs, android.R.attr.imageButtonStyle);
43 }
44
45 public RepeatingImageButton(Context context, AttributeSet attrs, int defStyle) {
46 super(context, attrs, defStyle);
47 setFocusable(true);
48 setLongClickable(true);
49 }
Jack Heb0fba8b2017-01-26 15:54:38 -080050
The Android Open Source Project792a2202009-03-03 19:32:30 -080051 /**
52 * Sets the listener to be called while the button is pressed and
53 * the interval in milliseconds with which it will be called.
54 * @param l The listener that will be called
Jack Heb0fba8b2017-01-26 15:54:38 -080055 * @param interval The interval in milliseconds for calls
The Android Open Source Project792a2202009-03-03 19:32:30 -080056 */
57 public void setRepeatListener(RepeatListener l, long interval) {
58 mListener = l;
59 mInterval = interval;
60 }
Jack Heb0fba8b2017-01-26 15:54:38 -080061
The Android Open Source Project792a2202009-03-03 19:32:30 -080062 @Override
63 public boolean performLongClick() {
64 mStartTime = SystemClock.elapsedRealtime();
65 mRepeatCount = 0;
66 post(mRepeater);
67 return true;
68 }
Jack Heb0fba8b2017-01-26 15:54:38 -080069
The Android Open Source Project792a2202009-03-03 19:32:30 -080070 @Override
71 public boolean onTouchEvent(MotionEvent event) {
72 if (event.getAction() == MotionEvent.ACTION_UP) {
73 // remove the repeater, but call the hook one more time
74 removeCallbacks(mRepeater);
75 if (mStartTime != 0) {
76 doRepeat(true);
77 mStartTime = 0;
78 }
79 }
80 return super.onTouchEvent(event);
81 }
82
83 @Override
Marco Nelissen59316fd2009-07-21 15:40:06 -070084 public boolean onKeyDown(int keyCode, KeyEvent event) {
85 switch (keyCode) {
86 case KeyEvent.KEYCODE_DPAD_CENTER:
87 case KeyEvent.KEYCODE_ENTER:
88 // need to call super to make long press work, but return
89 // true so that the application doesn't get the down event.
90 super.onKeyDown(keyCode, event);
91 return true;
92 }
93 return super.onKeyDown(keyCode, event);
94 }
95
96 @Override
The Android Open Source Project792a2202009-03-03 19:32:30 -080097 public boolean onKeyUp(int keyCode, KeyEvent event) {
98 switch (keyCode) {
Jack Heb0fba8b2017-01-26 15:54:38 -080099 case KeyEvent.KEYCODE_DPAD_CENTER:
100 case KeyEvent.KEYCODE_ENTER:
101 // remove the repeater, but call the hook one more time
102 removeCallbacks(mRepeater);
103 if (mStartTime != 0) {
104 doRepeat(true);
105 mStartTime = 0;
106 }
The Android Open Source Project792a2202009-03-03 19:32:30 -0800107 }
108 return super.onKeyUp(keyCode, event);
109 }
Jack Heb0fba8b2017-01-26 15:54:38 -0800110
The Android Open Source Project792a2202009-03-03 19:32:30 -0800111 private Runnable mRepeater = new Runnable() {
112 public void run() {
113 doRepeat(false);
114 if (isPressed()) {
115 postDelayed(this, mInterval);
116 }
117 }
118 };
119
Jack Heb0fba8b2017-01-26 15:54:38 -0800120 private void doRepeat(boolean last) {
The Android Open Source Project792a2202009-03-03 19:32:30 -0800121 long now = SystemClock.elapsedRealtime();
122 if (mListener != null) {
123 mListener.onRepeat(this, now - mStartTime, last ? -1 : mRepeatCount++);
124 }
125 }
Jack Heb0fba8b2017-01-26 15:54:38 -0800126
The Android Open Source Project792a2202009-03-03 19:32:30 -0800127 public interface RepeatListener {
128 /**
129 * This method will be called repeatedly at roughly the interval
130 * specified in setRepeatListener(), for as long as the button
131 * is pressed.
132 * @param v The button as a View.
133 * @param duration The number of milliseconds the button has been pressed so far.
134 * @param repeatcount The number of previous calls in this sequence.
135 * If this is going to be the last call in this sequence (i.e. the user
Jack Heb0fba8b2017-01-26 15:54:38 -0800136 * just stopped pressing the button), the value will be -1.
The Android Open Source Project792a2202009-03-03 19:32:30 -0800137 */
138 void onRepeat(View v, long duration, int repeatcount);
139 }
140}