RecycleView steals focus when inside a NestedScrollView

心已入冬 提交于 2019-12-28 02:49:11

问题


When I put a RecyclerView inside a nested scrollview, the screen always jumps to the top of the RecyclerView instead of the top of the page. Here is a simple example.

layout xml:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="350dp"
            android:background="@android:color/holo_blue_dark"/>
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycleView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
</android.support.v4.widget.NestedScrollView>
</layout>

Activity with dummy adapter:

public class RecycleViewTestActivity extends AppCompatActivity {

public static class ExampleAdapter extends RecyclerView.Adapter<ExampleViewHolder> {

    private Context context;

    public ExampleAdapter(Context context) {
        this.context = context;
    }

    @Override
    public ExampleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        TextView view = new TextView(context);
        view.setText("Test");
        return new ExampleViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ExampleViewHolder holder, int position) {

    }

    @Override
    public int getItemCount() {
        return 100;
    }
}

public static class ExampleViewHolder extends RecyclerView.ViewHolder {

    public ExampleViewHolder(View itemView) {
        super(itemView);
    }
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_rectest);
    RecyclerView view = (RecyclerView) findViewById(R.id.recycleView);
    view.setNestedScrollingEnabled(false);
    view.setLayoutManager(new LinearLayoutManager(this));
    ExampleAdapter adapter = new ExampleAdapter(this);
    view.setAdapter(adapter);
}

}

In this example I have a 350dp tall empty view over the recycleview because you need to have some content over the RecycleView for this to show up obviously. The RecycleView iteself contains 100 dummy textviews.

After you start the activity, the scroll is at the top of the RecycleView instead of the top of the page. It must be something inside the LinearLayoutManager, but havent really looked yet.

Any ideas how to solve this?


回答1:


Make your top view focusable. "RecyclerView has "focusableOnTouchMode" set to true to handle its childrens' focus changes during layout." Relevant discussion of the issue.

Example:

<android.support.v4.widget.NestedScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:focusableInTouchMode="true"
        android:orientation="vertical">

        <View
            android:id="@+id/someView"
            android:layout_width="wrap_content"
            android:layout_height="350dp"/>

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    </LinearLayout>
</android.support.v4.widget.NestedScrollView>



回答2:


For me accepted answer didn't work. I solve this by adding this attribute for parent:

android:descendantFocusability="blocksDescendants"




回答3:


Thanks @Amagi82. You answer helped me but it was not enough. I added more 2 attributes. That worked for me:

<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:focusableInTouchMode="true"
    android:focusable="true"
    android:descendantFocusability="blocksDescendants"
    android:orientation="vertical">

    <View
        android:id="@+id/someView"
        android:layout_width="wrap_content"
        android:layout_height="350dp"/>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>




回答4:


Do it this way:

LinearLayoutManager lm = new LinearLayoutManager(this);
lm.setAutoMeasureEnabled(true);
view.setLayoutManager(lm)


来源:https://stackoverflow.com/questions/36923948/recycleview-steals-focus-when-inside-a-nestedscrollview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!