AppBarLayout.OnOffsetChangedListener的使用

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

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值