热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android仿简书动态searchview搜索栏效果

这篇文章主要为大家详细介绍了Android仿简书动态searchview效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

简书的动态搜索栏效果是这样的,挺高大上的感觉。


ezgif.com-resize.gif

仔细想一下,其实实现起来非常简单,这是我做的效果,基本完美还原。


ezgif.com-resize (2).gif

实现这个效果, 只要关注几个点

1.搜索栏伸展和收缩动画效果实现
2.搜索栏伸展和收缩的时机
3.顶部透明度的渐变

搜索栏伸展和收缩动画效果实现:

我们只要明确,使用系统为我们提供的Transition框架,就可以轻而易举的实现了。
首先要引入依赖compile 'com.android.support:design:25.3.1',要知道我们使用到的这部分Transition效果只是封装了属性动画的内容,是可以兼容到5.0之前的。

private void expand() {
 //设置伸展状态时的布局
 tvSearch.setText("搜索简书的内容和朋友");
 RelativeLayout.LayoutParams LayoutParams = (RelativeLayout.LayoutParams) mSearchLayout.getLayoutParams();
 LayoutParams.width = LayoutParams.MATCH_PARENT;
 LayoutParams.setMargins(dip2px(10), dip2px(10), dip2px(10), dip2px(10));
 mSearchLayout.setLayoutParams(LayoutParams);
 //设置动画
 beginDelayedTransition(mSearchLayout);
 }

 private void reduce() {
 //设置收缩状态时的布局
 tvSearch.setText("搜索");
 RelativeLayout.LayoutParams LayoutParams = (RelativeLayout.LayoutParams) mSearchLayout.getLayoutParams();
 LayoutParams.width = dip2px(80);
 LayoutParams.setMargins(dip2px(10), dip2px(10), dip2px(10), dip2px(10));
 mSearchLayout.setLayoutParams(LayoutParams);
 //设置动画
 beginDelayedTransition(mSearchLayout);
 }

 void beginDelayedTransition(ViewGroup view) {
 mSet = new AutoTransition();
 //设置动画持续时间
 mSet.setDuration(300);
 // 开始表演
 TransitionManager.beginDelayedTransition(view, mSet);
 }

其中mSearchLayout就是搜索框的布局,只需要动态设置一下伸展和收缩的布局大小和其中显示的文字,剩下的就交给Transition吧~ 这样搜索框就可以来回摇摆了。。

搜索栏伸展和收缩的时机:

观察一下效果,伸展的时机是当顶部完全盖住banner的时候开始的,收缩的时机是滚动到顶部的时候触发。需要我们监听scllerview的滚动状态。这里的顶部我是用了自定义布局的toolbar,然后用一个imageview代替了banner。

//scrollview滚动状态监听
 mScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
  @Override
  public void onScrollChanged() {
  //改变toolbar的透明度
  changeToolbarAlpha();
  //滚动距离>=大图高度-toolbar高度 即toolbar完全盖住大图的时候 且不是伸展状态 进行伸展操作
  if (mScrollView.getScrollY() >=ivImg.getHeight() - toolbar.getHeight() && !isExpand) {
   expand();
   isExpand = true;
  }
  //滚动距离<=0时 即滚动到顶部时 且当前伸展状态 进行收缩操作
  else if (mScrollView.getScrollY()<=0&& isExpand) {
   reduce();
   isExpand = false;
  }
  }
 });
 }

当然简书的整个布局是基于recyclerview的,这里我为了方便使用了scrollerview。recyclerview也只需监听相应的滚动状态即可。

顶部透明度的渐变

直接上代码

 private void changeToolbarAlpha() {
 int scrollY = mScrollView.getScrollY();
 //快速下拉会引起瞬间scrollY<0
 if(scrollY<0){
  toolbar.getBackground().mutate().setAlpha(0);
  return;
 }
 //计算当前透明度比率
 float radio= Math.min(1,scrollY/(ivImg.getHeight()-toolbar.getHeight()*1f));
 //设置透明度
 toolbar.getBackground().mutate().setAlpha( (int)(radio * 0xFF));
 }

