Android RecyclerView Edittext问题

时间:2015-05-05 10:43:08

标签: android android-listview android-edittext android-softkeyboard android-recyclerview

我正在创建一个可编辑项目列表(从后端接收)。我正在使用" new" recyclerview为此。我的recyclerview中有几种可能的viewType:

  • 复选框
  • 喷丝
  • 的EditText

我遇到的问题是EditText获得关注。 AdjustResize踢得很好,我的键盘显示出来。但是获得焦点的EditText在列表中不再可见。 (现在调整大小的部分列表中的位置在可见位置下方)。在这种情况下,我不想使用AdjustPan,因为在顶部有一个寻呼机&那些东西我想在那里固定..

9 个答案:

答案 0 :(得分:3)

在布局中使用此工作: 的机器人:descendantFocusability = “beforeDescendants”

<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 | adjustPan”

<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>

答案 1 :(得分:2)

我遇到了同样的问题。长话短说-没有正确而优雅的解决方案。在Android中,焦点处理始终是一大难题。

失去焦点的原因有很多:

  • 键盘隐藏后代EditText的视图
  • 下一个EditText不会呈现,因为RecycleView尚未为其创建ViewHolder。例如:您有10个视图,其中5个在屏幕上,而其他视图则不可见,因为它们在下面。
  • 其他一些视图会占用焦点,例如CheckBox或某些DatePicker
  • RecyclerView由于滚动事件而消耗焦点
  • 一堆其他隐藏在后台的东西

在我的解决方案中关于架构和结构方法的几句话:

  • 一切都与数据绑定兼容
  • RecyclerView与支持AdapterDelegate方法的适配器一起使用
  • 每个EditTextSpinnerDatePickerCheckBoxRadioButton组都是一个单独的ViewModel,它是一个单独的单元,可以处理许多内容自己的。

我使用了很多技巧,并将它们混合在一起。正如已经提到的,第一步是将这些参数添加到您的RecyclerView中:

            android:descendantFocusability="beforeDescendants"
            android:focusable="true"
            android:focusableInTouchMode="true"

用于所有可能输入的基本视图模型已定义了接口,我们称之为SingleInputViewModel,在该接口中,您可以定义下一个函数/方法:

void onFocusGained();

void onFocusLost();

boolean isFocusable();

在每种特定的输入项实施中,您都可以控制焦点,例如,您可以将CheckBox实施为不可聚焦,并且焦点将跳至下一个isFocusable() == true项目。另外,您还可以根据对特定视图的消费/获得关注来控制状态和操作。

修复某些焦点传递问题的下一步-在发生IME_ACTION_NEXT时滚动RecyclerView 。在这种情况下,您需要通过计算适当的偏移量或位置将滚动逻辑委托给LayoutManager.scrollHorizontallyBy()LayoutManager.scrollToPosition()

硬而优雅的方法是覆盖LayoutManager 内部的逻辑,该逻辑也负责焦点处理。 LinearLayoutManager有很多隐藏的逻辑,您将无法覆盖它们,因此可能需要从头开始编写大量代码。

最后一种也是最复杂的修复方法是扩展RecyclerView并覆盖与焦点搜索相关的乐趣/方法:

  • RecyclerView.focusSearch()
  • RecyclerView.isPreferredNextFocus()
  • RecyclerView.onRequestFocusInDescendants()
  • RecyclerView.onFocusSearchFailed()
  • RecyclerView.onInterceptFocusSearch()
  • RecyclerView.onRequestChildFocus()

P.S。看看FocusFinder及其用法,只是为了了解常识。现在,您几乎没有其他选择。希望对您有所帮助。祝你好运!

答案 2 :(得分:1)

这种情况正在发生,因为在显示键盘时,您的EditText不再存在。我已经多次尝试为这个问题找到一个干净的解决方案,保持adjustResize输入模式和良好的用户体验。这就是我最终的结果:

为确保在显示键盘之前显示EditText,您必须手动滚动RecyclerView,然后关注EditText。 您可以通过覆盖代码中的焦点和单击处理来完成此操作。

首先,通过将EditText属性设置为android:focusableInTouchMode来禁用对false的关注:

<EditText
    android:id="@+id/et_review"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:focusableInTouchMode="false"/>

然后你必须为EditText设置一个点击监听器,你将手动滚动RecyclerView,然后显示键盘。您必须知道ViewHolder包含EditText

的位置
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();
        }
    }
});

这远不是一个简单而干净的解决方案,但希望它能帮助我帮助我。

答案 3 :(得分:1)

好 我找到了解决这个问题的方法 我为此使用了一个库,它很容易解决。 当您通过此模板制作recyclerView时,它会自动解决此问题。

注意:仅适用于复选框和单选按钮

使用此

https://github.com/TakeoffAndroid/RecyclerViewTemplate

答案 4 :(得分:0)

我将发布我的解决方案,因为在此之后2天,我希望它可以对其他人有所帮助。

我的问题是RecyclerView的高度是wrap_content,这意味着它没有固定的高度,而且每次我第一次单击其中的一个编辑文本时,它并没有将重点放在第一次点击上,而是在显示键盘,而在第二次点击上它获得了焦点。

解决方法是确保RecyclerView具有固定的高度或match_parent,我真的不知道为什么,但这对我有用!

希望有帮助

答案 5 :(得分:0)

我把这三样东西都放在了 recyclerview 中,最终它阻止了 recyclerview edittext 获得焦点

 android:descendantFocusability="beforeDescendants"
        android:focusable="true"
        android:focusableInTouchMode="true"

答案 6 :(得分:-1)

我尝试了一下,它奏效了 例如在复选框中: 1-

holder.swDone.setOnCheckedChangeListener(null);

2-选中或取消

3-

holder.swDone.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {}

答案 7 :(得分:-1)

之所以发生这种情况,是因为从android 9.0开始,您必须编写post()->才能获得以前版本中edittext的焦点,您只需将其放置
 edittext.requestFocus();

但是从9.0开始,您必须运行线程来获得像这样的edittext的焦点
 et.post(() -> {et.requestFocus();});

答案 8 :(得分:-1)

您可以在编辑文本焦点更改侦听器上将recyclerview滚动到选定的回收商项目位置。看看使用滚动选项How to use RecyclerView.scrollToPosition() to move the position to the top of current view?

的链接