概述
在开发过程中,这样的需求也是常见的,随着ScrollView 的滑动,标题栏和状态栏背景透明度发生变化。有多中实现方式,在这里记录一下自己用到的一种。
效果
待上传
代码实现
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);
}
}
}
注:代码里面的关键位置,注释比较详细,在这里就不做过多的介绍,有兴趣可以实际的尝试一下。
布局: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>
自定义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);
}
}
注:代码意思比较简单,不做过多的解释