简体   繁体   English

方向从横向更改为纵向后,RecyclerView位于中间而不是顶部

[英]RecyclerView is in the middle instead of top after orientation changes from landscape to portrait

I have used recyclerview in a fragment. 我已经在片段中使用了recyclerview。 If activity's configChanges includes orientation, recycler view appears in the middle of the screen after phone orientation changes from landscape to portrait. 如果活动的configChanges包括方向,则手机方向从横向更改为纵向后,回收中心视图将出现在屏幕中间。 However it should be on top always. 但是,它应该始终处于最重要的位置。 If configChanges does not include orientation, it always appear on top on orientation changes. 如果configChanges不包括方向,则它总是在方向更改时显示在顶部。

Do you have any idea what it is the reason? 你知道这是什么原因吗?

This is the activity layout 这是活动布局

 <android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context="com.butterfly.LoginActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    </android.support.design.widget.AppBarLayout>


    <FrameLayout
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:id="@+id/butterflypi_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="top|start" />


    </android.support.design.widget.CoordinatorLayout>

This is the fragment layout replaces framelayout above. 这是片段布局替换上面的framelayout。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="8dp"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    tools:context="com.butterfly.fragment.ButterflyPIsFragment">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_pi_recycler_view"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"

        />
</RelativeLayout>

I found solution here . 我在这里找到了解决方案。

Basically you are creating your own behavior class: 基本上,您正在创建自己的行为类:

public class PatchedScrollingViewBehavior extends AppBarLayout.ScrollingViewBehavior {

    public PatchedScrollingViewBehavior() {
        super();
    }

    public PatchedScrollingViewBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onMeasureChild(CoordinatorLayout parent, View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) {
        if (child.getLayoutParams().height == -1) {
            List dependencies = parent.getDependencies(child);
            if (dependencies.isEmpty()) {
                return false;
            }

            AppBarLayout appBar = findFirstAppBarLayout(dependencies);
            if (appBar != null && ViewCompat.isLaidOut(appBar)) {
                if (ViewCompat.getFitsSystemWindows(appBar)) {
                    ViewCompat.setFitsSystemWindows(child, true);
                }

                int scrollRange = appBar.getTotalScrollRange();
//                int height = parent.getHeight() - appBar.getMeasuredHeight() + scrollRange;
                int parentHeight = View.MeasureSpec.getSize(parentHeightMeasureSpec);
                int height = parentHeight - appBar.getMeasuredHeight() + scrollRange;
                int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.AT_MOST);
                parent.onMeasureChild(child, parentWidthMeasureSpec, widthUsed, heightMeasureSpec, heightUsed);
                return true;
            }
        }

        return false;
    }


    private static AppBarLayout findFirstAppBarLayout(List<View> views) {
        int i = 0;

        for (int z = views.size(); i < z; ++i) {
            View view = (View) views.get(i);
            if (view instanceof AppBarLayout) {
                return (AppBarLayout) view;
            }
        }

        return null;
    }
}

and changing app:layout_behavior in your FrameLayout: 并在您的FrameLayout中更改app:layout_behavior:

<FrameLayout
        app:layout_behavior="your_package.PatchedScrollingViewBehavior"
        android:id="@+id/butterflypi_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="top|start" />

UPDATE: As I just checked - this issue was fixed in 22.2.1 library, so please update library, if you are still using 22.2.0 更新:正如我刚刚检查的-此问题已在22.2.1库中修复,因此,如果您仍在使用22.2.0,请更新库

You may be able to achieve the desired effect by creating PORTRAIT and LANDSCAPE layout much like in the demo here . 通过像此处演示中一样创建PORTRAIT和LANDSCAPE布局,您也许可以实现所需的效果。 Take a look at attached clip if this is the behavior you desire. 如果这是您想要的行为,请查看附加的剪辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM