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

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念