1. 程式人生 > >Android 標題欄和狀態列隨ScrollView滑動顏色改變輕鬆實現

Android 標題欄和狀態列隨ScrollView滑動顏色改變輕鬆實現

01、概述:

在開發過程中,這樣的需求也是常見的,隨著ScrollView 的滑動,標題欄和狀態列背景透明度發生變化。有多中實現方式,在這裡記錄一下自己用到的一種。

02、效果:

03、程式碼實現:

public class ZpScrollViewActivity extends Activity{

    private View titleLine;
    private View titleLine1;
    private LinearLayout title;
    private LinearLayout top;
    private MyScrollView scrollView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scrollview);

        initView();
    }

    private void initView() {
        setTranslucentStatus(this, true);

        title = (LinearLayout) findViewById(R.id.ll_title);
        title.getBackground().mutate().setAlpha(0);
        top = (LinearLayout) findViewById(R.id.ll_title_top);
        titleLine1 = findViewById(R.id.v_title_line_1);
        titleLine = findViewById(R.id.v_title_line);
        scrollView = (MyScrollView) findViewById(R.id.sv_content);

        // 設定狀態列高度
        int statusBarHeight = this.getResources().getDimensionPixelSize(this.getResources().getIdentifier("status_bar_height", "dimen", "android"));
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, statusBarHeight);
        titleLine.setLayoutParams(params);
        titleLine1.setLayoutParams(params);

        // 設定滑動
        scrollView.setOnScrollistener(new MyScrollView.OnScrollistener() {

            @Override
            public void onScroll(int startY, int endY) {
                //根據scrollview滑動更改標題欄透明度
                changeAphla(startY, endY);
            }
        });
    }

    /**
     * 根據內容窗體的移動改變標題欄背景透明度
     *
     * @param startY scrollview開始滑動的y座標(相對值)
     * @param endY   scrollview結束滑動的y座標(相對值)
     */
    private void changeAphla(int startY, int endY) {
        //獲取標題高度
        int titleHeight = title.getMeasuredHeight();
        //獲取背景高度
        int backHeight = top.getMeasuredHeight();

        //獲取控制元件的絕對位置座標
        int[] location = new int[2];
        top.getLocationInWindow(location);
        //從螢幕頂部到控制元件頂部的座標位置Y
        int currentY = location[1];
        //表示回到原位(滑動到頂部)
        if (currentY >= 0) {
            title.getBackground().mutate().setAlpha(0);
        }

        Log.e("zpan", "=titleHeight=" + titleHeight + "=backHeight=" + backHeight + "=currentY=" + currentY);
        //顏色透明度改變
        if (currentY < titleHeight && currentY >= -(backHeight - titleHeight)) {
            //計算出滾動過程中改變的透明值
            double y = Math.abs(currentY) * 1.0;
            double height = (backHeight - titleHeight) * 1.0;
            int changeValue = (int) (y / height * 255);

            Log.e("zpan", "changeValue=" + changeValue);
            //判斷是向上還是向下
            if (endY > startY) {    //向上;透明度值增加,實際透明度減小
                title.getBackground().mutate().setAlpha(changeValue);
            } else if (endY < startY) {     //向下;透明度值減小,實際透明度增加
                title.getBackground().mutate().setAlpha(changeValue);
            }
        }
        //紅色背景移除螢幕
        if (currentY < -(backHeight - titleHeight)) {
            title.getBackground().mutate().setAlpha(255);
        }
    }

    /**
     * 設定狀態列透明
     *
     * @param activity
     * @param on
     */
    public void setTranslucentStatus(Activity activity, boolean on) {
        Window win = activity.getWindow();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            win.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                    | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            win.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
//                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION //保證華為虛擬鍵盤能顯示
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            win.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            win.setStatusBarColor(Color.TRANSPARENT);
//            win.setNavigationBarColor(Color.TRANSPARENT); //保證華為虛擬鍵盤是系統色
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            WindowManager.LayoutParams winParams = win.getAttributes();
            final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
            if (on) {
                winParams.flags |= bits;
            } else {
                winParams.flags &= ~bits;
            }
            win.setAttributes(winParams);
        }
    }
}

注:程式碼裡面的關鍵位置,註釋比較詳細,在這裡就不做過多的介紹,有興趣可以實際的嘗試一下。

04、佈局:activity_scrollview

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <com.example.zpdemo.base.MyScrollView
        android:id="@+id/sv_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <LinearLayout
                android:id="@+id/ll_title_top"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:background="#2c5aff">

                <View
                    android:id="@+id/v_title_line"
                    android:layout_width="match_parent"
                    android:layout_height="0dp"/>

                <View
                    android:layout_width="match_parent"
                    android:layout_height="50dp"/>

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="150dp"
                    android:gravity="center"
                    android:text="狀\n態\n改\n變"
                    android:textColor="#ffffff"
                    android:textSize="24sp"/>

            </LinearLayout>

            <TextView
                android:layout_width="match_parent"
                android:layout_height="600dp"
                android:gravity="center"
                android:background="#b5f581"
                android:text="內\n容\n區\n域"
                android:textColor="#ffffff"
                android:textSize="24sp"/>

        </LinearLayout>
    </com.example.zpdemo.base.MyScrollView>

    <LinearLayout
        android:id="@+id/ll_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:background="#f10303">

        <View
            android:id="@+id/v_title_line_1"
            android:layout_width="match_parent"
            android:layout_height="0dp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:gravity="center"
            android:text="頭部"
            android:textColor="#ffffff"
            android:textSize="18sp"/>

        <View
            android:layout_width="match_parent"
            android:layout_height="2dp"
            android:background="#fff"/>

    </LinearLayout>
</RelativeLayout>

05、自定義ScrollView 滑動事件,是為了處理ScrollView 的向下相容問題
public class MyScrollView extends ScrollView {

    private OnScrollistener onScrollistener;

    public OnScrollistener getOnScrollistener() {
        return onScrollistener;
    }

    public void setOnScrollistener(OnScrollistener onScrollistener) {
        this.onScrollistener = onScrollistener;
    }

    public MyScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyScrollView(Context context) {
        super(context);
    }

    public interface OnScrollistener {

        void onScroll(int startY, int endY);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        onScrollistener.onScroll(oldt, t);
        super.onScrollChanged(l, t, oldl, oldt);
    }
}

注:程式碼意思比較簡單,不做過多的解釋