RecyclerView在中间,而不是顶部方向从横向变为纵向之后 [英] RecyclerView is in the middle instead of top after orientation changes from landscape to portrait

查看:491
本文介绍了RecyclerView在中间,而不是顶部方向从横向变为纵向之后的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个片段中使用recyclerview。如果活动的configChanges包括取向,回收视图显示在屏幕的手机方向变化从横向到纵向后中间。然而它应该是在顶部始终。如果configChanges不包括方向,它总是出现在上方向变化上面。

你有任何想法是什么原因呢?

这是该活动的布局

 < android.support.design.widget.CoordinatorLayout
    的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    的xmlns:工具=htt​​p://schemas.android.com/tool​​s
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    的xmlns:程序=htt​​p://schemas.android.com/apk/res-auto
    工具:上下文=com.butterfly.LoginActivity>    < android.support.design.widget.AppBarLayout
        机器人:layout_width =match_parent
        机器人:主题=@风格/ ThemeOverlay.AppCompat.Dark.ActionBar
        机器人:layout_height =WRAP_CONTENT>        < android.support.v7.widget.Toolbar
            机器人:ID =@ + ID /工具栏
            机器人:layout_width =match_parent
            机器人:layout_height =?ATTR / actionBarSize
            应用:layout_scrollFlags =滚动| enterAlways
            应用:popupTheme =@风格/ ThemeOverlay.AppCompat.Light/>    < /android.support.design.widget.AppBarLayout>
    <的FrameLayout
        应用:layout_behavior =@字符串/ appbar_scrolling_view_behavior
        机器人:ID =@ + ID / butterflypi_fragment
        机器人:layout_width =match_parent
        机器人:layout_height =match_parent
        机器人:layout_gravity =顶|开始/>
    < /android.support.design.widget.CoordinatorLayout>

这是片段的布局替换上述的FrameLayout。

 <的RelativeLayout的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    的xmlns:工具=htt​​p://schemas.android.com/tool​​s的android:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:填充=8DP
    的xmlns:card_view =htt​​p://schemas.android.com/apk/res-auto
    工具:上下文=com.butterfly.fragment.ButterflyPIsFragment>    < android.support.v7.widget.RecyclerView
        机器人:ID =@ + ID / my_pi_recycler_view
        机器人:滚动条=垂直
        机器人:layout_width =match_parent
        机器人:layout_height =match_parent
        机器人:layout_alignParentTop =真        />
< / RelativeLayout的>


解决方案

我找到了解决方案的这里

基本上你创建你自己的行为类:

 公共类PatchedScrollingViewBehavior扩展AppBarLayout.ScrollingViewBehavior {    公共PatchedScrollingViewBehavior(){
        超();
    }    公共PatchedScrollingViewBehavior(上下文的背景下,ATTRS的AttributeSet){
        超(背景下,ATTRS);
    }    @覆盖
    公共布尔onMeasureChild(CoordinatorLayout父母,子女观,诠释parentWidthMeasureSpec,诠释widthUsed,诠释parentHeightMeasureSpec,诠释heightUsed){
        如果(child.getLayoutParams()==高度-1){
            列出依赖性= parent.getDependencies(孩子);
            如果(dependencies.isEmpty()){
                返回false;
            }            AppBarLayout appBar = findFirstAppBarLayout(依赖);
            如果(appBar = NULL&放大器;!&安培; ViewCompat.isLaidOut(appBar)){
                如果(ViewCompat.getFitsSystemWindows(appBar)){
                    ViewCompat.setFitsSystemWindows(孩子,真);
                }                INT scrollRange = appBar.getTotalScrollRange();
// INT高度= parent.getHeight() - appBar.getMeasuredHeight()+ scrollRange;
                INT上级高度= View.MeasureSpec.getSize(parentHeightMeasureSpec);
                INT高度=上级高度 - appBar.getMeasuredHeight()+ scrollRange;
                INT heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(高度,View.MeasureSpec.AT_MOST);
                parent.onMeasureChild(儿童,parentWidthMeasureSpec,widthUsed,heightMeasureSpec,heightUsed);
                返回true;
            }
        }        返回false;
    }
    私有静态AppBarLayout findFirstAppBarLayout(列表<视图>的观点){
        INT I = 0;        对于(INT Z = views.size(); I< Z ++我){
            查看查看=(查看)views.get(I)
            如果(查看的instanceof AppBarLayout){
                返回(AppBarLayout)视图。
            }
        }        返回null;
    }
}

和不断变化的应用程序:layout_behavior在你的FrameLayout:

 <的FrameLayout
        应用:layout_behavior =your_package.PatchedScrollingViewBehavior
        机器人:ID =@ + ID / butterflypi_fragment
        机器人:layout_width =match_parent
        机器人:layout_height =match_parent
        机器人:layout_gravity =顶|开始/>

更新:正如我刚才检查 - 这个问题是固定在22.2.1库,所以请更新库,如果你还在使用22.2.0

I have used recyclerview in a fragment. If activity's configChanges includes orientation, recycler view appears in the middle of the screen after phone orientation changes from landscape to portrait. However it should be on top always. If configChanges does not include orientation, it always appear on top on orientation changes.

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.

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

这篇关于RecyclerView在中间,而不是顶部方向从横向变为纵向之后的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