天天看點

仿QQ空間滾動ActionBar透明度變化Demo

QQ空間5.0的ActionBar會随着滾動的距離讓ActionBar的透明度發生變化,效果還是非常cool,自己實作了一個小demo,基本實作了上面的所說的效果,但是其他控件的事件監聽以及一系列較為複雜的控件的沖突還沒考慮,暫時來總結下。

仿QQ空間滾動ActionBar透明度變化Demo

1,實作思路:

在最外層包裹一個自定義的FadingScrollView,監聽滑動事件,然後去滾動控件,不過滾動範圍隻是最上面的fadingView的高度減去actionBar的高度,然後根據已經滾動的距離和fadingView的height來改變actionbar的透明度。還有一點注意讓actionBar懸停在contentView之上。

package huwei.com.fadingactionbardemo;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.v7.app.ActionBar;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ImageView;
import android.widget.LinearLayout;


/**
 * Created by huwei on 15-1-31.
 */
public class FadingScrollView extends LinearLayout {
    private static String TAG = "FadingScrollView";

    private ActionBar mActionBar;
    private Drawable mBgDrawable;

    private ImageView fadingBar;

    private int fadingHeight;   //可隐藏的控件高度
    private int oldY;
    private int fadingOffset;

    public static final int ALPHA_START=20;
    public static final int ALPHA_END=255;

    public FadingScrollView(Context context) {
        this(context, null);
    }

    public FadingScrollView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FadingScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        setOrientation(VERTICAL);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        fadingBar = (ImageView) findViewById(R.id.fading_bar);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        fadingHeight = fadingBar.getMeasuredHeight()-fadingOffset;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                oldY = (int) ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                int scrollY = getScrollY();

                Log.i(TAG, "scrollY:" + scrollY + " ;-fadingHeight" + fadingHeight);
                int y = (int) ev.getY();
                int deltaY = y - oldY;

                int willScrollY = scrollY - deltaY;

                if (willScrollY > fadingHeight) {
                    willScrollY = fadingHeight;
                }

                if (willScrollY < 0) {
                    willScrollY = 0;
                }

                scrollTo(0, willScrollY);
                updateActionBarAlpha(willScrollY*(ALPHA_END-ALPHA_START)/fadingHeight+ALPHA_START);
                oldY = y;

                break;
            case MotionEvent.ACTION_UP:
                break;
        }

        return true;
    }

    public void bindingActionBar(ActionBar actionBar) {
        mActionBar = actionBar;
    }

    public void setActionBarBgDrawable(Drawable bgDrawable) throws Exception{
        if(mActionBar==null){
            throw new Exception("Please try to binding the actionBar before set it's background.");
        }

        mBgDrawable = bgDrawable;
        mBgDrawable.setAlpha(ALPHA_START);
        mActionBar.setBackgroundDrawable(mBgDrawable);
    }
    
    public void setActionBarAlpha(int alpha) throws Exception{
        if(mActionBar==null||mBgDrawable==null){
            throw new Exception("acitonBar is not binding or bgDrawable is not set.");
        }
        mBgDrawable.setAlpha(alpha);
        mActionBar.setBackgroundDrawable(mBgDrawable);
    }
    
    void updateActionBarAlpha(int alpha){
        try {
            setActionBarAlpha(alpha);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
    
    public void setFadingOffset(int height){
        fadingOffset=height;
    }
}
           

2,讓ActionBar懸停。

1)代碼實作:

RequestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
           

2)自定義樣式

<!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light">
        <!-- Customize your theme here. -->
        <item name="windowActionBarOverlay">true</item>
    </style>
           

3,改變透明度

設定背景的Drawable的透明度即可,比如:

mBgDrawable.setAlpha(ALPHA_START);
        mActionBar.setBackgroundDrawable(mBgDrawable);
           

下載下傳位址