diff --git a/res/layout/font_size_activity.xml b/res/layout/font_size_activity.xml
index ec064fa5555..479a5f5412f 100644
--- a/res/layout/font_size_activity.xml
+++ b/res/layout/font_size_activity.xml
@@ -70,7 +70,7 @@
android:focusable="true"
android:contentDescription="@string/font_size_make_smaller_desc" />
-
- list) {
+ for (int i = 0, c = LabeledSeekBar.this.getMax(); i <= c; ++i) {
+ list.add(i);
+ }
+ }
+
+ @Override
+ protected boolean onPerformActionForVirtualView(int virtualViewId, int action,
+ Bundle arguments) {
+ if (virtualViewId == ExploreByTouchHelper.HOST_ID) {
+ // Do nothing
+ return false;
+ }
+
+ switch (action) {
+ case AccessibilityNodeInfoCompat.ACTION_CLICK:
+ LabeledSeekBar.this.setProgress(virtualViewId);
+ sendEventForVirtualView(virtualViewId, AccessibilityEvent.TYPE_VIEW_CLICKED);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ protected void onPopulateNodeForVirtualView(
+ int virtualViewId, AccessibilityNodeInfoCompat node) {
+ node.setClassName(RadioButton.class.getName());
+ node.setBoundsInParent(getBoundsInParentFromVirtualViewId(virtualViewId));
+ node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK);
+ node.setContentDescription(mLabels[virtualViewId]);
+ node.setClickable(true);
+ node.setCheckable(true);
+ node.setChecked(virtualViewId == LabeledSeekBar.this.getProgress());
+ }
+
+ @Override
+ protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) {
+ event.setClassName(RadioButton.class.getName());
+ event.setContentDescription(mLabels[virtualViewId]);
+ event.setChecked(virtualViewId == LabeledSeekBar.this.getProgress());
+ }
+
+ @Override
+ protected void onPopulateNodeForHost(AccessibilityNodeInfoCompat node) {
+ node.setClassName(RadioGroup.class.getName());
+ }
+
+ @Override
+ protected void onPopulateEventForHost(AccessibilityEvent event) {
+ event.setClassName(RadioGroup.class.getName());
+ }
+
+ private int getHalfVirtualViewWidth() {
+ final int width = LabeledSeekBar.this.getWidth();
+ final int barWidth = width - LabeledSeekBar.this.getPaddingStart()
+ - LabeledSeekBar.this.getPaddingEnd();
+ return Math.max(0, barWidth / (LabeledSeekBar.this.getMax() * 2));
+ }
+
+ private int getVirtualViewIdIndexFromX(float x) {
+ final int posBase = Math.max(0,
+ ((int) x - LabeledSeekBar.this.getPaddingStart()) / getHalfVirtualViewWidth());
+ return (posBase + 1) / 2;
+ }
+
+ private Rect getBoundsInParentFromVirtualViewId(int virtualViewId) {
+ int left = (virtualViewId * 2 - 1) * getHalfVirtualViewWidth()
+ + LabeledSeekBar.this.getPaddingStart();
+ int right = (virtualViewId * 2 + 1) * getHalfVirtualViewWidth()
+ + LabeledSeekBar.this.getPaddingStart();
+
+ // Edge case
+ left = virtualViewId == 0 ? 0 : left;
+ right = virtualViewId == LabeledSeekBar.this.getMax()
+ ? LabeledSeekBar.this.getWidth() : right;
+
+ final Rect r = new Rect();
+ r.set(left, 0, right, LabeledSeekBar.this.getHeight());
+ return r;
+ }
+ }
+
+ private String[] mLabels;
+
+ private ExploreByTouchHelper mAccessHelper;
+
+ public LabeledSeekBar(Context context, AttributeSet attrs) {
+ this(context, attrs, com.android.internal.R.attr.seekBarStyle);
+ }
+
+ public LabeledSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public LabeledSeekBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ @Override
+ public synchronized void setProgress(int progress) {
+ if (mAccessHelper != null) {
+ mAccessHelper.invalidateRoot();
+ }
+
+ super.setProgress(progress);
+ }
+
+ public void setLabels(String[] labels) {
+ mLabels = labels;
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ mAccessHelper = new LabeledSeekBarExploreByTouchHelper(this);
+ ViewCompat.setAccessibilityDelegate(this, mAccessHelper);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ ViewCompat.setAccessibilityDelegate(this, null);
+ mAccessHelper = null;
+ super.onDetachedFromWindow();
+ }
+
+ @Override
+ protected boolean dispatchHoverEvent(MotionEvent event) {
+ if (mAccessHelper != null && mAccessHelper.dispatchHoverEvent(event)) {
+ return true;
+ }
+
+ return super.dispatchHoverEvent(event);
+ }
+}