具有自定义行为的CollapsingToolbarLayout [英] CollapsingToolbarLayout with a customised behavior

查看:99
本文介绍了具有自定义行为的CollapsingToolbarLayout的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在关注此流行的链接,以了解警戒人员的行为,并遵循以下post .
我想要一种理想的行为,即图像应浮动在右侧而不是左侧,为此,我修改了

I am following this popular link for cordinator behaviour, following this post .
I wanted a desired behavior that image should be floated to right side instead of left and for this, I modified

AvatarImageBehavior.java -> maybeInitProperties() method ->

如下:

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

现在,我希望工具栏固定在顶部,并且只有图像能够移动并固定在其上.
根据我的理解,只有行为文件才是该过渡的原因.
我尝试了太多事情,但没有找到正确的方法/回叫继续.
任何解决方案/方法/不同的示例都非常受欢迎.

Now I wish the toolbar to be fixed at top, and only image to move and stick to it.
As per my understanding, only Behavior file is responsible for this transition.
I tried too many things, but not getting and proper approach / call back to proceed.
Any solution/ approach/ different sample is most welcome.

推荐答案

因此,您要做的第一事情是调整布局文件-通过删除Toolbar使其顶部固定在Toolbar顶部c1>属性.

So, the first thing you should do is to tweak the layout file - make Toolbar fixed at top by removing its layout_anchor attribute.

<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的一部分.而且我还删除了MainActivity中的onOffsetChanged()及其所有与之相关的方法,并使我们的Toolbar标题始终可见.

Note, I've also removed main.framelayout.title section, as I consider it as a part of a Toolbar as well. And I've also removed onOffsetChanged() and all relative to it methods in MainActivity, and made our title of Toolbar always visible.

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

Secondly, of course, you should make changes in the AvatarImageBehavior class. The main thing here is that now your ImageView is dependent on NestedScrollView instead of Toolbar. But since we're not dependent on Toolbar anymore, we still need it to define the mFinalYPosition, so I've added the method to find the Toolbar as well. Here is the behavior:

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;
    }
} 

这是我设法做到的:

这篇关于具有自定义行为的CollapsingToolbarLayout的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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