You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
141 lines
4.5 KiB
141 lines
4.5 KiB
/*
|
|
* Copyright (C) 2008 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.android.music;
|
|
|
|
import android.content.Context;
|
|
import android.os.SystemClock;
|
|
import android.util.AttributeSet;
|
|
import android.view.KeyEvent;
|
|
import android.view.MotionEvent;
|
|
import android.view.View;
|
|
import android.widget.ImageButton;
|
|
|
|
/**
|
|
* A button that will repeatedly call a 'listener' method
|
|
* as long as the button is pressed.
|
|
*/
|
|
public class RepeatingImageButton extends ImageButton {
|
|
private long mStartTime;
|
|
private int mRepeatCount;
|
|
private RepeatListener mListener;
|
|
private long mInterval = 500;
|
|
|
|
public RepeatingImageButton(Context context) {
|
|
this(context, null);
|
|
}
|
|
|
|
public RepeatingImageButton(Context context, AttributeSet attrs) {
|
|
this(context, attrs, android.R.attr.imageButtonStyle);
|
|
}
|
|
|
|
public RepeatingImageButton(Context context, AttributeSet attrs, int defStyle) {
|
|
super(context, attrs, defStyle);
|
|
setFocusable(true);
|
|
setLongClickable(true);
|
|
}
|
|
|
|
/**
|
|
* Sets the listener to be called while the button is pressed and
|
|
* the interval in milliseconds with which it will be called.
|
|
* @param l The listener that will be called
|
|
* @param interval The interval in milliseconds for calls
|
|
*/
|
|
public void setRepeatListener(RepeatListener l, long interval) {
|
|
mListener = l;
|
|
mInterval = interval;
|
|
}
|
|
|
|
@Override
|
|
public boolean performLongClick() {
|
|
mStartTime = SystemClock.elapsedRealtime();
|
|
mRepeatCount = 0;
|
|
post(mRepeater);
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean onTouchEvent(MotionEvent event) {
|
|
if (event.getAction() == MotionEvent.ACTION_UP) {
|
|
// remove the repeater, but call the hook one more time
|
|
removeCallbacks(mRepeater);
|
|
if (mStartTime != 0) {
|
|
doRepeat(true);
|
|
mStartTime = 0;
|
|
}
|
|
}
|
|
return super.onTouchEvent(event);
|
|
}
|
|
|
|
@Override
|
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
switch (keyCode) {
|
|
case KeyEvent.KEYCODE_DPAD_CENTER:
|
|
case KeyEvent.KEYCODE_ENTER:
|
|
// need to call super to make long press work, but return
|
|
// true so that the application doesn't get the down event.
|
|
super.onKeyDown(keyCode, event);
|
|
return true;
|
|
}
|
|
return super.onKeyDown(keyCode, event);
|
|
}
|
|
|
|
@Override
|
|
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
|
switch (keyCode) {
|
|
case KeyEvent.KEYCODE_DPAD_CENTER:
|
|
case KeyEvent.KEYCODE_ENTER:
|
|
// remove the repeater, but call the hook one more time
|
|
removeCallbacks(mRepeater);
|
|
if (mStartTime != 0) {
|
|
doRepeat(true);
|
|
mStartTime = 0;
|
|
}
|
|
}
|
|
return super.onKeyUp(keyCode, event);
|
|
}
|
|
|
|
private Runnable mRepeater = new Runnable() {
|
|
public void run() {
|
|
doRepeat(false);
|
|
if (isPressed()) {
|
|
postDelayed(this, mInterval);
|
|
}
|
|
}
|
|
};
|
|
|
|
private void doRepeat(boolean last) {
|
|
long now = SystemClock.elapsedRealtime();
|
|
if (mListener != null) {
|
|
mListener.onRepeat(this, now - mStartTime, last ? -1 : mRepeatCount++);
|
|
}
|
|
}
|
|
|
|
public interface RepeatListener {
|
|
/**
|
|
* This method will be called repeatedly at roughly the interval
|
|
* specified in setRepeatListener(), for as long as the button
|
|
* is pressed.
|
|
* @param v The button as a View.
|
|
* @param duration The number of milliseconds the button has been pressed so far.
|
|
* @param repeatcount The number of previous calls in this sequence.
|
|
* If this is going to be the last call in this sequence (i.e. the user
|
|
* just stopped pressing the button), the value will be -1.
|
|
*/
|
|
void onRepeat(View v, long duration, int repeatcount);
|
|
}
|
|
}
|