注意刚才监听滚动事件的时候调用changeToolbarAlpha()方法,并且需要初始设置为全透明
toolbar.getBackground().mutate().setAlpha(0);

好了关键代码就这么多点了~

下面附上完整代码

布局文件

<&#63;xml version="1.0" encoding="utf-8"&#63;>

 
 
 
 
 
 
  

  
  
 
 


就一个activity

public class MainActivity extends AppCompatActivity {
 @Bind(R.id.tv_search)
 TextView tvSearch;
 @Bind(R.id.ll_search)
 LinearLayout mSearchLayout;
 @Bind(R.id.scrollView)
 ScrollView mScrollView;
 boolean isExpand = false;
 @Bind(R.id.iv_img)
 ImageView ivImg;
 @Bind(R.id.toolbar)
 Toolbar toolbar;
 private TransitionSet mSet;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 ButterKnife.bind(this);
 //设置全屏透明状态栏
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  ViewGroup rootView = (ViewGroup) ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0);
  ViewCompat.setFitsSystemWindows(rootView,false);
  rootView.setClipToPadding(true);
 }
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS|
   WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
 getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
 getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

  getWindow().setStatusBarColor(Color.TRANSPARENT);
 }
 //设置toolbar初始透明度为0
 toolbar.getBackground().mutate().setAlpha(0);
 //scrollview滚动状态监听
 mScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
  @Override
  public void onScrollChanged() {
  //改变toolbar的透明度
  changeToolbarAlpha();
  //滚动距离>=大图高度-toolbar高度 即toolbar完全盖住大图的时候 且不是伸展状态 进行伸展操作
  if (mScrollView.getScrollY() >=ivImg.getHeight() - toolbar.getHeight() && !isExpand) {
   expand();
   isExpand = true;
  }
  //滚动距离<=0时 即滚动到顶部时 且当前伸展状态 进行收缩操作
  else if (mScrollView.getScrollY()<=0&& isExpand) {
   reduce();
   isExpand = false;
  }
  }
 });
 }

 private void changeToolbarAlpha() {
 int scrollY = mScrollView.getScrollY();
 //快速下拉会引起瞬间scrollY<0
 if(scrollY<0){
  toolbar.getBackground().mutate().setAlpha(0);
  return;
 }
 //计算当前透明度比率
 float radio= Math.min(1,scrollY/(ivImg.getHeight()-toolbar.getHeight()*1f));
 //设置透明度
 toolbar.getBackground().mutate().setAlpha( (int)(radio * 0xFF));
 }


 private void expand() {
 //设置伸展状态时的布局
 tvSearch.setText("搜索简书的内容和朋友");
 RelativeLayout.LayoutParams LayoutParams = (RelativeLayout.LayoutParams) mSearchLayout.getLayoutParams();
 LayoutParams.width = LayoutParams.MATCH_PARENT;
 LayoutParams.setMargins(dip2px(10), dip2px(10), dip2px(10), dip2px(10));
 mSearchLayout.setLayoutParams(LayoutParams);
 //开始动画
 beginDelayedTransition(mSearchLayout);
 }

 private void reduce() {
 //设置收缩状态时的布局
 tvSearch.setText("搜索");
 RelativeLayout.LayoutParams LayoutParams = (RelativeLayout.LayoutParams) mSearchLayout.getLayoutParams();
 LayoutParams.width = dip2px(80);
 LayoutParams.setMargins(dip2px(10), dip2px(10), dip2px(10), dip2px(10));
 mSearchLayout.setLayoutParams(LayoutParams);
 //开始动画
 beginDelayedTransition(mSearchLayout);
 }

 void beginDelayedTransition(ViewGroup view) {
 mSet = new AutoTransition();
 mSet.setDuration(300);
 TransitionManager.beginDelayedTransition(view, mSet);
 }

 private int dip2px(float dpVale) {
 final float scale = getResources().getDisplayMetrics().density;
 return (int) (dpVale * scale + 0.5f);
 }
}

