【问题标题】:CollapsingToolbarLayout with a customised behavior具有自定义行为的 CollapsingToolbarLayout
【发布时间】:2017-06-14 07:18:10
【问题描述】:

我正在关注这个流行的link 的协调器行为,遵循这个post
我想要一个期望的行为,图像应该浮动到右侧而不是左侧,为此,我修改了

AvatarImageBehavior.java -> maybeInitProperties() method ->

如下:

if (mFinalXPosition == 0)
            mFinalXPosition= getScreenWidth()-70;

现在我希望工具栏固定在顶部,只有图像可以移动并粘在上面。
据我了解,只有 Behavior 文件负责此转换。
我尝试了太多东西,但没有得到正确的方法/回电继续。
欢迎任何解决方案/方法/不同的示例。

【问题讨论】:

    标签: android toolbar android-collapsingtoolbarlayout android-appbarlayout


    【解决方案1】:

    所以,第一你应该做的事情是调整布局文件 - 通过删除 layout_anchor 属性使 Toolbar 固定在顶部。

    <android.support.design.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:ignore="RtlHardcoded"
        >
    
        <android.support.design.widget.AppBarLayout
            android:id="@+id/main.appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            >
    
            <android.support.design.widget.CollapsingToolbarLayout
                android:id="@+id/main.collapsing"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
                >
    
                <ImageView
                    android:id="@+id/main.imageview.placeholder"
                    android:layout_width="match_parent"
                    android:layout_height="300dp"
                    android:scaleType="centerCrop"
                    android:src="@drawable/quila2"
                    android:tint="#11000000"
                    app:layout_collapseMode="parallax"
                    app:layout_collapseParallaxMultiplier="0.9"
                    />
    
            </android.support.design.widget.CollapsingToolbarLayout>
        </android.support.design.widget.AppBarLayout>
    
    
        <android.support.v4.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="none"
            app:behavior_overlapTop="24dp"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            >
    
            <android.support.v7.widget.CardView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="8dp"
                app:cardElevation="8dp"
                app:contentPadding="16dp"
                >
    
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:lineSpacingExtra="8dp"
                    android:text="@string/lorem"
                    android:textSize="18sp"
                    />
            </android.support.v7.widget.CardView>
    
    
        </android.support.v4.widget.NestedScrollView>
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/main.toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/primary"
            app:theme="@style/ThemeOverlay.AppCompat.Dark"
            app:title="">
    
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:orientation="horizontal">
                <TextView
                    android:id="@+id/main.textview.title"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_marginLeft="8dp"
                    android:gravity="center_vertical"
                    android:text="@string/quila_name2"
                    android:textColor="@android:color/white"
                    android:textSize="20sp"/>
    
            </LinearLayout>
        </android.support.v7.widget.Toolbar>
    
        <de.hdodenhof.circleimageview.CircleImageView
            android:layout_width="@dimen/image_width"
            android:layout_height="@dimen/image_width"
            android:layout_gravity="center_horizontal"
            android:src="@drawable/quila"
            app:border_color="@android:color/white"
            app:border_width="2dp"
            app:finalHeight="@dimen/image_final_width"
            app:layout_behavior="saulmm.myapplication.AvatarImageBehavior"
            />
    </android.support.design.widget.CoordinatorLayout>
    

    注意,我还删除了 main.framelayout.title 部分,因为我认为它也是 Toolbar 的一部分。而且我还删除了onOffsetChanged() 以及MainActivity 中所有与它相关的方法,并使我们的Toolbar 标题始终可见。

    其次,当然,您应该在AvatarImageBehavior 类中进行更改。这里主要的是现在你的ImageView 依赖于NestedScrollView 而不是Toolbar。但是由于我们不再依赖Toolbar,我们仍然需要它来定义mFinalYPosition,所以我也添加了查找Toolbar 的方法。这是行为:

    public class AvatarImageBehavior extends CoordinatorLayout.Behavior<CircleImageView> {
    
        private final static float MIN_AVATAR_PERCENTAGE_SIZE   = 0.3f;
        private final static int EXTRA_FINAL_AVATAR_PADDING     = 80;
    
        private final static String TAG = "behavior";
        private Context mContext;
    
        private float mCustomFinalYPosition;
        private float mCustomStartXPosition;
        private float mCustomStartToolbarPosition;
        private float mCustomStartHeight;
        private float mCustomFinalHeight;
    
        private float mAvatarMaxSize;
        private float mStartPosition;
        private int mStartXPosition;
        private float mStartToolbarPosition;
        private int mStartYPosition;
        private int mFinalYPosition;
        private int mStartHeight;
        private int mFinalXPosition;
        private float mChangeBehaviorPoint;
    
        public AvatarImageBehavior(Context context, AttributeSet attrs) {
            mContext = context;
    
            if (attrs != null) {
                TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AvatarImageBehavior);
                mCustomFinalYPosition = a.getDimension(R.styleable.AvatarImageBehavior_finalYPosition, 0);
                mCustomStartXPosition = a.getDimension(R.styleable.AvatarImageBehavior_startXPosition, 0);
                mCustomStartToolbarPosition = a.getDimension(R.styleable.AvatarImageBehavior_startToolbarPosition, 0);
                mCustomStartHeight = a.getDimension(R.styleable.AvatarImageBehavior_startHeight, 0);
                mCustomFinalHeight = a.getDimension(R.styleable.AvatarImageBehavior_finalHeight, 0);
    
                a.recycle();
            }
    
            init();
        }
    
        private void init() {
            bindDimensions();
        }
    
        private void bindDimensions() {
            mAvatarMaxSize = mContext.getResources().getDimension(R.dimen.image_width);
        }
    
        @Override
        public boolean layoutDependsOn(CoordinatorLayout parent, CircleImageView child, View dependency) {
            return dependency instanceof NestedScrollView;
        }
    
        @Override
        public boolean onDependentViewChanged(CoordinatorLayout parent, CircleImageView child, View dependency) {
            maybeInitProperties(parent, child, dependency);
    
            final int maxScrollDistance = (int) (mStartToolbarPosition);
            float expandedPercentageFactor = dependency.getY() / maxScrollDistance;
    
            if (expandedPercentageFactor < mChangeBehaviorPoint) {
                float heightFactor = (mChangeBehaviorPoint - expandedPercentageFactor) / mChangeBehaviorPoint;
    
                float distanceXToSubtract = ((mStartXPosition - mFinalXPosition)
                        * heightFactor) + (child.getHeight()/2);
                float distanceYToSubtract = ((mStartYPosition - mFinalYPosition)
                        * (1f - expandedPercentageFactor)) + (child.getHeight()/2);
    
                child.setX(mStartXPosition - distanceXToSubtract);
                child.setY(mStartYPosition - distanceYToSubtract);
    
                float heightToSubtract = ((mStartHeight - mCustomFinalHeight) * heightFactor);
    
                CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
                lp.width = (int) (mStartHeight - heightToSubtract);
                lp.height = (int) (mStartHeight - heightToSubtract);
                child.setLayoutParams(lp);
            } else {
                float distanceYToSubtract = ((mStartYPosition - mFinalYPosition)
                        * (1f - expandedPercentageFactor)) + (mStartHeight/2);
    
                child.setX(mStartXPosition - child.getWidth()/2);
                child.setY(mStartYPosition - distanceYToSubtract);
    
                CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
                lp.width = (int) (mStartHeight);
                lp.height = (int) (mStartHeight);
                child.setLayoutParams(lp);
            }
            return true;
        }
    
        private void maybeInitProperties(CoordinatorLayout parent, CircleImageView child, View dependency) {
            if (mStartYPosition == 0)
                mStartYPosition = (int) (dependency.getY());
    
            View toolbar = tryFindToolbarInLayout(parent);
    
            if (mFinalYPosition == 0 && toolbar != null) {
                mFinalYPosition = (toolbar.getHeight() / 2);
            }
    
            if (mStartHeight == 0)
                mStartHeight = child.getHeight();
    
            if (mStartXPosition == 0)
                mStartXPosition = (int) (child.getX() + (child.getWidth() / 2));
    
            if (mFinalXPosition == 0)
                mFinalXPosition = dependency.getContext().getResources().getDisplayMetrics().widthPixels - mContext.getResources().getDimensionPixelOffset(R.dimen.abc_action_bar_content_inset_material)
                        - ((int) mCustomFinalHeight / 2);
    
            if (mStartToolbarPosition == 0)
                mStartToolbarPosition = dependency.getY();
    
            if (mChangeBehaviorPoint == 0 && toolbar != null) {
                mChangeBehaviorPoint = (child.getHeight() - mCustomFinalHeight) / (mStartYPosition - mFinalYPosition - toolbar.getHeight());
            }
        }
    
        private View tryFindToolbarInLayout(CoordinatorLayout parent) {
            for (int i = 0; i < parent.getChildCount(); i++) {
                View child = parent.getChildAt(i);
                if (child instanceof Toolbar)
                    return child;
            }
            return null;
        }
    
        public int getStatusBarHeight() {
            int result = 0;
            int resourceId = mContext.getResources().getIdentifier("status_bar_height", "dimen", "android");
    
            if (resourceId > 0) {
                result = mContext.getResources().getDimensionPixelSize(resourceId);
            }
            return result;
        }
    } 
    

    这是我设法做到的:

    【讨论】:

    猜你喜欢
    • 2015-12-29
    • 2015-09-02
    • 2012-08-29
    • 1970-01-01
    • 2017-03-12
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    相关资源
    最近更新 更多