AppBarLayout.OnOffsetChangedListener的使用

2024-09-04 18:08

本文主要是介绍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> 

这篇关于AppBarLayout.OnOffsetChangedListener的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1136652

相关文章

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

C#中lock关键字的使用小结

《C#中lock关键字的使用小结》在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时,其他线程无法访问同一实例的该代码块,下面就来介绍一下lock关键字的使用... 目录使用方式工作原理注意事项示例代码为什么不能lock值类型在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时