Android 標題欄和狀態列隨ScrollView滑動顏色改變輕鬆實現
阿新 • • 發佈:2019-01-02
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); } }
注:程式碼意思比較簡單,不做過多的解釋