转自:http://www.eoeandroid.com/thread-577241-1-1.html

最近看到最美等应用里面有一个特效,自己上网查了下,写了个demo如下:

在写这个demo之前,查了很多资料,主要是参考github上面的一个例子:
https://github.com/ksoichiro/Android-ObservableScrollView

这个例子里面写了很多特效,但是下载下来后,导入Studio里面很多错误,无法跑起来,所以,自己抠了其中的一个特效,修改了一些代码,效果如上图所示。

主要代码片段:(后面会有解释)

  1. import android.content.res.TypedArray;
  2. import android.graphics.Color;
  3. import android.os.Bundle;
  4. import android.support.v7.app.ActionBarActivity;
  5. import android.support.v7.widget.Toolbar;
  6. import android.util.TypedValue;
  7. import android.view.Menu;
  8. import android.view.MenuItem;
  9. import android.view.View;
  10. import android.widget.TextView;
  11. import com.nineoldandroids.view.ViewHelper;
  12. public class MainActivity extends ActionBarActivity implements ObservableScrollViewCallbacks{
  13. private static final float MAX_TEXT_SCALE_DELTA = 0.3f;
  14. private static final boolean TOOLBAR_IS_STICKY = true;
  15. private View mToolbar;
  16. private View mImageView;
  17. private View mOverlayView;
  18. private ObservableScrollView mScrollView;
  19. private TextView mTitleView;
  20. private View mFab;
  21. private int mActionBarSize;
  22. private int mFlexibleSpaceShowFabOffset;
  23. private int mFlexibleSpaceImageHeight;
  24. private int mToolbarColor;
  25. @Override
  26. protected void onCreate(Bundle savedInstanceState) {
  27. super.onCreate(savedInstanceState);
  28. setContentView(R.layout.activity_main);
  29. setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
  30. mFlexibleSpaceImageHeight = getResources().getDimensionPixelSize(R.dimen.flexible_space_image_height);
  31. mActionBarSize = getActionBarSize();
  32. mToolbarColor = getResources().getColor(R.color.primary);
  33. mToolbar = findViewById(R.id.toolbar);
  34. if (!TOOLBAR_IS_STICKY) {
  35. mToolbar.setBackgroundColor(Color.TRANSPARENT);
  36. }
  37. mImageView = findViewById(R.id.image);
  38. mOverlayView = findViewById(R.id.overlay);
  39. mScrollView = (ObservableScrollView) findViewById(R.id.scroll);
  40. mScrollView.setScrollViewCallbacks(this);
  41. mTitleView = (TextView) findViewById(R.id.title);
  42. mTitleView.setText(getTitle());
  43. setTitle(null);
  44. ScrollUtils.addOnGlobalLayoutListener(mScrollView, new Runnable() {
  45. @Override
  46. public void run() {
  47. mScrollView.scrollTo(0, mFlexibleSpaceImageHeight - mActionBarSize);
  48. }
  49. });
  50. }
  51. @Override
  52. public boolean onCreateOptionsMenu(Menu menu) {
  53. // Inflate the menu; this adds items to the action bar if it is present.
  54. getMenuInflater().inflate(R.menu.menu_main, menu);
  55. return true;
  56. }
  57. @Override
  58. public boolean onOptionsItemSelected(MenuItem item) {
  59. // Handle action bar item clicks here. The action bar will
  60. // automatically handle clicks on the Home/Up button, so long
  61. // as you specify a parent activity in AndroidManifest.xml.
  62. int id = item.getItemId();
  63. //noinspection SimplifiableIfStatement
  64. return super.onOptionsItemSelected(item);
  65. }
  66. protected int getActionBarSize() {
  67. TypedValue typedValue = new TypedValue();
  68. int[] textSizeAttr = new int[]{R.attr.actionBarSize};
  69. int indexOfAttrTextSize = 0;
  70. TypedArray a = obtainStyledAttributes(typedValue.data, textSizeAttr);
  71. int actionBarSize = a.getDimensionPixelSize(indexOfAttrTextSize, -1);
  72. a.recycle();
  73. return actionBarSize;
  74. }
  75. @Override
  76. public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
  77. float flexibleRange = mFlexibleSpaceImageHeight - mActionBarSize;
  78. int minOverlayTransitionY = mActionBarSize - mOverlayView.getHeight();
  79. ViewHelper.setTranslationY(mOverlayView, ScrollUtils.getFloat(-scrollY, minOverlayTransitionY, 0));
  80. ViewHelper.setTranslationY(mImageView, ScrollUtils.getFloat(-scrollY / 2, minOverlayTransitionY, 0));
  81. // Change alpha of overlay
  82. ViewHelper.setAlpha(mOverlayView, ScrollUtils.getFloat((float) scrollY / flexibleRange, 0, 1));
  83. // Scale title text
  84. float scale = 1 + ScrollUtils.getFloat((flexibleRange - scrollY) / flexibleRange, 0, MAX_TEXT_SCALE_DELTA);
  85. ViewHelper.setPivotX(mTitleView, 0);
  86. ViewHelper.setPivotY(mTitleView, 0);
  87. ViewHelper.setScaleX(mTitleView, scale);
  88. ViewHelper.setScaleY(mTitleView, scale);
  89. // Translate title text
  90. int maxTitleTranslationY = (int) (mFlexibleSpaceImageHeight - mTitleView.getHeight() * scale);
  91. int titleTranslationY = maxTitleTranslationY - scrollY;
  92. if (TOOLBAR_IS_STICKY) {
  93. titleTranslationY = Math.max(0, titleTranslationY);
  94. }
  95. ViewHelper.setTranslationY(mTitleView, titleTranslationY);
  96. if (TOOLBAR_IS_STICKY) {
  97. // Change alpha of toolbar background
  98. if (-scrollY + mFlexibleSpaceImageHeight <= mActionBarSize) {
  99. mToolbar.setBackgroundColor(ScrollUtils.getColorWithAlpha(1, mToolbarColor));
  100. } else {
  101. mToolbar.setBackgroundColor(ScrollUtils.getColorWithAlpha(0, mToolbarColor));
  102. }
  103. } else {
  104. // Translate Toolbar
  105. if (scrollY < mFlexibleSpaceImageHeight) {
  106. ViewHelper.setTranslationY(mToolbar, 0);
  107. } else {
  108. ViewHelper.setTranslationY(mToolbar, -scrollY);
  109. }
  110. }
  111. }
  112. @Override
  113. public void onDownMotionEvent() {
  114. }
  115. @Override
  116. public void onUpOrCancelMotionEvent(ScrollState scrollState) {
  117. }
  118. }

