博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android 4.2的新特性layoutRtl,让布局自动从右往左显示
阅读量:6525 次
发布时间:2019-06-24

本文共 6089 字,大约阅读时间需要 20 分钟。

hot3.png

android4.2有一个新特性 layoutRtl,当然是对于开发者而言的,主要是方便开发者去支持阿拉伯语/波斯语等阅读习惯是从右往左的。

可以在manifest的application标签添加: 取值:true/false

这样就可以打开layoutRtl这个功能。如果当前系统语言是阿拉伯语/波斯语,打开了这个功能的应用的布局就会自动变成从右往左的,当然前提是布局没有写死控件间的位置。

layoutRtl这个功能主要是在的子类在控制,具体怎么实现,还是需要自己去看看代码,

如果布局变成了从右往左的话,焦点的移动也会有一些变化。有一个标签是用来让输入法提供类似“next”的按钮的:imeoptions=“actionNext”。你按“next”的时候会发现,本来应该往右/下移动的光标,变成往左/上移动。

View焦点(focus)的控制方向是由类进行控制的。你按下“next”的事件会由的onEditorAction()进行处理。

public void onEditorAction(int actionCode) {        final Editor.InputContentType ict = mEditor == null ? null : mEditor.mInputContentType;        if (ict != null) {            if (ict.onEditorActionListener != null) {                if (ict.onEditorActionListener.onEditorAction(this,                        actionCode, null)) {                    return;                }            }            // This is the handling for some default action.            // Note that for backwards compatibility we don't do this            // default handling if explicit ime options have not been given,            // instead turning this into the normal enter key codes that an            // app may be expecting.            if (actionCode == EditorInfo.IME_ACTION_NEXT) {                View v = focusSearch(FOCUS_FORWARD);                if (v != null) {                    if (!v.requestFocus(FOCUS_FORWARD)) {                        throw new IllegalStateException("focus search returned a view " +                                "that wasn't able to take focus!");                    }                }                return;            } else if (actionCode == EditorInfo.IME_ACTION_PREVIOUS) {                View v = focusSearch(FOCUS_BACKWARD);                if (v != null) {                    if (!v.requestFocus(FOCUS_BACKWARD)) {                        throw new IllegalStateException("focus search returned a view " +                                "that wasn't able to take focus!");                    }                }                return;            } else if (actionCode == EditorInfo.IME_ACTION_DONE) {                InputMethodManager imm = InputMethodManager.peekInstance();                if (imm != null && imm.isActive(this)) {                    imm.hideSoftInputFromWindow(getWindowToken(), 0);                }                return;            }        }        ViewRootImpl viewRootImpl = getViewRootImpl();        if (viewRootImpl != null) {            long eventTime = SystemClock.uptimeMillis();            viewRootImpl.dispatchKeyFromIme(                    new KeyEvent(eventTime, eventTime,                    KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER, 0, 0,                    KeyCharacterMap.VIRTUAL_KEYBOARD, 0,                    KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE                    | KeyEvent.FLAG_EDITOR_ACTION));            viewRootImpl.dispatchKeyFromIme(                    new KeyEvent(SystemClock.uptimeMillis(), eventTime,                    KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER, 0, 0,                    KeyCharacterMap.VIRTUAL_KEYBOARD, 0,                    KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE                    | KeyEvent.FLAG_EDITOR_ACTION));        }    }

最终会调用类的findNextFocus()方法来查找下一个可以获得focus的view。

private View findNextFocus(ViewGroup root, View focused, Rect focusedRect,            int direction, ArrayList
focusables) { if (focused != null) { if (focusedRect == null) { focusedRect = mFocusedRect; } // fill in interesting rect from focused focused.getFocusedRect(focusedRect); root.offsetDescendantRectToMyCoords(focused, focusedRect); } else { if (focusedRect == null) { focusedRect = mFocusedRect; // make up a rect at top left or bottom right of root switch (direction) { case View.FOCUS_RIGHT: case View.FOCUS_DOWN: setFocusTopLeft(root, focusedRect); break; case View.FOCUS_FORWARD://这里root是ViewRootImpl的实例 if (root.isLayoutRtl()) { setFocusBottomRight(root, focusedRect); } else { setFocusTopLeft(root, focusedRect); } break; case View.FOCUS_LEFT: case View.FOCUS_UP: setFocusBottomRight(root, focusedRect); break; case View.FOCUS_BACKWARD: if (root.isLayoutRtl()) { setFocusTopLeft(root, focusedRect); } else { setFocusBottomRight(root, focusedRect); break; } } } } switch (direction) { case View.FOCUS_FORWARD: case View.FOCUS_BACKWARD: return findNextFocusInRelativeDirection(focusables, root, focused, focusedRect, direction); case View.FOCUS_UP: case View.FOCUS_DOWN: case View.FOCUS_LEFT: case View.FOCUS_RIGHT: return findNextFocusInAbsoluteDirection(focusables, root, focused, focusedRect, direction); default: throw new IllegalArgumentException("Unknown direction: " + direction); } }
private void setFocusBottomRight(ViewGroup root, Rect focusedRect) {        final int rootBottom = root.getScrollY() + root.getHeight();        final int rootRight = root.getScrollX() + root.getWidth();        focusedRect.set(rootRight, rootBottom, rootRight, rootBottom);    }    private void setFocusTopLeft(ViewGroup root, Rect focusedRect) {        final int rootTop = root.getScrollY();        final int rootLeft = root.getScrollX();        focusedRect.set(rootLeft, rootTop, rootLeft, rootTop);    }
具体可以自己看代码,上面的类名都添加了超链接到github

转载于:https://my.oschina.net/benzhang99/blog/157060

你可能感兴趣的文章
Bridgehead Servers
查看>>
sprintf() 和 sscanf()
查看>>
open***
查看>>
Codevs 4246 奶牛的身高
查看>>
微服务专题:服务注册与发现之二Consul注册服务
查看>>
SPRING BOOT是如何实现自动初始化的?
查看>>
用VisualVM远程监控Java进程
查看>>
SVN常见图标含义及图标无法正常解决方法!
查看>>
yum install 出现 Transaction Check Error:
查看>>
paip.盘古汉字转拼音组件库使用总结
查看>>
JSP内置对象(9个常用的内置对象)
查看>>
EDI 解决方案之•EDI 消息传递•协议在 EDI 处理中的角色
查看>>
BizTalkServer 如何接收 EDI 消息(6)
查看>>
Android 通知栏
查看>>
如何使用POI对Excel表进行导入和导出
查看>>
Hyper-V中的“Network adapter “和“Legacy Network adapter”之间的区别
查看>>
淘宝开源平台(taobao-code)使用心得
查看>>
Fragment(片段)的使用步骤
查看>>
我的友情链接
查看>>
HTTP ( 一)
查看>>