12030f45f8f411cf2907ad5929feed3882c050a73Noah Wang/*
22030f45f8f411cf2907ad5929feed3882c050a73Noah Wang * Copyright (C) 2016 The Android Open Source Project
32030f45f8f411cf2907ad5929feed3882c050a73Noah Wang *
42030f45f8f411cf2907ad5929feed3882c050a73Noah Wang * Licensed under the Apache License, Version 2.0 (the "License");
52030f45f8f411cf2907ad5929feed3882c050a73Noah Wang * you may not use this file except in compliance with the License.
62030f45f8f411cf2907ad5929feed3882c050a73Noah Wang * You may obtain a copy of the License at
72030f45f8f411cf2907ad5929feed3882c050a73Noah Wang *
82030f45f8f411cf2907ad5929feed3882c050a73Noah Wang *      http://www.apache.org/licenses/LICENSE-2.0
92030f45f8f411cf2907ad5929feed3882c050a73Noah Wang *
102030f45f8f411cf2907ad5929feed3882c050a73Noah Wang * Unless required by applicable law or agreed to in writing, software
112030f45f8f411cf2907ad5929feed3882c050a73Noah Wang * distributed under the License is distributed on an "AS IS" BASIS,
122030f45f8f411cf2907ad5929feed3882c050a73Noah Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132030f45f8f411cf2907ad5929feed3882c050a73Noah Wang * See the License for the specific language governing permissions and
142030f45f8f411cf2907ad5929feed3882c050a73Noah Wang * limitations under the License.
152030f45f8f411cf2907ad5929feed3882c050a73Noah Wang */
162030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
172030f45f8f411cf2907ad5929feed3882c050a73Noah Wangpackage com.android.settings.widget;
182030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
192030f45f8f411cf2907ad5929feed3882c050a73Noah Wangimport android.content.Context;
2035a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wangimport android.content.res.Configuration;
212030f45f8f411cf2907ad5929feed3882c050a73Noah Wangimport android.graphics.Rect;
222030f45f8f411cf2907ad5929feed3882c050a73Noah Wangimport android.os.Bundle;
232030f45f8f411cf2907ad5929feed3882c050a73Noah Wangimport android.support.v4.view.ViewCompat;
242030f45f8f411cf2907ad5929feed3882c050a73Noah Wangimport android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
252030f45f8f411cf2907ad5929feed3882c050a73Noah Wangimport android.support.v4.widget.ExploreByTouchHelper;
262030f45f8f411cf2907ad5929feed3882c050a73Noah Wangimport android.util.AttributeSet;
272030f45f8f411cf2907ad5929feed3882c050a73Noah Wangimport android.view.MotionEvent;
2835a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wangimport android.view.View;
292030f45f8f411cf2907ad5929feed3882c050a73Noah Wangimport android.view.accessibility.AccessibilityEvent;
302030f45f8f411cf2907ad5929feed3882c050a73Noah Wangimport android.widget.RadioButton;
312030f45f8f411cf2907ad5929feed3882c050a73Noah Wangimport android.widget.RadioGroup;
322030f45f8f411cf2907ad5929feed3882c050a73Noah Wangimport android.widget.SeekBar;
332030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
342030f45f8f411cf2907ad5929feed3882c050a73Noah Wangimport java.util.List;
352030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
362030f45f8f411cf2907ad5929feed3882c050a73Noah Wang/**
372030f45f8f411cf2907ad5929feed3882c050a73Noah Wang * LabeledSeekBar represent a seek bar assigned with labeled, discrete values.
382030f45f8f411cf2907ad5929feed3882c050a73Noah Wang * It pretends to be a group of radio button for AccessibilityServices, in order to adjust the
392030f45f8f411cf2907ad5929feed3882c050a73Noah Wang * behavior of these services to keep the mental model of the visual discrete SeekBar.
402030f45f8f411cf2907ad5929feed3882c050a73Noah Wang */
412030f45f8f411cf2907ad5929feed3882c050a73Noah Wangpublic class LabeledSeekBar extends SeekBar {
422030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
433550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    private final ExploreByTouchHelper mAccessHelper;
443550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette
453550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    /** Seek bar change listener set via public method. */
463550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    private OnSeekBarChangeListener mOnSeekBarChangeListener;
473550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette
483550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    /** Labels for discrete progress values. */
493550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    private String[] mLabels;
503550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette
513550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    public LabeledSeekBar(Context context, AttributeSet attrs) {
523550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        this(context, attrs, com.android.internal.R.attr.seekBarStyle);
533550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    }
543550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette
553550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    public LabeledSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
563550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        this(context, attrs, defStyleAttr, 0);
573550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    }
583550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette
593550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    public LabeledSeekBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
603550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        super(context, attrs, defStyleAttr, defStyleRes);
613550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette
623550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        mAccessHelper = new LabeledSeekBarExploreByTouchHelper(this);
633550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        ViewCompat.setAccessibilityDelegate(this, mAccessHelper);
643550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette
653550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        super.setOnSeekBarChangeListener(mProxySeekBarListener);
663550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    }
673550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette
683550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    @Override
693550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    public synchronized void setProgress(int progress) {
703550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        // This method gets called from the constructor, so mAccessHelper may
713550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        // not have been assigned yet.
723550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        if (mAccessHelper != null) {
733550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette            mAccessHelper.invalidateRoot();
743550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        }
753550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette
763550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        super.setProgress(progress);
773550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    }
783550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette
793550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    public void setLabels(String[] labels) {
803550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        mLabels = labels;
813550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    }
823550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette
833550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    @Override
843550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    public void setOnSeekBarChangeListener(OnSeekBarChangeListener l) {
853550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        // The callback set in the constructor will proxy calls to this
863550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        // listener.
873550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        mOnSeekBarChangeListener = l;
883550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    }
893550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette
903550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    @Override
913550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    protected boolean dispatchHoverEvent(MotionEvent event) {
923550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        return mAccessHelper.dispatchHoverEvent(event) || super.dispatchHoverEvent(event);
933550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    }
943550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette
953550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    private void sendClickEventForAccessibility(int progress) {
963550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        mAccessHelper.invalidateRoot();
973550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        mAccessHelper.sendEventForVirtualView(progress, AccessibilityEvent.TYPE_VIEW_CLICKED);
983550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    }
993550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette
1003550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    private final OnSeekBarChangeListener mProxySeekBarListener = new OnSeekBarChangeListener() {
1013550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        @Override
1023550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        public void onStopTrackingTouch(SeekBar seekBar) {
1033550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette            if (mOnSeekBarChangeListener != null) {
1043550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette                mOnSeekBarChangeListener.onStopTrackingTouch(seekBar);
1053550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette            }
1063550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        }
1073550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette
1083550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        @Override
1093550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        public void onStartTrackingTouch(SeekBar seekBar) {
1103550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette            if (mOnSeekBarChangeListener != null) {
1113550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette                mOnSeekBarChangeListener.onStartTrackingTouch(seekBar);
1123550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette            }
1133550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        }
1143550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette
1153550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        @Override
1163550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
1173550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette            if (mOnSeekBarChangeListener != null) {
1183550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette                mOnSeekBarChangeListener.onProgressChanged(seekBar, progress, fromUser);
1193550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette                sendClickEventForAccessibility(progress);
1203550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette            }
1213550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        }
1223550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette    };
1233550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette
1242030f45f8f411cf2907ad5929feed3882c050a73Noah Wang    private class LabeledSeekBarExploreByTouchHelper extends ExploreByTouchHelper {
1252030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
12635a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wang        private boolean mIsLayoutRtl;
12735a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wang
1283550a32ca9044fbf05676d68e8b89987521ed121Alan Viverette        public LabeledSeekBarExploreByTouchHelper(LabeledSeekBar forView) {
1292030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            super(forView);
13035a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wang            mIsLayoutRtl = forView.getResources().getConfiguration()
13135a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wang                    .getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
1322030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        }
1332030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
1342030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        @Override
1352030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        protected int getVirtualViewAt(float x, float y) {
1362030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            return getVirtualViewIdIndexFromX(x);
1372030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        }
1382030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
1392030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        @Override
1402030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        protected void getVisibleVirtualViews(List<Integer> list) {
1412030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            for (int i = 0, c = LabeledSeekBar.this.getMax(); i <= c; ++i) {
1422030f45f8f411cf2907ad5929feed3882c050a73Noah Wang                list.add(i);
1432030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            }
1442030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        }
1452030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
1462030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        @Override
1472030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        protected boolean onPerformActionForVirtualView(int virtualViewId, int action,
1482030f45f8f411cf2907ad5929feed3882c050a73Noah Wang                Bundle arguments) {
1492030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            if (virtualViewId == ExploreByTouchHelper.HOST_ID) {
1502030f45f8f411cf2907ad5929feed3882c050a73Noah Wang                // Do nothing
1512030f45f8f411cf2907ad5929feed3882c050a73Noah Wang                return false;
1522030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            }
1532030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
1542030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            switch (action) {
1552030f45f8f411cf2907ad5929feed3882c050a73Noah Wang                case AccessibilityNodeInfoCompat.ACTION_CLICK:
1562030f45f8f411cf2907ad5929feed3882c050a73Noah Wang                    LabeledSeekBar.this.setProgress(virtualViewId);
1572030f45f8f411cf2907ad5929feed3882c050a73Noah Wang                    sendEventForVirtualView(virtualViewId, AccessibilityEvent.TYPE_VIEW_CLICKED);
1582030f45f8f411cf2907ad5929feed3882c050a73Noah Wang                    return true;
1592030f45f8f411cf2907ad5929feed3882c050a73Noah Wang                default:
1602030f45f8f411cf2907ad5929feed3882c050a73Noah Wang                    return false;
1612030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            }
1622030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        }
1632030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
1642030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        @Override
1652030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        protected void onPopulateNodeForVirtualView(
1662030f45f8f411cf2907ad5929feed3882c050a73Noah Wang                int virtualViewId, AccessibilityNodeInfoCompat node) {
1672030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            node.setClassName(RadioButton.class.getName());
1682030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            node.setBoundsInParent(getBoundsInParentFromVirtualViewId(virtualViewId));
1692030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK);
1702030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            node.setContentDescription(mLabels[virtualViewId]);
1712030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            node.setClickable(true);
1722030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            node.setCheckable(true);
1732030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            node.setChecked(virtualViewId == LabeledSeekBar.this.getProgress());
1742030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        }
1752030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
1762030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        @Override
1772030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) {
1782030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            event.setClassName(RadioButton.class.getName());
1792030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            event.setContentDescription(mLabels[virtualViewId]);
1802030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            event.setChecked(virtualViewId == LabeledSeekBar.this.getProgress());
1812030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        }
1822030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
1832030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        @Override
1842030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        protected void onPopulateNodeForHost(AccessibilityNodeInfoCompat node) {
1852030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            node.setClassName(RadioGroup.class.getName());
1862030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        }
1872030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
1882030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        @Override
1892030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        protected void onPopulateEventForHost(AccessibilityEvent event) {
1902030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            event.setClassName(RadioGroup.class.getName());
1912030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        }
1922030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
1932030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        private int getHalfVirtualViewWidth() {
1942030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            final int width = LabeledSeekBar.this.getWidth();
1952030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            final int barWidth = width - LabeledSeekBar.this.getPaddingStart()
1962030f45f8f411cf2907ad5929feed3882c050a73Noah Wang                    - LabeledSeekBar.this.getPaddingEnd();
1972030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            return Math.max(0, barWidth / (LabeledSeekBar.this.getMax() * 2));
1982030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        }
1992030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
2002030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        private int getVirtualViewIdIndexFromX(float x) {
20135a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wang            int posBase = Math.max(0,
2022030f45f8f411cf2907ad5929feed3882c050a73Noah Wang                    ((int) x - LabeledSeekBar.this.getPaddingStart()) / getHalfVirtualViewWidth());
20335a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wang            posBase = (posBase + 1) / 2;
204b605a4e2013337774a4e9b04eca5bf388c437234Phil Weaver            posBase = Math.min(posBase, LabeledSeekBar.this.getMax());
20535a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wang            return mIsLayoutRtl ? LabeledSeekBar.this.getMax() - posBase : posBase;
2062030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        }
2072030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
2082030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        private Rect getBoundsInParentFromVirtualViewId(int virtualViewId) {
20935a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wang            final int updatedVirtualViewId = mIsLayoutRtl
21035a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wang                    ? LabeledSeekBar.this.getMax() - virtualViewId : virtualViewId;
21135a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wang            int left = (updatedVirtualViewId * 2 - 1) * getHalfVirtualViewWidth()
2122030f45f8f411cf2907ad5929feed3882c050a73Noah Wang                    + LabeledSeekBar.this.getPaddingStart();
21335a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wang            int right = (updatedVirtualViewId * 2 + 1) * getHalfVirtualViewWidth()
2142030f45f8f411cf2907ad5929feed3882c050a73Noah Wang                    + LabeledSeekBar.this.getPaddingStart();
2152030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
2162030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            // Edge case
21735a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wang            left = updatedVirtualViewId == 0 ? 0 : left;
21835a95617fd467b823a6c1c66f0f5d9651752f2efNoah Wang            right = updatedVirtualViewId == LabeledSeekBar.this.getMax()
2192030f45f8f411cf2907ad5929feed3882c050a73Noah Wang                    ? LabeledSeekBar.this.getWidth() : right;
2202030f45f8f411cf2907ad5929feed3882c050a73Noah Wang
2212030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            final Rect r = new Rect();
2222030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            r.set(left, 0, right, LabeledSeekBar.this.getHeight());
2232030f45f8f411cf2907ad5929feed3882c050a73Noah Wang            return r;
2242030f45f8f411cf2907ad5929feed3882c050a73Noah Wang        }
2252030f45f8f411cf2907ad5929feed3882c050a73Noah Wang    }
2262030f45f8f411cf2907ad5929feed3882c050a73Noah Wang}
227