我正在创建一个可编辑项目列表(从后端接收)。为此,我使用了“新”回收器视图。在我的回收器视图中有几种可能的视图类型:
我遇到的问题是EditText获得焦点。调整大小踢得很好,我的键盘就显示出来了。但是获得焦点的EditText在列表中不再可见。(现在调整大小部分列表中的位置低于可见位置)。在这种情况下,我不想使用调整潘,因为顶部有一个寻呼机
发生这种情况是因为,在显示键盘时,您的EditText
不再存在。我做了几次尝试来找到这个问题的干净解决方案,保持调整大小
输入模式和良好的用户体验。以下是我最终得到的:
要确保在显示键盘之前EditText
是可见的,您必须手动滚动回收视图
,然后聚焦您的EditText
。您可以通过覆盖焦点并单击代码中的处理来做到这一点。
首先,通过将android: Focus usableInTouchMode
属性设置为false
来禁用对EditText
的关注:
<EditText
android:id="@+id/et_review"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusableInTouchMode="false"/>
然后您必须为EditText
设置一个单击侦听器,您将在其中手动滚动RecyclerView
,然后显示键盘。您必须知道包含EditText
的ViewHolder
的位置:
editText.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
// you may want to play with the offset parameter
layoutManager.scrollToPositionWithOffset(position, 0);
editText.setFocusableInTouchMode(true);
editText.post(() -> {
editText.requestFocus();
UiUtils.showKeyboard(editText);
});
}
});
最后,您必须确保EditText
在自然失去焦点时再次不可聚焦:
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
editText.setFocusableInTouchMode(false);
UiUtils.hideKeyboard();
}
}
});
这远不是一个简单干净的解决方案,但希望它能像帮助我一样帮助我。
我也遇到过同样的问题。长话短说——没有正确和优雅的解决方案。焦点处理在Android系统中一直是一大难题。
您失去注意力的原因有很多:
EditText
视图EditText
未渲染,因为RecycleView
甚至还没有为它创建ViewHolder
。示例:您有10个视图,其中5个在屏幕上,其他的不可见,因为它们在下面。CheckBox
或一些DatePicker
由于滚动事件会消耗焦点
在我的解决方案中,关于架构和结构方法的几个词:
EditText
、Spiner
、DatePicker
、CheckBox
或RadioButton
组都是一个单独的ViewModel,它是一个单独的单元,可以自己处理很多东西。我使用了很多技巧并将它们混合在一起。正如有人已经提到的,第一步是将这些参数添加到您的RecyclerView
中:
android:descendantFocusability="beforeDescendants"
android:focusable="true"
android:focusableInTouchMode="true"
所有可能输入的基本视图模型都定义了接口,我们称之为SingleInputViewModel
,在该接口中,您可以定义下一个函数/方法:
void onFocusGained();
void onFocusLost();
boolean isFocusable();
在每个特定的输入项实现中,您都可以控制焦点,例如,您可以将CheckBox
实现为不可聚焦,焦点将跳转到下一个is焦点()==true
项。此外,您还可以根据对特定视图的消费/获得焦点来控制状态和操作。
修复一些焦点传递问题的下一步-是在发生IME_ACTION_NEXT时滚动回收站视图。在这种情况下,您需要将滚动逻辑委托给LayoutManager. scrollHorizontalyBy()
或LayoutManager.scrollToPoplace()
并计算适当的偏移量或位置。
硬而优雅的方法是覆盖LayoutManager
内部的逻辑,它也负责焦点处理。LinearLayoutManager
有很多隐藏的逻辑,你无法覆盖,所以可能你需要从头开始写很多代码。
最后也是最复杂的解决方法是扩展RecyclerView
并覆盖焦点搜索相关的功能/方法:
回收r查看。焦点搜索()
回收r视图。是首选的下一个焦点()
Recycle r View. on请求焦点在Desc事()
回收r查看。焦点搜索失败()
Recycle r View. on Intercept Focus Search()
Recycle r View. on Request子Focus()
附言:看看Focus usFinder
和它的用法,只是为了了解一般知识。现在你没有什么选择了。我希望你能找到有用的东西。祝你好运!
在布局中使用此功能有效:android: desendantFocus usability="beforeDesc和"
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:descendantFocusability="beforeDescendants"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/extrasLayout"
android:layout_below="@+id/anchorView"
android:layout_marginTop="@dimen/margin5"
android:fastScrollEnabled="false"
/>
清单文件:将其添加到活动部分android: windowSoftInputMode="stateHidden|调整潘"
<activity
android:name=".activites.CartActivity"
android:label="@string/title_activity_cart"
android:exported="true"
android:windowSoftInputMode="stateHidden|adjustPan"
android:parentActivityName=".activites.HomeActivity"
android:screenOrientation="portrait">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activites.HomeActivity"/>
</activity>