1.依赖
maven { url "https://jitpack.io" }
//noinspection GradleCompatible
implementation 'com.android.support:design:26.1.0'
//RecyclerView 快速适配器
compile 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30'
//沉浸式的依赖
compile 'com.readystatesoftware.systembartint:systembartint:1.0.3'
2.Style NoActionbar
3.使用NestScrollView 解决 RecyclerView 滑动卡动冲突 也是需要监听的关键
public class MyNestedScrollView extends NestedScrollView {
//重写构造方法 这里让它都去使用第三中构造方法
public MyNestedScrollView(Context context) {
this(context, null);
}
public MyNestedScrollView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
//每次都只会 调用这个方法
public MyNestedScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
//覆写滑动监听方法 再做一个自己的接口
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (mOnScrollViewListenner != null) {
mOnScrollViewListenner.onScrollChanged(this, l, t, oldl, oldt);
}
}
//自定义接口
public interface OnScrollViewListenner {
//把方法放进去 做修改加入本类对象参数
void onScrollChanged(MyNestedScrollView mMyScrollView, int l, int t, int oldl, int oldt);
}
//定义自己的接口变量
private OnScrollViewListenner mOnScrollViewListenner;
//设置Set方法
public void setmOnScrollViewListenner(OnScrollViewListenner mOnScrollViewListenner) {
this.mOnScrollViewListenner = mOnScrollViewListenner;
}
}
4.MainAc整体布局
5.设置状态栏的字体图案颜色 黑/白俩种模式
public class StatusBarUtil {
/**
* 修改状态栏为全透明 * @param activity
*/
@TargetApi(19)
public static void transparencyBar(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = activity.getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window window = activity.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
/**
* 修改状态栏颜色,支持4.4以上版本 * @param activity * @param colorId
*/
public static void setStatusBarColor(Activity activity, int colorId) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = activity.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(activity.getResources().getColor(colorId));
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//使用SystemBarTint库使4.4版本状态栏变色,需要先将状态栏设置为透明
transparencyBar(activity);
SystemBarTintManager tintManager = new SystemBarTintManager(activity);
tintManager.setStatusBarTintEnabled(true);
tintManager.setStatusBarTintResource(colorId);
}
}
/**
* 状态栏亮色模式,设置状态栏黑色文字、图标, * 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android * @param activity * @return 1:MIUUI 2:Flyme 3:android6.0
*/
public static int StatusBarLightMode(Activity activity) {
int result = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (MIUISetStatusBarLightMode(activity, true)) {
result = 1;
} else if (FlymeSetStatusBarLightMode(activity.getWindow(), true)) {
result = 2;
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
result = 3;
}
}
return result;
}
/**
* 已知系统类型时,设置状态栏黑色文字、图标。 * 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android * @param activity * @param type 1:MIUUI 2:Flyme 3:android6.0
*/
public static void StatusBarLightMode(Activity activity, int type) {
if (type == 1) {
MIUISetStatusBarLightMode(activity, true);
} else if (type == 2) {
FlymeSetStatusBarLightMode(activity.getWindow(), true);
} else if (type == 3) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
}
/**
* 状态栏暗色模式,清除MIUI、flyme或6.0以上版本状态栏黑色文字、图标
*/
public static void StatusBarDarkMode(Activity activity, int type) {
if (type == 1) {
MIUISetStatusBarLightMode(activity, false);
} else if (type == 2) {
FlymeSetStatusBarLightMode(activity.getWindow(), false);
} else if (type == 3) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
}
}
/**
* 设置状态栏图标为深色和魅族特定的文字风格 * 可以用来判断是否为Flyme用户 * @param window 需要设置的窗口 * @param dark 是否把状态栏文字及图标颜色设置为深色 * @return boolean 成功执行返回true *
*/
public static boolean FlymeSetStatusBarLightMode(Window window, boolean dark) {
boolean result = false;
if (window != null) {
try {
WindowManager.LayoutParams lp = window.getAttributes();
Field darkFlag = WindowManager.LayoutParams.class.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
Field meizuFlags = WindowManager.LayoutParams.class.getDeclaredField("meizuFlags");
darkFlag.setAccessible(true);
meizuFlags.setAccessible(true);
int bit = darkFlag.getInt(null);
int value = meizuFlags.getInt(lp);
if (dark) {
value |= bit;
} else {
value &= ~bit;
}
meizuFlags.setInt(lp, value);
window.setAttributes(lp);
result = true;
} catch (Exception e) {
}
}
return result;
}
/**
* 需要MIUIV6以上 * @param activity * @param dark 是否把状态栏文字及图标颜色设置为深色 * @return boolean 成功执行返回true *
*/
public static boolean MIUISetStatusBarLightMode(Activity activity, boolean dark) {
boolean result = false;
Window window = activity.getWindow();
if (window != null) {
Class clazz = window.getClass();
try {
int darkModeFlag = 0;
Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
darkModeFlag = field.getInt(layoutParams);
Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
if (dark) {
extraFlagField.invoke(window, darkModeFlag, darkModeFlag); //状态栏透明且黑色字体
} else {
extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字体
}
result = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//开发版 7.7.13 及以后版本采用了系统API,旧方法无效但不会报错,所以两个方式都要加上
if (dark) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
}
}
} catch (Exception e) {
}
}
return result;
}
}
6.自定义LayoutManager也是为了解决滑动卡顿的
public class CustomLinearLayoutManager extends LinearLayoutManager {
private boolean isScrollEnabled = true;
public CustomLinearLayoutManager(Context context) {
super(context);
}
public void setScrollEnabled(boolean flag) {
this.isScrollEnabled = flag;
}
public void setScrollHorizentalEnabled(boolean flag1) {
this.isScrollEnabled = flag1;
}
@Override
public boolean canScrollVertically() {
//Similarly you can customize "canScrollHorizontally()" for managing horizontal scroll
return isScrollEnabled && super.canScrollVertically();
}
@Override
public boolean canScrollHorizontally() {
return isScrollEnabled && super.canScrollVertically();
}
}
7.MainAc
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private RecyclerView myRecyclerView;
private MyNestedScrollView myNestScrollView;
private View view_white;
private ImageView imageback;
private TextView tvColorChange;
private RelativeLayout relatv_change;
private ImageView topImageview;
private int height;// 实时变化的高度
private View viewtiao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
initView();
getHeighOfTopView();
initRecyclerView();
myNestScrollView.setmOnScrollViewListenner(new MyNestedScrollView.OnScrollViewListenner() {
@Override
public void onScrollChanged(MyNestedScrollView mMyScrollView, int l, int t, int oldl, int oldt) {
//对T轴进行判断,就俩种状态1.消失没有了 2.随着滑动,颜色越来越深
if (t <= 0) {//没有往下滑
StatusBarUtil.StatusBarDarkMode(MainActivity.this, 3);
//设置标题隐藏
view_white.setVisibility(View.GONE);
relatv_change.setVisibility(View.GONE);
//设置标题所在背景为透明
relatv_change.setBackgroundColor(Color.argb(0, 0, 0, 0));
viewtiao.setBackgroundColor(Color.argb(0, 0, 0, 0));
}
//大于0表示有位移 正在拖动中,发生颜色变化的同时不超过顶部图片的高度
else if (t > 0 && t < height) {
view_white.setVisibility(View.VISIBLE);
StatusBarUtil.StatusBarLightMode(MainActivity.this);
//显示标题
relatv_change.setVisibility(View.VISIBLE);
//获取ScrollView向下滑动,图片消失部分的比例 注意在配置比例时 一定要强转float
float scale = (float) t / height;
//根据这个比例,让标题的颜色慢慢的由浅入深
float alpha = (255 * scale);
//设置标题的内容和颜色
tvColorChange.setText("我是标题");
tvColorChange.setTextColor(Color.argb((int) alpha, 0, 0, 0));
//设置标题布局颜色
relatv_change.setBackgroundColor(Color.argb((int) alpha, 255, 255, 255));
viewtiao.setBackgroundColor(Color.argb((int) alpha, 255, 255, 255));
} else {
relatv_change.setBackgroundColor(getResources().getColor(R.color.white));
tvColorChange.setTextColor(getResources().getColor(R.color.black));
viewtiao.setBackgroundColor(getResources().getColor(R.color.colorGray));
}
}
});
}
private void initRecyclerView() {
List list = new ArrayList<>();
for (int i = 0; i < 60; i++) {
list.add("第" + i + "条数据");
}
MyAdapter myAdapter = new MyAdapter(R.layout.item, list);
CustomLinearLayoutManager linearLayoutManager = new CustomLinearLayoutManager(this);
linearLayoutManager.setScrollEnabled(false);
myRecyclerView.setAdapter(myAdapter);
myRecyclerView.setLayoutManager(linearLayoutManager);
}
private void getHeighOfTopView() {
//获取控件的试图观察者,以便通过试图观察者得到控件的宽高参数
ViewTreeObserver viewTreeObserver = topImageview.getViewTreeObserver();
//添加观察者监听
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//回调监听后首先移除该监听 占资源
topImageview.getViewTreeObserver().removeOnGlobalLayoutListener(this);
//得到高度
height = topImageview.getHeight();
}
});
}
private void initView() {
myRecyclerView = (RecyclerView) findViewById(R.id.myRecyclerView);
myNestScrollView = (MyNestedScrollView) findViewById(R.id.myNestScrollView);
view_white = (View) findViewById(R.id.view_white);
imageback = (ImageView) findViewById(R.id.imageback);
tvColorChange = (TextView) findViewById(R.id.tvColorChange);
relatv_change = (RelativeLayout) findViewById(R.id.relatv_change);
topImageview = (ImageView) findViewById(R.id.topImageview);
imageback.setOnClickListener(this);
viewtiao = (View) findViewById(R.id.viewtiao);
viewtiao.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.imageback:
Toast.makeText(this, "imageback", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
}
至于RecyclerView Adapter 随意写了.
采用Behavior 实现类似
//https://www.jianshu.com/p/b987fad8fcb4
有俩种
public class SampleTitleBehavior extends CoordinatorLayout.Behavior {
// 列表顶部和title底部重合时,列表的滑动距离。
private float deltaY;
public SampleTitleBehavior() {
}
public SampleTitleBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return dependency instanceof RecyclerView;
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
if (deltaY == 0) {
deltaY = dependency.getY() - child.getHeight();
}
float dy = dependency.getY() - child.getHeight();
dy = dy < 0 ? 0 : dy;
float y = -(dy / deltaY) * child.getHeight();
child.setTranslationY(y);
return true;
}
/* @Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
if (deltaY == 0) {
deltaY = dependency.getY() - child.getHeight();
}
float dy = dependency.getY() - child.getHeight();
dy = dy < 0 ? 0 : dy;
float alpha = 1 - (dy / deltaY);
child.setAlpha(alpha);
//提供一个思路 写在内部类里 然后 传上线文 设置 状态栏 白底黑字
// if(alpha==1){
// }
return true;
}*/
}