顶部布局随ScrollView滑动透明度渐变(QQ空间效果)

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方法就好了。

效果图:                                 


关键代码:

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下载地址



  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值