android 源码——packages/apps/Music学习二

来源:互联网 发布:手机淘宝怎么取消好评 编辑:程序博客网 时间:2024/05/16 11:00


长按"上一首"、"下一首"按钮实现歌曲快退、快进功能,代码如下

重写按钮ImageButton,RepeatingImageButton.java


/** * 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);    }}



MediaPlaybackActivity.java中的代码如下:

        mNextButton = (RepeatingImageButton) findViewById(R.id.next);        mNextButton.setOnClickListener(mNextListener);        mNextButton.setRepeatListener(mFfwdListener, 260);

    private RepeatingImageButton.RepeatListener mFfwdListener =        new RepeatingImageButton.RepeatListener() {        public void onRepeat(View v, long howlong, int repcnt) {            scanForward(repcnt, howlong);        }    };

    private void scanForward(int repcnt, long delta) {        if(mService == null) return;        try {            if(repcnt == 0) {                mStartSeekPos = mService.position();                mLastSeekEventTime = 0;                mSeeking = false;            } else {                mSeeking = true;                if (delta < 5000) {                    // seek at 10x speed for the first 5 seconds                    delta = delta * 10;                 } else {                    // seek at 40x after that                    delta = 50000 + (delta - 5000) * 40;                }                long newpos = mStartSeekPos + delta;                long duration = mService.duration();                if (newpos >= duration) {                    // move to next track                    mService.next();                    mStartSeekPos -= duration; // is OK to go negative                    newpos -= duration;                }                if (((delta - mLastSeekEventTime) > 250) || repcnt < 0){                    mService.seek(newpos);                    mLastSeekEventTime = delta;                }                if (repcnt >= 0) {                    mPosOverride = newpos;                } else {                    mPosOverride = -1;                }                refreshNow();            }        } catch (RemoteException ex) {        }    }


        mPrevButton = (RepeatingImageButton) findViewById(R.id.prev);        mPrevButton.setOnClickListener(mPrevListener);        mPrevButton.setRepeatListener(mRewListener, 260);
    private RepeatingImageButton.RepeatListener mRewListener =        new RepeatingImageButton.RepeatListener() {        public void onRepeat(View v, long howlong, int repcnt) {            scanBackward(repcnt, howlong);        }    };
    private void scanBackward(int repcnt, long delta) {        if(mService == null) return;        try {            if(repcnt == 0) {                mStartSeekPos = mService.position();                mLastSeekEventTime = 0;                mSeeking = false;            } else {                mSeeking = true;                if (delta < 5000) {                    // seek at 10x speed for the first 5 seconds                    delta = delta * 10;                 } else {                    // seek at 40x after that                    delta = 50000 + (delta - 5000) * 40;                }                long newpos = mStartSeekPos - delta;                if (newpos < 0) {                    // move to previous track                    mService.prev();                    long duration = mService.duration();                    mStartSeekPos += duration;                    newpos += duration;                }                if (((delta - mLastSeekEventTime) > 250) || repcnt < 0){                    mService.seek(newpos);                    mLastSeekEventTime = delta;                }                if (repcnt >= 0) {                    mPosOverride = newpos;                } else {                    mPosOverride = -1;                }                refreshNow();            }        } catch (RemoteException ex) {        }    }








原创粉丝点击