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); + } +}