android - 像 Whatsapp 配置文件一样在滚动上折叠/调整图像大小

标签 android xml android-activity scroll android-recyclerview

我正在创建一个带有回收 View 的应用程序。在 RV 上方我有一个图像,当我滚动时它应该变小。这有效,但 RV 也滚动。我希望首先图像变小,然后 recyclerview 开始滚动。但是我该怎么做呢?这是我的 XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/b"
        android:id="@+id/test_photo"
        android:orientation="horizontal">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="test"/>

    </LinearLayout>
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        app:layout_anchor="@+id/test_photo"
        android:background="@color/colorPrimary"
        app:layout_anchorGravity="bottom|start">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/colorWhite"
            android:textSize="30sp"
            android:text="username"/>
    </LinearLayout>

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

这是调整图像大小的代码:

rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
                float state = 0.0f;

                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, final int dy) {
                    Log.e("Y",Integer.toString(dy));
                    state+=dy;
                    LinearLayout img = (LinearLayout) findViewById(R.id.test_photo);
                    Log.e("STATE", Float.toString(state));
                    if(state >= 500){
                        img.getLayoutParams().height = minWidth;
                        img.getLayoutParams().width = minWidth;
                        img.requestLayout();
                    }
                    if(state <= 0){
                        img.getLayoutParams().height = imgHeight;
                        img.getLayoutParams().width = imgHeight;
                        img.requestLayout();
                    }
                    if(state > 0 && state < 500){

                        //up
                        img.getLayoutParams().height = (int)(imgHeight - ((float)(imgHeight-minWidth)/500)*state);
                        img.getLayoutParams().width = (int)(imgHeight - ((float)(imgHeight-minWidth)/500)*state);
                        img.requestLayout();

                    }
                }
            });

感谢您的帮助!

编辑:

<?xml version="1.0" encoding="utf-8"?>

<android.support.design.widget.AppBarLayout
    android:id="@+id/app_bar"
    android:layout_width="match_parent"
    android:layout_height="320dp"
    android:fitsSystemWindows="true"
    android:theme="@style/AppTheme.AppBarOverlay">

    <com.obware.alifsto.HelpClasses.CollapsingImageLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        android:minHeight="108dp"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

        <ImageView
            android:id="@+id/background"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            android:scaleType="centerCrop"
            android:src="@drawable/sunset" />

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize" />

        <ImageView
            android:id="@+id/avatar"
            android:layout_width="96dp"
            android:layout_height="96dp"
            android:layout_gravity="bottom|center_horizontal"
            android:layout_marginBottom="96dp"
            android:src="@drawable/logo_blau_weiss"
            android:transitionName="@string/transition_userview_image"/>

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center_horizontal"
            android:layout_marginBottom="48dp"
            android:text="Title"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/subtitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center_horizontal"
            android:layout_marginBottom="24dp"
            android:text="Subtitle "
            android:transitionName="@string/transition_userview_username"
            android:textAppearance="?android:attr/textAppearanceMedium" />

    </com.obware.alifsto.HelpClasses.CollapsingImageLayout>

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


<android.support.v7.widget.RecyclerView
    android:id="@+id/user_interface_recycler"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">


</android.support.v7.widget.RecyclerView>

最佳答案

您想要做到这一点的方式是使用 CoordinatorLayoutAppBarLayout 并使用所有 Material Design 滚动优点。

所以基本上您所做的是创建一个类似于 CollapsingToolbarLayout 的专用布局。对于我的演示,我使用该类中的代码作为灵感来让我的折叠图像布局正常工作。

它的工作原理是将布局添加为 AppBarLayout 的直接子级,然后创建一个 AppBarLayout.OnOffsetChangeListener 并将其注册到 AppBarLayout。当您这样做时,您将在用户滚动和布局向上滚动时收到通知。

另一个重要的部分是设置最小高度。 AppBarLayout 使用最小高度来确定何时停止滚动您的布局,为您留下一个折叠的布局区域。

