提问者:小点点

Android回收视图编辑文本问题


我正在创建一个可编辑项目列表(从后端接收)。为此,我使用了“新”回收器视图。在我的回收器视图中有几种可能的视图类型:

  • 复选框
  • 微调器
  • 编辑文本

我遇到的问题是EditText获得焦点。调整大小踢得很好,我的键盘就显示出来了。但是获得焦点的EditText在列表中不再可见。(现在调整大小部分列表中的位置低于可见位置)。在这种情况下,我不想使用调整潘,因为顶部有一个寻呼机


共3个答案

匿名用户

发生这种情况是因为,在显示键盘时,您的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,然后显示键盘。您必须知道包含EditTextViewHolder的位置:

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视图
  • NextEditText未渲染,因为RecycleView甚至还没有为它创建ViewHolder。示例:您有10个视图,其中5个在屏幕上,其他的不可见,因为它们在下面。
  • 其他一些视图消耗焦点,例如CheckBox或一些DatePicker
  • 由于滚动事件会消耗焦点
  • 一堆隐藏在引擎盖下的东西

在我的解决方案中,关于架构和结构方法的几个词:

  • 一切都适用于数据绑定
  • RecyclerView与支持适配器委托方法的适配器一起使用
  • 每个EditTextSpinerDatePickerCheckBoxRadioButton组都是一个单独的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>