androidO 行为变更输入和导航

输入和导航

随着 Android 应用出现在 Chrome 操作系统和平板电脑等其他大尺寸设备上,我们看到,用户在 Android 应用中又重新开始使用键盘导航。在 Android O 中,我们又再次使用键盘作为导航输入设备,从而为基于箭头键和 Tab 键的导航构建了一种更可靠并且可预测的模型。

尤其要指出的是,我们对元素焦点行为做出以下变更:

  • 现在,如果您没有为 View对象(前景或背景图片)定义任何焦点状态颜色,框架会为 View设置默认的焦点突出显示颜色。此焦点突出显示标志是基于操作组件主题背景的涟漪图片。

  • 如果您不希望 View对象在接收焦点时使用此默认突出显示标志,请在包含 View的布局 XML 文件中将 android:defaultFocusHighlightEnabled属性设置为 false ,或者将 false传递至应用界面逻辑中的 setDefaultFocusHighlightEnabled ( )。

  • 要测试键盘输入对界面元素焦点有何影响,您可以启用 Drawing > Show layout bounds开发者选项。在 Android O 中,此选项在当前具有焦点的元素上显示一个 “X” 图标。

另外,Android O 中的所有工具栏元素自动组成键盘导航键区,用户可以更加轻松地导航进入和离开每个作为一个整体的工具栏。

如需详细了解如何在您的应用中改善对键盘导航的支持,请阅读以下链接中的支持键盘导航指南。

(https://developer.android.google.cn/training/keyboard-input/navigation.html)

本文前面均引自已有文章,主要重点介绍关于 android:defaultFocusHightEnabled的使用原理:

frameworks/base/core/java/android/view/View.java#20140
> 20209    private void switchDefaultFocusHighlight() {
> 20210        if (isFocused()) {
> 20211            final boolean needed = isDefaultFocusHighlightNeeded(mBackground,
> 20212                    mForegroundInfo == null ? null : mForegroundInfo.mDrawable);
> 20213            final boolean active = mDefaultFocusHighlight != null;
> 20214            if (needed && !active) {
                       // 表示此View有焦点,需要设置selectableItemBackground背景
> 20215                setDefaultFocusHighlight(getDefaultFocusHighlightDrawable());
> 20216            } else if (!needed && active) {
> 20217                // The highlight is no longer needed, so tear it down.
> 20218                setDefaultFocusHighlight(null);
> 20219            }
> 20220        }
> 20221    }


   /// 系统默认的selectableItemBackground背景高亮
> 20140    private Drawable getDefaultFocusHighlightDrawable() {
> 20141        if (mDefaultFocusHighlightCache == null) {
> 20142            if (mContext != null) {
> 20143                final int[] attrs = new int[] { android.R.attr.selectableItemBackground };
> 20144                final TypedArray ta = mContext.obtainStyledAttributes(attrs);
> 20145                mDefaultFocusHighlightCache = ta.getDrawable(0);
> 20146                ta.recycle();
> 20147            }
> 20148        }
> 20149        return mDefaultFocusHighlightCache;
> 20150    }

isDefaultFocusHighlightNeeded()函数的定义:

21280    public boolean isDefaultFocusHighlightNeeded(Drawable background, Drawable foreground) {
21281        final boolean lackFocusState = (background == null || !background.isStateful()
21282                || !background.hasFocusStateSpecified())
21283                && (foreground == null || !foreground.isStateful()
21284                || !foreground.hasFocusStateSpecified());
21285        return !isInTouchMode() && getDefaultFocusHighlightEnabled() && lackFocusState
21286                && isAttachedToWindow() && sUseDefaultFocusHighlight;
21287    }

表示是否默认的焦点高亮开启;当非触摸模式,getDefaultFocusHighlightEnabled()的View_defaultFocusHighlightEnabled

xml配置值为true时, 且没有有效的设置背景焦点状态,表示开启;因此,android:defaultFocusHighlightEnabled属性设置为 false即可关闭默认焦点高亮。

在View.java的draw()方法中,调用drawDefaultFocusHighlight()会绘制默认的焦点高亮:

也就是当setDefaultFocusHighlight前面设置过后,mDefaultFocusHighlight才不会为null,才会绘制具体默认背景(selectableItemBackground)

21313    private void drawDefaultFocusHighlight(Canvas canvas) {
21314        if (mDefaultFocusHighlight != null) {
21315            if (mDefaultFocusHighlightSizeChanged) {
21316                mDefaultFocusHighlightSizeChanged = false;
21317                final int l = mScrollX;
21318                final int r = l + mRight - mLeft;
21319                final int t = mScrollY;
21320                final int b = t + mBottom - mTop;
21321                mDefaultFocusHighlight.setBounds(l, t, r, b);
21322            }
21323            mDefaultFocusHighlight.draw(canvas);
21324        }
21325    }

我们也可以在View的XML中自己添加:

android:defaultFocusHighlightEnabled="false"
android:background="?android:selectableItemBackground"

实现视图背景,此效果关闭夏天默认的,使用background具有鼠标悬停高亮效果。

猜你喜欢

转载自blog.csdn.net/snail201211/article/details/84324808