AppBarLayout.OnOffsetChangedListener的使用

论坛 期权论坛 脚本     
已经匿名di用户   2022-7-2 21:48   4878   0
如果没听说过AppBarLayout.OnOffsetChangedListener,那么就先看这里:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0616/3052.html

我在项目中的使用:
Java代码 收藏代码
  1. import android.content.Context;
  2. import android.content.res.Resources;
  3. import android.content.res.TypedArray;
  4. import android.support.annotation.NonNull;
  5. import android.support.design.widget.AppBarLayout;
  6. import android.support.v7.widget.Toolbar;
  7. import android.util.AttributeSet;
  8. import android.util.TypedValue;
  9. import android.view.View;
  10. import android.view.ViewGroup;
  11. import android.view.ViewParent;
  12. import android.widget.LinearLayout;
  13. import android.widget.TextView;
  14. /**
  15. * CollapsingAvatarToolbar必须在AppBarLayout里面,被CollapsingToolbarLayout包裹。
  16. CollapsingAvatarToolbar必须有个Toolbar伴随,如果你不想使用Toolbar,我们可以讨论讨论。
  17. 扩展高度(Expanded height) 取决于AppBarLayout的高度。
  18. 折叠高度(Collapsed height )取决于Toolbar的高度。
  19. 你必须在CollapsingAvatarToolbar里面设置头像(avatar)和标题视图( title view),且id必须喝上面演示的完全一致。这些id事library里面的。(所以是@而不是@+)。
  20. 你可以使用任意TextView作为title,以及任意view作为头像,我这里的例子用的是hdodenhof的CircleImageView ,但是这取决于你自己。
  21. 你也可以添加更多view到CollapsingAvatarToolbar里面。
  22. 所有的自定义属性都是可选的,如果没有提供就使用默认的 。
  23. * @author Administrator
  24. * @see http://www.jcodecraeer.com/a/opensource/2015/0830/3385.html
  25. */
  26. public class CollapsingAvatarToolbar extends LinearLayout implements AppBarLayout.OnOffsetChangedListener {
  27. private View avatarView;
  28. private TextView titleView;
  29. private float collapsedPadding;
  30. private float expandedPadding;
  31. private float expandedImageSize;
  32. private float collapsedImageSize;
  33. private float collapsedTextSize;
  34. private float expandedTextSize;
  35. private boolean valuesCalculatedAlready = false;
  36. private Toolbar toolbar;
  37. private AppBarLayout appBarLayout;
  38. private float collapsedHeight;
  39. private float expandedHeight;
  40. private float maxOffset;
  41. public CollapsingAvatarToolbar(Context context) {
  42. this(context, null);
  43. init();
  44. }
  45. public CollapsingAvatarToolbar(Context context, AttributeSet attrs) {
  46. super(context, attrs);
  47. init();
  48. TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CollapsingAvatarToolbar, 0, 0);
  49. try {
  50. collapsedPadding = a.getDimension(R.styleable.CollapsingAvatarToolbar_collapsedPadding, -1);
  51. expandedPadding = a.getDimension(R.styleable.CollapsingAvatarToolbar_expandedPadding, -1);
  52. collapsedImageSize = a.getDimension(R.styleable.CollapsingAvatarToolbar_collapsedImageSize, -1);
  53. expandedImageSize = a.getDimension(R.styleable.CollapsingAvatarToolbar_expandedImageSize, -1);
  54. collapsedTextSize = a.getDimension(R.styleable.CollapsingAvatarToolbar_collapsedTextSize, -1);
  55. expandedTextSize = a.getDimension(R.styleable.CollapsingAvatarToolbar_expandedTextSize, -1);
  56. } finally {
  57. a.recycle();
  58. }
  59. final Resources resources = getResources();
  60. if (collapsedPadding < 0) {
  61. collapsedPadding = resources.getDimension(R.dimen.default_collapsed_padding);
  62. }
  63. if (expandedPadding < 0) {
  64. expandedPadding = resources.getDimension(R.dimen.default_expanded_padding);
  65. }
  66. if (collapsedImageSize < 0) {
  67. collapsedImageSize = resources.getDimension(R.dimen.default_collapsed_image_size);
  68. }
  69. if (expandedImageSize < 0) {
  70. expandedImageSize = resources.getDimension(R.dimen.default_expanded_image_size);
  71. }
  72. if (collapsedTextSize < 0) {
  73. collapsedTextSize = resources.getDimension(R.dimen.default_collapsed_text_size);
  74. }
  75. if (expandedTextSize < 0) {
  76. expandedTextSize = resources.getDimension(R.dimen.default_expanded_text_size);
  77. }
  78. }
  79. private void init() {
  80. setOrientation(HORIZONTAL);
  81. }
  82. @NonNull
  83. private AppBarLayout findParentAppBarLayout() {
  84. ViewParent parent = this.getParent();
  85. if (parent instanceof AppBarLayout) {
  86. return ((AppBarLayout) parent);
  87. } else if (parent.getParent() instanceof AppBarLayout) {
  88. return ((AppBarLayout) parent.getParent());
  89. } else {
  90. throw new IllegalStateException("Must be inside an AppBarLayout");
  91. //TODO actually, a collapsingtoolbar
  92. }
  93. }
  94. protected void onAttachedToWindow() {
  95. super.onAttachedToWindow();
  96. findViews();
  97. if (!isInEditMode()) {
  98. appBarLayout.addOnOffsetChangedListener(this);
  99. } else {
  100. setExpandedValuesForEditMode();
  101. }
  102. }
  103. private void setExpandedValuesForEditMode() {
  104. calculateValues();
  105. updateViews(1f, 0);
  106. }
  107. private void findViews() {
  108. appBarLayout = findParentAppBarLayout();
  109. toolbar = findSiblingToolbar();
  110. avatarView = findAvatar();
  111. titleView = findTitle();
  112. }
  113. @NonNull
  114. private View findAvatar() {
  115. View avatar = this.findViewById(R.id.cat_avatar);
  116. if (avatar == null) {
  117. throw new IllegalStateException("View with id ta_avatar not found");
  118. }
  119. return avatar;
  120. }
  121. @NonNull
  122. private TextView findTitle() {
  123. TextView title = (TextView) this.findViewById(R.id.cat_title);
  124. if (title == null) {
  125. throw new IllegalStateException("TextView with id ta_title not found");
  126. }
  127. return title;
  128. }
  129. @NonNull
  130. private Toolbar findSiblingToolbar() {
  131. ViewGroup parent = ((ViewGroup) this.getParent());
  132. for (int i = 0, c = parent.getChildCount(); i < c; i++) {
  133. View child = parent.getChildAt(i);
  134. if (child instanceof Toolbar) {
  135. return (Toolbar) child;
  136. }
  137. }
  138. throw new IllegalStateException("No toolbar found as sibling");
  139. }
  140. @Override
  141. public void onOffsetChanged(AppBarLayout appBarLayout, int offset) {
  142. if (!valuesCalculatedAlready) {
  143. calculateValues();
  144. valuesCalculatedAlready = true;
  145. }
  146. float expandedPercentage = 1 - (-offset / maxOffset);
  147. updateViews(expandedPercentage, offset);
  148. }
  149. private void calculateValues() {
  150. collapsedHeight = toolbar.getHeight();
  151. expandedHeight = appBarLayout.getHeight() - toolbar.getHeight();
  152. maxOffset = expandedHeight;
  153. }
  154. private void updateViews(float expandedPercentage, int currentOffset) {
  155. float inversePercentage = 1 - expandedPercentage;
  156. float translation = -currentOffset + ((float) toolbar.getHeight() * expandedPercentage);
  157. float currHeight = collapsedHeight + (expandedHeight - collapsedHeight) * expandedPercentage;
  158. float currentPadding = expandedPadding + (collapsedPadding - expandedPadding) * inversePercentage;
  159. float currentImageSize = collapsedImageSize + (expandedImageSize - collapsedImageSize) * expandedPercentage;
  160. float currentTextSize = collapsedTextSize + (expandedTextSize - collapsedTextSize) * expandedPercentage;
  161. setContainerOffset(translation);
  162. setContainerHeight((int) currHeight);
  163. setPadding((int) currentPadding);
  164. setAvatarSize((int) currentImageSize);
  165. setTextSize(currentTextSize);
  166. }
  167. private void setContainerOffset(float translation) {
  168. this.setTranslationY(translation);
  169. }
  170. private void setContainerHeight(int currHeight) {
  171. this.getLayoutParams().height = currHeight;
  172. }
  173. private void setPadding(int currentPadding) {
  174. this.setPadding(currentPadding, 0, 0, 0);
  175. }
  176. private void setTextSize(float currentTextSize) {
  177. titleView.setTextSize(TypedValue.COMPLEX_UNIT_PX, currentTextSize);
  178. }
  179. private void setAvatarSize(int currentImageSize) {
  180. avatarView.getLayoutParams().height = currentImageSize;
  181. avatarView.getLayoutParams().width = currentImageSize;
  182. }
  183. }