这是一段代码摘录:

    class OnOffsetChangedListener implements AppBarLayout.OnOffsetChangedListener {

        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {

            final int insetTop = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0;
            final int scrollRange = appBarLayout.getTotalScrollRange();
            float offsetFactor = (float) (-verticalOffset) / (float) scrollRange;
            Log.d(TAG, "onOffsetChanged(), offsetFactor = " + offsetFactor);


            int childCount = getChildCount();
            for (int i = 0; i < childCount; i++) {
                View child = getChildAt(i);
                final ViewOffsetHelper offsetHelper = getViewOffsetHelper(child);

                if (child instanceof Toolbar) {
                    if (getHeight() - insetTop + verticalOffset >= child.getHeight()) {
                        offsetHelper.setTopAndBottomOffset(-verticalOffset); // pin
                    }
                }

                if (child.getId() == R.id.background) {
                    int offset = Math.round(-verticalOffset * .5F);
                    offsetHelper.setTopAndBottomOffset(offset); // parallax
                }

                if (child.getId() == R.id.avatar) {

                    float scaleFactor = 1F - offsetFactor * .5F ;
                    child.setScaleX(scaleFactor);
                    child.setScaleY(scaleFactor);

                    int topOffset = (int) ((mImageTopCollapsed - mImageTopExpanded) * offsetFactor) - verticalOffset;
                    int leftOffset = (int) ((mImageLeftCollapsed - mImageLeftExpanded) * offsetFactor);
                    child.setPivotX(0);
                    child.setPivotY(0);
                    offsetHelper.setTopAndBottomOffset(topOffset);
                    offsetHelper.setLeftAndRightOffset(leftOffset);
                }

                if (child.getId() == R.id.title) {

                    int topOffset = (int) ((mTitleTopCollapsed - mTitleTopExpanded) * offsetFactor) - verticalOffset;
                    int leftOffset = (int) ((mTitleLeftCollapsed - mTitleLeftExpanded) * offsetFactor);
                    offsetHelper.setTopAndBottomOffset(topOffset);
                    offsetHelper.setLeftAndRightOffset(leftOffset);
                    Log.d(TAG, "onOffsetChanged(), offsetting title top = " + topOffset + ", left = " + leftOffset);
                    Log.d(TAG, "onOffsetChanged(), offsetting title mTitleLeftCollapsed = " + mTitleLeftCollapsed + ", mTitleLeftExpanded = " + mTitleLeftExpanded);
                }

                if (child.getId() == R.id.subtitle) {

                    int topOffset = (int) ((mSubtitleTopCollapsed - mSubtitleTopExpanded) * offsetFactor) - verticalOffset;
                    int leftOffset = (int) ((mSubtitleLeftCollapsed - mSubtitleLeftExpanded) * offsetFactor);
                    offsetHelper.setTopAndBottomOffset(topOffset);
                    offsetHelper.setLeftAndRightOffset(leftOffset);
                }
            }
        }
    }

child.setScaleX()child.setScaleY() 是实际改变图像大小的代码。

演示应用程序位于 GitHub 上 https://github.com/klarson2/Collapsing-Image .享受吧。


编辑:添加 TabLayout 后,我意识到我在布局中犯了一个错误,即让 AppBarLayout 成为固定高度,然后让自定义折叠组件高度是 match_parent。这使得您看不到添加到应用栏的 TabLayout。我更改了布局,使 AppBarLayout 高度为 wrap_content 并且自定义折叠组件具有固定高度。这使得向 AppBarLayout 添加附加组件(如 TabLayout)成为可能。这已在 GitHub 上的最新修订版中得到纠正。

关于android - 像 Whatsapp 配置文件一样在滚动上折叠/调整图像大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38797265/

相关文章:

android - TabLayout 使用 Activity 而不是 fragment

android - 在 Kotlin 中传递多个 lambda 函数以处理成功/失败的最佳方法

Android Facebook Graph API 更新状态

android - Android 中的碰撞检测

android - 从 Assets 文件夹中获取 txt 文件的名称到列表中

php - 将亚马逊 MWS 暂存器查询转换为 API 调用

iphone - ELCUI应用程序超时问题

xml - JAXB Unmarshal 创建了一个空对象

c# - 未知元素在反序列化过程中被忽略

android - 初学者 - 在另一个类中使用一个类中定义的变量