顶部布局随ScrollView滑动透明度渐变(QQ空间效果)
2016-03-30 18:57
483 查看
QQ控件顶部的工具条在整体的ScrollView从顶部滑动时会从透明逐渐变为solid纯色;虽然有人实现过 ActionBar随ScorllView上下拖动而透明度渐变效果 以及 仿QQ空间滚动ActionBar透明度变化Demo ,但是两者存在以下问题:
1、前者的适用范围是ActionBar+ScrollView,但是实际中顶部的布局可能是任何view类型,即适用性不够宽;
2、后者的实现是通过重写ScrollView的onTouchEvent来实现的,但是这样有弊端:因为是监听的触摸事件,所以在我们进行“用力滑一下靠惯性就让ScrollView自己滚动到底部或顶部”的操作时(其实就是FLING啦),触摸事件是监听不到的,就会出现透明度显示错误的bug。
综上,我实现的方式是:
重写ScrollView的onScrollChanged方法,自定义一个公共的OnScrollChangedListener接口(因为Activity里面是无法直接使用OnScrollChangedListener的),并暴露一个setOnScrollChangedListener用来让Activity设置并监听滚动事件,在接口实现当中就可以放入我们的透明度渐变效果啦。
透明度渐变其实很简单,使用Drawable的setAlpha方法,之后再对任何类型的顶部布局(view或viewgroup都行)调用setBackgroundDrawable方法就好了。
效果图:
关键代码:
demo下载地址
1、前者的适用范围是ActionBar+ScrollView,但是实际中顶部的布局可能是任何view类型,即适用性不够宽;
2、后者的实现是通过重写ScrollView的onTouchEvent来实现的,但是这样有弊端:因为是监听的触摸事件,所以在我们进行“用力滑一下靠惯性就让ScrollView自己滚动到底部或顶部”的操作时(其实就是FLING啦),触摸事件是监听不到的,就会出现透明度显示错误的bug。
综上,我实现的方式是:
重写ScrollView的onScrollChanged方法,自定义一个公共的OnScrollChangedListener接口(因为Activity里面是无法直接使用OnScrollChangedListener的),并暴露一个setOnScrollChangedListener用来让Activity设置并监听滚动事件,在接口实现当中就可以放入我们的透明度渐变效果啦。
透明度渐变其实很简单,使用Drawable的setAlpha方法,之后再对任何类型的顶部布局(view或viewgroup都行)调用setBackgroundDrawable方法就好了。
效果图:
关键代码:
package com.example.alphatop; import com.example.alphatop.myScrollView.OnScrollChangedListener; import android.app.Activity; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.widget.LinearLayout; import android.widget.ScrollView; public class MainActivity extends Activity { private LinearLayout titleLayout; //顶部渐变布局 private myScrollView scrollView; //整体ScrollView private static final int START_ALPHA = 0; private static final int END_ALPHA = 255; private int fadingHeight = 600; //当ScrollView滑动到什么位置时渐变消失(根据需要进行调整) private Drawable drawable; //顶部渐变布局需设置的Drawable @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); titleLayout = (LinearLayout) findViewById(R.id.linear); scrollView = (myScrollView) findViewById(R.id.scrollview); drawable = getResources().getDrawable(R.drawable.color_exam_grey); drawable.setAlpha(START_ALPHA); titleLayout.setBackgroundDrawable(drawable); scrollView.setOnScrollChangedListener(scrollChangedListener); } /** * 公共接口:ScrollView的滚动监听 */ private OnScrollChangedListener scrollChangedListener = new OnScrollChangedListener() { @Override public void onScrollChanged(ScrollView who, int x, int y, int oldx, int oldy) { if (y > fadingHeight) { y = fadingHeight; //当滑动到指定位置之后设置颜色为纯色,之前的话要渐变---实现下面的公式即可 } drawable.setAlpha(y * (END_ALPHA - START_ALPHA) / fadingHeight + START_ALPHA); } }; }
package com.example.alphatop; import android.content.Context; import android.util.AttributeSet; import android.widget.ScrollView; public class myScrollView extends ScrollView { public myScrollView(Context context) { super(context); } public myScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public myScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /** * 公共接口:ScrollView滚动监听 */ public interface OnScrollChangedListener { void onScrollChanged(ScrollView who, int x, int y, int oldx, int oldy); } private OnScrollChangedListener mOnScrollChangedListener; @Override protected void onScrollChanged(int x, int y, int oldx, int oldy) { super.onScrollChanged(x, y, oldx, oldy); if (mOnScrollChangedListener != null) { //使用公共接口触发滚动信息的onScrollChanged方法,将滚动位置信息暴露给外部 mOnScrollChangedListener.onScrollChanged(this, x, y, oldx, oldy); } } /** * 暴露给外部的方法:设置滚动监听 * @param listener */ public void setOnScrollChangedListener(OnScrollChangedListener listener) { mOnScrollChangedListener = listener; } }
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="${relativePackage}.${activityClass}" > <com.example.alphatop.myScrollView android:id="@+id/scrollview" android:layout_width="match_parent" android:layout_height="wrap_content" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <ImageView android:layout_width="match_parent" android:layout_height="200dp" android:background="@color/color_pink" android:contentDescription="@null" /> <ImageView android:layout_width="match_parent" android:layout_height="1000dp" android:background="@color/color_blue" android:contentDescription="@null" /> </LinearLayout> </com.example.alphatop.myScrollView> <LinearLayout android:id="@+id/linear" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:gravity="center_horizontal" android:text="title bar" /> <ImageView android:layout_width="match_parent" android:layout_height="2dp" android:src="@color/color_grey" android:contentDescription="@null" /> </LinearLayout> </RelativeLayout>
demo下载地址
相关文章推荐
- sql获取该周的开始结束日期
- EventBus3.0源码解析
- 【NLP】Tika 文本预处理:抽取各种格式文件内容
- IOS-推送通知
- [Xcode]Xcode自动打ipa包脚本
- SQL索引介绍
- 【译】Java 8的新特性—终极版
- Linux具体权限规划之ACL(Access Control List)
- IOS学习之——导航控制器 UINavigationController
- [UWP]一种利用Behavior 将StateTrigger集中管理的方案
- 《linux内核设计与实现》读书笔记第三章
- codeforces-597C-Subsequences【树状数组】
- 判断一棵树是否是二叉查找树
- Oracle之高级查询
- spring学习
- 微信支付v3开发(6) 收货地址共享接口
- 微信支付v3开发(6) 收货地址共享接口
- puppet的概述和架构
- 借助链表解决猴子选大王问题(约瑟夫环问题)
- 装饰模式笔试