AppBarLayout.OnOffsetChangedListener的使用

来源:互联网 发布:ubuntu文件服务器搭建 编辑:程序博客网 时间:2024/04/27 06:27
如果没听说过AppBarLayout.OnOffsetChangedListener,那么就先看这里:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0616/3052.html

我在项目中的使用:
import android.content.Context;import android.content.res.Resources;import android.content.res.TypedArray;import android.support.annotation.NonNull;import android.support.design.widget.AppBarLayout;import android.support.v7.widget.Toolbar;import android.util.AttributeSet;import android.util.TypedValue;import android.view.View;import android.view.ViewGroup;import android.view.ViewParent;import android.widget.LinearLayout;import android.widget.TextView;/** * CollapsingAvatarToolbar必须在AppBarLayout里面,被CollapsingToolbarLayout包裹。CollapsingAvatarToolbar必须有个Toolbar伴随,如果你不想使用Toolbar,我们可以讨论讨论。扩展高度(Expanded height) 取决于AppBarLayout的高度。折叠高度(Collapsed height )取决于Toolbar的高度。你必须在CollapsingAvatarToolbar里面设置头像(avatar)和标题视图( title view),且id必须喝上面演示的完全一致。这些id事library里面的。(所以是@而不是@+)。你可以使用任意TextView作为title,以及任意view作为头像,我这里的例子用的是hdodenhof的CircleImageView ,但是这取决于你自己。你也可以添加更多view到CollapsingAvatarToolbar里面。所有的自定义属性都是可选的,如果没有提供就使用默认的 。 * @author Administrator *@see http://www.jcodecraeer.com/a/opensource/2015/0830/3385.html */public class CollapsingAvatarToolbar extends LinearLayout implements AppBarLayout.OnOffsetChangedListener {    private View avatarView;    private TextView titleView;    private float collapsedPadding;    private float expandedPadding;    private float expandedImageSize;    private float collapsedImageSize;    private float collapsedTextSize;    private float expandedTextSize;    private boolean valuesCalculatedAlready = false;    private Toolbar toolbar;    private AppBarLayout appBarLayout;    private float collapsedHeight;    private float expandedHeight;    private float maxOffset;    public CollapsingAvatarToolbar(Context context) {        this(context, null);        init();    }    public CollapsingAvatarToolbar(Context context, AttributeSet attrs) {        super(context, attrs);        init();        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CollapsingAvatarToolbar, 0, 0);        try {            collapsedPadding = a.getDimension(R.styleable.CollapsingAvatarToolbar_collapsedPadding, -1);            expandedPadding = a.getDimension(R.styleable.CollapsingAvatarToolbar_expandedPadding, -1);            collapsedImageSize = a.getDimension(R.styleable.CollapsingAvatarToolbar_collapsedImageSize, -1);            expandedImageSize = a.getDimension(R.styleable.CollapsingAvatarToolbar_expandedImageSize, -1);            collapsedTextSize = a.getDimension(R.styleable.CollapsingAvatarToolbar_collapsedTextSize, -1);            expandedTextSize = a.getDimension(R.styleable.CollapsingAvatarToolbar_expandedTextSize, -1);        } finally {            a.recycle();        }        final Resources resources = getResources();        if (collapsedPadding < 0) {            collapsedPadding = resources.getDimension(R.dimen.default_collapsed_padding);        }        if (expandedPadding < 0) {            expandedPadding = resources.getDimension(R.dimen.default_expanded_padding);        }        if (collapsedImageSize < 0) {            collapsedImageSize = resources.getDimension(R.dimen.default_collapsed_image_size);        }        if (expandedImageSize < 0) {            expandedImageSize = resources.getDimension(R.dimen.default_expanded_image_size);        }        if (collapsedTextSize < 0) {            collapsedTextSize = resources.getDimension(R.dimen.default_collapsed_text_size);        }        if (expandedTextSize < 0) {            expandedTextSize = resources.getDimension(R.dimen.default_expanded_text_size);        }    }    private void init() {        setOrientation(HORIZONTAL);    }    @NonNull    private AppBarLayout findParentAppBarLayout() {        ViewParent parent = this.getParent();        if (parent instanceof AppBarLayout) {            return ((AppBarLayout) parent);        } else if (parent.getParent() instanceof AppBarLayout) {            return ((AppBarLayout) parent.getParent());        } else {            throw new IllegalStateException("Must be inside an AppBarLayout");             //TODO actually, a collapsingtoolbar        }    }    protected void onAttachedToWindow() {        super.onAttachedToWindow();        findViews();        if (!isInEditMode()) {            appBarLayout.addOnOffsetChangedListener(this);        } else {            setExpandedValuesForEditMode();        }    }    private void setExpandedValuesForEditMode() {        calculateValues();        updateViews(1f, 0);    }    private void findViews() {        appBarLayout = findParentAppBarLayout();        toolbar = findSiblingToolbar();        avatarView = findAvatar();        titleView = findTitle();    }    @NonNull    private View findAvatar() {        View avatar = this.findViewById(R.id.cat_avatar);        if (avatar == null) {            throw new IllegalStateException("View with id ta_avatar not found");        }        return avatar;    }    @NonNull    private TextView findTitle() {        TextView title = (TextView) this.findViewById(R.id.cat_title);        if (title == null) {            throw new IllegalStateException("TextView with id ta_title not found");        }        return title;    }    @NonNull    private Toolbar findSiblingToolbar() {        ViewGroup parent = ((ViewGroup) this.getParent());        for (int i = 0, c = parent.getChildCount(); i < c; i++) {            View child = parent.getChildAt(i);            if (child instanceof Toolbar) {                return (Toolbar) child;            }        }        throw new IllegalStateException("No toolbar found as sibling");    }    @Override    public void onOffsetChanged(AppBarLayout appBarLayout, int offset) {        if (!valuesCalculatedAlready) {            calculateValues();            valuesCalculatedAlready = true;        }        float expandedPercentage = 1 - (-offset / maxOffset);        updateViews(expandedPercentage, offset);    }    private void calculateValues() {        collapsedHeight = toolbar.getHeight();        expandedHeight = appBarLayout.getHeight() - toolbar.getHeight();        maxOffset = expandedHeight;    }    private void updateViews(float expandedPercentage, int currentOffset) {        float inversePercentage = 1 - expandedPercentage;        float translation = -currentOffset + ((float) toolbar.getHeight() * expandedPercentage);        float currHeight = collapsedHeight + (expandedHeight - collapsedHeight) * expandedPercentage;        float currentPadding = expandedPadding + (collapsedPadding - expandedPadding) * inversePercentage;        float currentImageSize = collapsedImageSize + (expandedImageSize - collapsedImageSize) * expandedPercentage;        float currentTextSize = collapsedTextSize + (expandedTextSize - collapsedTextSize) * expandedPercentage;        setContainerOffset(translation);        setContainerHeight((int) currHeight);        setPadding((int) currentPadding);        setAvatarSize((int) currentImageSize);        setTextSize(currentTextSize);    }    private void setContainerOffset(float translation) {        this.setTranslationY(translation);    }    private void setContainerHeight(int currHeight) {        this.getLayoutParams().height = currHeight;    }    private void setPadding(int currentPadding) {        this.setPadding(currentPadding, 0, 0, 0);    }    private void setTextSize(float currentTextSize) {        titleView.setTextSize(TypedValue.COMPLEX_UNIT_PX, currentTextSize);    }    private void setAvatarSize(int currentImageSize) {        avatarView.getLayoutParams().height = currentImageSize;        avatarView.getLayoutParams().width = currentImageSize;    }}

attr.xml
<?xml version="1.0" encoding="utf-8"?><resources>        <declare-styleable name="CollapsingAvatarToolbar">        <attr name="collapsedPadding" format="dimension" />        <attr name="expandedPadding" format="dimension" />        <attr name="collapsedImageSize" format="dimension" />        <attr name="expandedImageSize" format="dimension" />        <attr name="collapsedTextSize" format="dimension" />        <attr name="expandedTextSize" format="dimension" />    </declare-styleable></resources>

ids.xml
<?xml version="1.0" encoding="utf-8"?><resources>    <item name="cat_avatar" type="id"></item>    <item name="cat_title" type="id"></item></resources>


使用,伪代码:
<android.support.design.widget.AppBarLayout            android:id="@+id/appbar"            android:layout_width="match_parent"            android:layout_height="200dp"            android:fitsSystemWindows="true"            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" >            <!-- 如果想制造toolbar的折叠效果,我们必须把Toolbar放在CollapsingToolbarLayout中: -->            <!-- 通常,我们我们都是设置Toolbar的title,而现在,我们需要把title设置在CollapsingToolBarLayout上,而不是Toolbar。 -->            <!-- 给需要有折叠效果的组件设置 layout_collapseMode属性 -->            <!-- Toolbar 的高度layout_height必须固定,不能 “wrap_content”,否则Toolbar不会滑动,也没有折叠效果 --><!-- app:contentScrim="?attr/colorPrimary"用于设置收缩的时候Toolbar自动变化到普通的颜色 --><!-- app:titleEnabled="false"用于设置是否显示title,默认为显示-->            <android.support.design.widget.CollapsingToolbarLayout                android:id="@+id/collapsingToolbarLayout"                android:layout_width="match_parent"                android:layout_height="match_parent"                app:layout_scrollFlags="scroll|exitUntilCollapsed"                android:fitsSystemWindows="true"                app:contentScrim="?attr/colorPrimary"                app:expandedTitleMarginEnd="64dp"                app:expandedTitleMarginStart="48dp"                 app:titleEnabled="false"                >                <!-- 制造视差效果 -->                <!-- CollapsingToolbarLayout还能让我们做出更高级的动画,比如在里面放一个ImageView,然后在它折叠的时候渐渐淡出。同时在用户滚动的时候title的高度也会随着改变。 -->                <!-- 为了制造出这种效果,我们添加一个定义了app:layout_collapseMode="parallax" 属性的ImageView。 -->                <ImageView                    android:id="@+id/backdrop"                    android:layout_width="match_parent"                    android:layout_height="match_parent"                    app:layout_collapseMode="parallax"                    app:layout_collapseParallaxMultiplier="0.7"                    app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"                    android:fitsSystemWindows="true"                    android:scaleType="centerCrop"                    android:src="@drawable/bg_login" />                <android.support.v7.widget.Toolbar                    android:id="@+id/toolbar"                    android:layout_width="match_parent"                    android:layout_height="?attr/actionBarSize"                    app:layout_collapseMode="pin"                    app:layout_scrollFlags="scroll|enterAlways"                    app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"                    app:titleTextAppearance="@style/TextAppearance.AppCompat.Headline" />                                <com.widget.view.CollapsingAvatarToolbar                    android:layout_width="match_parent"                    android:layout_height="?attr/actionBarSize"                    android:gravity="center_vertical"                    >                    <!--                     app:collapsedPadding="@dimen/collapsedPadding"  app:expandedPadding="@dimen/expandedPadding"  app:collapsedImageSize="@dimen/collapsedImageSize"  app:expandedImageSize="@dimen/expandedImageSize"  app:collapsedTextSize="@dimen/collapsedTextSize"  app:expandedTextSize="@dimen/expandedTextSize"                     -->                    <ImageView                        android:id="@id/cat_avatar"                        android:layout_width="wrap_content"                        android:layout_height="wrap_content"                        android:src="@drawable/face"                         android:background="@drawable/default_face_bg"        android:padding="4dp"                        />                    <TextView                        android:id="@id/cat_title"                        android:layout_width="wrap_content"                        android:layout_height="wrap_content"                        android:textColor="@android:color/holo_blue_dark"                        android:text="Name" />                </com.widget.view.CollapsingAvatarToolbar>                            </android.support.design.widget.CollapsingToolbarLayout>        </android.support.design.widget.AppBarLayout>


https://github.com/hugeterry/CoordinatorTabLayout
0 0