更完整的在这里https://github.com/yanyiqun001/dymicSearchview 希望大家多多支持

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 嵌入式开发环境搭建与文件传输指南
    本文详细介绍了如何为嵌入式应用开发搭建必要的软硬件环境,并提供了通过串口和网线两种方式将文件传输到开发板的具体步骤。适合Linux开发初学者参考。 ... [详细]
  • 本文探讨了如何在Classic ASP中实现与PHP的hash_hmac('SHA256', $message, pack('H*', $secret))函数等效的哈希生成方法。通过分析不同实现方式及其产生的差异,提供了一种使用Microsoft .NET Framework的解决方案。 ... [详细]
  • 在项目部署后,Node.js 进程可能会遇到不可预见的错误并崩溃。为了及时通知开发人员进行问题排查,我们可以利用 nodemailer 插件来发送邮件提醒。本文将详细介绍如何配置和使用 nodemailer 实现这一功能。 ... [详细]
  • C#设计模式学习笔记:观察者模式解析
    本文将探讨观察者模式的基本概念、应用场景及其在C#中的实现方法。通过借鉴《Head First Design Patterns》和维基百科等资源,详细介绍该模式的工作原理,并提供具体代码示例。 ... [详细]
  • 简化报表生成:EasyReport工具的全面解析
    本文详细介绍了EasyReport,一个易于使用的开源Web报表工具。该工具支持Hadoop、HBase及多种关系型数据库,能够将SQL查询结果转换为HTML表格,并提供Excel导出、图表显示和表头冻结等功能。 ... [详细]
  • Git管理工具SourceTree安装与使用指南
    本文详细介绍了Git管理工具SourceTree的安装、配置及团队协作方案,旨在帮助开发者更高效地进行版本控制和项目管理。 ... [详细]
  • Win11 22563右键单击Windows图标还原方法
    有小伙伴安装了Win1122563,发现出现了右键单击任务栏中的Windows图标或Windows键+X将导致explorerexe崩溃,而且一直出现循环启动,这要怎么解 ... [详细]
  • 本文探讨了在使用Selenium进行自动化测试时,由于webdriver对象实例化位置不同而导致浏览器闪退的问题,并提供了详细的代码示例和解决方案。 ... [详细]
  • 解决Anaconda安装TensorFlow时遇到的TensorBoard版本问题
    本文介绍了在使用Anaconda安装TensorFlow时遇到的“Could not find a version that satisfies the requirement tensorboard”错误,并提供详细的解决方案,包括创建虚拟环境和配置PyCharm项目。 ... [详细]
  • Windows 7 64位系统下Redis的安装与PHP Redis扩展配置
    本文详细介绍了在Windows 7 64位操作系统中安装Redis以及配置PHP Redis扩展的方法,包括下载、安装和基本使用步骤。适合对Redis和PHP集成感兴趣的开发人员参考。 ... [详细]
  • 解决TensorFlow CPU版本安装中的依赖问题
    本文记录了在安装CPU版本的TensorFlow过程中遇到的依赖问题及解决方案,特别是numpy版本不匹配和动态链接库(DLL)错误。通过详细的步骤说明和专业建议,帮助读者顺利安装并使用TensorFlow。 ... [详细]
  • ListView简单使用
    先上效果:主要实现了Listview的绑定和点击事件。项目资源结构如下:先创建一个动物类,用来装载数据:Animal类如下:packagecom.example.simplelis ... [详细]
  • JavaScript 中创建对象的多种方式
    本文介绍了 JavaScript 中创建对象的几种常见方法,包括字面量形式、构造函数、原型对象等。每种方法都有其特点和适用场景,通过对比分析,帮助开发者选择最适合的方式。 ... [详细]
  • 在成功安装和测试MySQL及Apache之后,接下来的步骤是安装PHP。为了确保安全性和配置的一致性,建议在安装PHP前先停止MySQL和Apache服务,并将MySQL集成到PHP中。 ... [详细]
  • Python处理Word文档的高效技巧
    本文详细介绍了如何使用Python处理Word文档,涵盖从基础操作到高级功能的各种技巧。我们将探讨如何生成文档、定义样式、提取表格数据以及处理超链接和图片等内容。 ... [详细]
author-avatar
人心城府深我如z何故做清纯
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有