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中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景