复制代码

activity_main.xml文件

  1. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:app="http://schemas.android.com/apk/res-auto"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent">
  5. <ImageView
  6. android:id="@+id/image"
  7. android:layout_width="match_parent"
  8. android:layout_height="@dimen/flexible_space_image_height"
  9. android:scaleType="centerCrop"
  10. android:src="@mipmap/ic_pic" />
  11. <View
  12. android:id="@+id/overlay"
  13. android:layout_width="match_parent"
  14. android:layout_height="@dimen/flexible_space_image_height"
  15. android:background="?attr/colorPrimary" />
  16. <com.picasso.observablescrollviewdemo.ObservableScrollView
  17. android:id="@+id/scroll"
  18. android:layout_width="match_parent"
  19. android:layout_height="match_parent"
  20. android:overScrollMode="never"
  21. android:scrollbars="none">
  22. <LinearLayout
  23. android:layout_width="match_parent"
  24. android:layout_height="wrap_content"
  25. android:orientation="vertical">
  26. <View
  27. android:layout_width="match_parent"
  28. android:layout_height="@dimen/flexible_space_image_height"
  29. android:background="@android:color/transparent" />
  30. <TextView
  31. android:layout_width="match_parent"
  32. android:layout_height="wrap_content"
  33. android:background="@android:color/white"
  34. android:paddingBottom="@dimen/activity_vertical_margin"
  35. android:paddingLeft="@dimen/activity_horizontal_margin"
  36. android:paddingRight="@dimen/activity_horizontal_margin"
  37. android:paddingTop="@dimen/activity_vertical_margin"
  38. android:text="@string/desc" />
  39. </LinearLayout>
  40. </com.picasso.observablescrollviewdemo.ObservableScrollView>
  41. <android.support.v7.widget.Toolbar
  42. android:id="@+id/toolbar"
  43. android:layout_width="match_parent"
  44. android:layout_height="wrap_content"
  45. android:background="?attr/colorPrimary"
  46. android:minHeight="?attr/actionBarSize"
  47. app:popupTheme="@style/Theme.AppCompat.Light.DarkActionBar"
  48. />
  49. <LinearLayout
  50. android:layout_width="match_parent"
  51. android:layout_height="wrap_content"
  52. android:orientation="vertical"
  53. >
  54. <TextView
  55. android:id="@+id/title"
  56. android:layout_width="match_parent"
  57. android:layout_height="wrap_content"
  58. android:ellipsize="end"
  59. android:gravity="center_vertical"
  60. android:maxLines="1"
  61. android:minHeight="?attr/actionBarSize"
  62. android:textColor="@android:color/white"
  63. android:text="Make Attractive"
  64. android:paddingLeft="@dimen/activity_vertical_margin"
  65. android:textSize="20sp" />
  66. <View
  67. android:layout_width="match_parent"
  68. android:layout_height="@dimen/flexible_space_image_height"
  69. android:background="@android:color/transparent" />
  70. </LinearLayout>
  71. </FrameLayout>

复制代码

其实,效果实现很简单,控件ObservableScrollView主要是继承了ScrollView并实现了Scrollable接口,在MainActivity中,重写onScrollChanged方法,在方法中,主要做了这几部操作:
1、随着滑动,让图片mImageView上移
2、随着滑动,让盖在图片上的view上移,长度是imageView上移的2倍
3、随着滑动,让盖在图片上的view的alpha值逐渐变大(就是那个渐渐变绿的效果)
4、随着滑动,让Title的字体逐渐变小并让title上移到ToolBar的位置
5、当滑动到ToolBar的位置时,让ToolBar显示