attr.xml
Xml代码 收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <declare-styleable name="CollapsingAvatarToolbar">
  4. <attr name="collapsedPadding" format="dimension" />
  5. <attr name="expandedPadding" format="dimension" />
  6. <attr name="collapsedImageSize" format="dimension" />
  7. <attr name="expandedImageSize" format="dimension" />
  8. <attr name="collapsedTextSize" format="dimension" />
  9. <attr name="expandedTextSize" format="dimension" />
  10. </declare-styleable>
  11. </resources>

ids.xml
Xml代码 收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <item name="cat_avatar" type="id"></item>
  4. <item name="cat_title" type="id"></item>
  5. </resources>


使用,伪代码:
Xml代码 收藏代码
  1. <android.support.design.widget.AppBarLayout
  2. android:id="@+id/appbar"
  3. android:layout_width="match_parent"
  4. android:layout_height="200dp"
  5. android:fitsSystemWindows="true"
  6. android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" >
  7. <!-- 如果想制造toolbar的折叠效果,我们必须把Toolbar放在CollapsingToolbarLayout中: -->
  8. <!-- 通常,我们我们都是设置Toolbar的title,而现在,我们需要把title设置在CollapsingToolBarLayout上,而不是Toolbar。 -->
  9. <!-- 给需要有折叠效果的组件设置 layout_collapseMode属性 -->
  10. <!-- Toolbar 的高度layout_height必须固定,不能 “wrap_content”,否则Toolbar不会滑动,也没有折叠效果 -->
  11. <!-- app:contentScrim="?attr/colorPrimary"用于设置收缩的时候Toolbar自动变化到普通的颜色 -->
  12. <!-- app:titleEnabled="false"用于设置是否显示title,默认为显示-->
  13. <android.support.design.widget.CollapsingToolbarLayout
  14. android:id="@+id/collapsingToolbarLayout"
  15. android:layout_width="match_parent"
  16. android:layout_height="match_parent"
  17. app:layout_scrollFlags="scroll|exitUntilCollapsed"
  18. android:fitsSystemWindows="true"
  19. app:contentScrim="?attr/colorPrimary"
  20. app:expandedTitleMarginEnd="64dp"
  21. app:expandedTitleMarginStart="48dp"
  22. app:titleEnabled="false"
  23. >
  24. <!-- 制造视差效果 -->
  25. <!-- CollapsingToolbarLayout还能让我们做出更高级的动画,比如在里面放一个ImageView,然后在它折叠的时候渐渐淡出。同时在用户滚动的时候title的高度也会随着改变。 -->
  26. <!-- 为了制造出这种效果,我们添加一个定义了app:layout_collapseMode="parallax" 属性的ImageView。 -->
  27. <ImageView
  28. android:id="@+id/backdrop"
  29. android:layout_width="match_parent"
  30. android:layout_height="match_parent"
  31. app:layout_collapseMode="parallax"
  32. app:layout_collapseParallaxMultiplier="0.7"
  33. app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
  34. android:fitsSystemWindows="true"
  35. android:scaleType="centerCrop"
  36. android:src="@drawable/bg_login" />
  37. <android.support.v7.widget.Toolbar
  38. android:id="@+id/toolbar"
  39. android:layout_width="match_parent"
  40. android:layout_height="?attr/actionBarSize"
  41. app:layout_collapseMode="pin"
  42. app:layout_scrollFlags="scroll|enterAlways"
  43. app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"
  44. app:titleTextAppearance="@style/TextAppearance.AppCompat.Headline" />
  45. <com.widget.view.CollapsingAvatarToolbar
  46. android:layout_width="match_parent"
  47. android:layout_height="?attr/actionBarSize"
  48. android:gravity="center_vertical"
  49. >
  50. <!--
  51. app:collapsedPadding="@dimen/collapsedPadding"
  52. app:expandedPadding="@dimen/expandedPadding"
  53. app:collapsedImageSize="@dimen/collapsedImageSize"
  54. app:expandedImageSize="@dimen/expandedImageSize"
  55. app:collapsedTextSize="@dimen/collapsedTextSize"
  56. app:expandedTextSize="@dimen/expandedTextSize"
  57. -->
  58. <ImageView
  59. android:id="@id/cat_avatar"
  60. android:layout_width="wrap_content"
  61. android:layout_height="wrap_content"
  62. android:src="@drawable/face"
  63. android:background="@drawable/default_face_bg"
  64. android:padding="4dp"
  65. />
  66. <TextView
  67. android:id="@id/cat_title"
  68. android:layout_width="wrap_content"
  69. android:layout_height="wrap_content"
  70. android:textColor="@android:color/holo_blue_dark"
  71. android:text="Name" />
  72. </com.widget.view.CollapsingAvatarToolbar>
  73. </android.support.design.widget.CollapsingToolbarLayout>
  74. </android.support.design.widget.AppBarLayout>
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:81
帖子:4969
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP