AppBarLayout.OnOffsetChangedListener的使用

如果没听说过AppBarLayout.OnOffsetChangedListener,那么就先看这里:
[url]http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0616/3052.html[/url]

我在项目中的使用:

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>


[url]https://github.com/hugeterry/CoordinatorTabLayout[/url]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值