下载源码如下:

 ObservableScrollViewDemo.rar 

android 一个很漂亮的控件ObservableScrollView(含片段代码和源码)相关推荐

  1. 一步步教你如何定制一个Android「填空题」控件(仿学习强国填空题控件)

    一.写在前面 开始之前,老规矩,絮絮叨叨. 本文讲解的是如何自定义一个填空题控件,实现的方式其实有很多,最重要的是了解其中实现的思路和想法,正所谓条条大路通罗马嘛. 在Android系统中,我们最常使 ...

  2. android仿小米日历,实现一个仿小米日历控件

    先看效果图: 效果图 根据效果,我们可以看到,要实现该控件,需要具备: 容器以及触摸事件处理 周日历布局以及选择,切换上下周处理 月日历布局以及选择,切换上下月处理 首先说说容器 对于其他使用者来说, ...

  3. Study on Android【四】--显示控件使用

    Android的界面显示同样也是基于控件的.通常是用View(包括ViewGroup)控件配上XML的样式来做的.具体细节不想说了,可以参考 Samples里的ApiDemos/View,和View的 ...

  4. android将被代替的控件,Android 控件被忽略的属性

    作者:ivm 参考了 http://www.cnblogs.com/jisheng/archive/2013/01/10/2854088.html 导航栏: 1.TextView autoLink H ...

  5. Android:Socket客户端开发,Android 的Socket客户端优化,Android非UI线程修改控件程序崩溃的问题

    一.Android:Socket客户端开发 创建一个工程 我们要做的是按下按键之后,去往服务器 (服务器) 或者我们自己写的服务器 ,给他发送一些预定好的东西 然后打开操作界面 然后修改一下 你要发送 ...

  6. Android开发三:常用控件1--TextView、EditText、Button

    上一节写到android的工程目录结构,这一节继续,开始学习控件,中间的跨度挺大,关于Activity和intent的知识我就略过了,原因很简单,网上的关于那个的资料特别多,而且理论的东西我这都是了解 ...

  7. Android开发的之基本控件和详解四种布局方式

    Android中的控件的使用方式和iOS中控件的使用方式基本相同,都是事件驱动.给控件添加事件也有接口回调和委托代理的方式.今天这篇博客就总结一下Android中常用的基本控件以及布局方式.说到布局方 ...

  8. android菜鸟学习笔记13----Android控件(二) 自定义控件简单示例

    有时候,可能觉得系统提供的控件太丑,就会需要自定义控件来实现自己想要的效果. 以下主要参考<第一行代码> 1.自定义一个标题栏: 系统自带的标题栏很丑,且没什么大的作用,所以我们之前会在o ...

  9. Android微信九宫格图片展示控件

    版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/214 Android微信九宫格图片展示控件 半年前,公司产 ...

最新文章

  1. java重命名sheet失败_java jxl excel 数据导出 重新命名无效的工作表名称 | 学步园...
  2. python udp客户端 服务器实现方式_python3实现UDP协议的简单服务器和客户端
  3. vb microsoft.xmlhttp 获取所有超链接_编写我的第一个VB程序
  4. HTTP协议编程,实现文件上传,Android客户端代码
  5. 回归、自回归、循环神经网络(RNN)、LSTM
  6. 人人网是明文传输,所以只要抓包就能知道用户名和密码
  7. NSA机密文件泄密者如何暴露身份
  8. 【laravel-admin】权限管理与实现原理
  9. 浅谈jodaTime 的使用
  10. Ubuntu18.04 因断电开机报错:utmp处卡死
  11. 信息安全意识培训非常重要
  12. linux下使用动态壁纸
  13. c语言用break语句提前结束循环,break语句C语言程序设计.pdf
  14. 贴片绕线电感和贴片电感的区别
  15. 机器人需要Matlab嘛,用MATLAB玩转机器人
  16. .NET进阶篇-丑话先说,Flag先立
  17. 软工作业 2:时事点评-红芯浏览器事件
  18. Linux IGMP SNOOPING 学习笔记 之三 igmp snooping实现需求分析
  19. 不明恶意攻击致搜狗搜索搜索结果跳转百度搜索技术原理分析
  20. 洛谷——P1017 [NOIP2000 提高组] 进制转换(C++)

热门文章

  1. python openstack oslo_config使用_OpenStack配置解析库oslo.config的使用方法
  2. android 重启app_[Boot]Android系统启动-zygote篇
  3. 剑指offer-斐波那契数列
  4. 解决 iOS 11 webview 顶部空白条的问题
  5. 汇编指令CALL与JMP的区别
  6. 如何成为优秀的程序员
  7. LeetCode每日一题 24. 两两交换链表中的节点
  8. Tarjan 强连通分量
  9. fgets函数及其用法,C语言fgets函数详解
  10. c++ primer 5th,练习11.19,编写代码验证