1.在TabLayout+Fragment+ViewPager中,将ViewPager嵌套在NestedScrollView中,发现TabLayout的tab项只能点击,不能左右滑动切换,解决的方案就是在NestedScrollView控件中添加如下代码即可
android:fillViewport="true"
2.安卓沉浸式适配
亲测可用,包括适配华为虚拟按键和没有虚拟按键的情况.由于vivo虚拟按键的这块我实在不知道怎么处理.故直接做隐藏处理。使用的话直接调用setStatusBarFullTransparent(getWindow(),getResources().getColor(R.color.bg_00DFDFDF));
该代码一般放到BaseActivity后面的setContentView,这样避免了每个界面添加
/**
* 全透状态栏
*/
public static void setStatusBarFullTransparent(Window window, int parseColor) {
if (Build.VERSION.SDK_INT >= 21) {//21表示5.0
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);
if ("vivo".equals(android.os.Build.BRAND) || "oppo".equals(android.os.Build.BRAND)) {
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
hideBottomUIMenu(window); //直接隐藏调虚拟按键
} else {
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); //兼容华为虚拟按键
window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
}
try {
// 设置状态栏底色颜色
window.setStatusBarColor(parseColor);
// 如果亮色,设置状态栏文字为黑色
boolean dark = ColorUtils.calculateLuminance(parseColor) >= 0.5;
if (MIUISetStatusBarLightMode(window, dark)) {
//小米的设置成功
} else if (FlymeSetStatusBarLightMode(window, dark)) {
//魅族的设置成功
} else {
if (ColorUtils.calculateLuminance(parseColor) >= 0.5) {
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
}
}
} catch (Exception e) {
e.printStackTrace();
}
} else{//表示5.0以下
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
/**
* 小米MIUI系统 亲测好用
*
* @param window
* @param dark
* @return
*/
public static boolean MIUISetStatusBarLightMode(Window window, boolean dark) {
boolean result = false;
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;
} catch (Exception e) {
}
}
return result;
}
/**
* 设置状态栏图标为深色和魅族特定的文字风格
* 可以用来判断是否为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;
}
//隐藏虚拟按键
public static void hideBottomUIMenu(Window window) {
//隐藏虚拟按键,并且全屏
if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
View v = window.getDecorView();
v.setSystemUiVisibility(View.GONE);
} else if (Build.VERSION.SDK_INT >= 19) {
WindowManager.LayoutParams params = window.getAttributes();
params.systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|View.SYSTEM_UI_FLAG_IMMERSIVE;
window.setAttributes(params);
}
}
3.安卓xml的形式自定义阴影
这里只设置底部的阴影,如需设置其它的阴影,则设置padding里面的top,lef和right三个方向的阴影,这个基本上可以做通用阴影模块
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<padding
android:bottom="2dp" />
<solid android:color="#0DCCCCCC" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<padding
android:bottom="2dp" />
<solid android:color="#10CCCCCC" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<padding
android:bottom="2dp" />
<solid android:color="#15CCCCCC" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<padding
android:bottom="2dp" />
<solid android:color="#20CCCCCC" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<padding
android:bottom="2dp" />
<solid android:color="#30CCCCCC" />
</shape>
</item>
<item>
<shape>
<solid android:color="#FFFFFF" />
</shape>
</item>
</layer-list>
4.安卓手机系统自带左滑右滑返回事件监听(主要有时候需要自定义自己的返回事件方法)
我这块主要是处理webView里面打开多个网页时返回事件的处理,一定要返回true,不然会受onKeyUp事件的影响
//监听系统滑动返回手势事件(拦截处理)
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP) {
if (binding.webView.canGoBack()) {
binding.webView.goBack();
} else {
setResult(RESULT_OK);
present.finish();
}
}
return true;
}
5.android非常简单的自定义弹出框实现(基本上种下的弹出框都可以套用)
自定义一个View继承者AlertDialog,具体代码实现如下
//通用组件,弹出框位置由View布局文件控制,主要用于底部,中间和顶部位置弹出
public class CurrencyDialog<T extends View> extends AlertDialog {
private T view;
private Boolean cancel = false;
public CurrencyDialog(@NonNull Context context, T view) {
super(context, R.style.dialog);
this.view = view;
}
public <V extends View> V getView(int viewId) {
return view.findViewById(viewId);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.currency_dialog_layout);
FrameLayout frameLayout = findViewById(R.id.frameLayout);
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.alpha = 1f;
lp.width = FrameLayout.LayoutParams.MATCH_PARENT;
lp.height = FrameLayout.LayoutParams.WRAP_CONTENT;
frameLayout.addView(view);
getWindow().setAttributes(lp);
}
}
布局文件如下
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="@+id/frameLayout"
android:layout_height="wrap_content">
</FrameLayout>
代码实现示例
1.1 弹出框布局文件(布局文件建议一定要以RelativeLayout作为根布局,然后通过其设置)
<?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"
android:background="@android:color/transparent"
android:orientation="vertical">
<!-- 最好以RelativeLayout为根布局,然后通过设置-->
<!-- android:layout_centerInParent="true"-->
<!-- android:layout_alignParentBottom="true"-->
<!-- android:layout_alignParentTop="true"-->
<!-- 设置弹出框的位置是居中,底部还是顶部弹出-->
<!-- 记得设置根布局RelativeLayout的 背景色为:-->
<!-- android:background="@android:color/transparent"-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:background="@drawable/drawable_round_edge"
android:orientation="vertical">
<TextView
android:id="@+id/tv2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginTop="30dp"
android:layout_marginRight="50dp"
android:gravity="center"
android:text="退出登录?"
android:textColor="#333333"
android:textSize="16sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<Button
android:id="@+id/cancel"
android:layout_width="120dp"
android:layout_height="38dp"
android:layout_marginTop="30dp"
android:layout_marginBottom="30dp"
android:background="@drawable/button_corner_exit"
android:text="取消"
android:textColor="#666666" />
<Button
android:id="@+id/confirm"
android:layout_width="120dp"
android:layout_height="38dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="30dp"
android:layout_marginBottom="30dp"
android:background="@drawable/button2_corner"
android:text="@string/confirm"
android:textColor="#FFFFFF" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
1.2 java代码中使用
<!-- 初始化弹出框View-->
View quitView= LayoutInflater.from(getContext()).inflate(R.layout.dialog_exit,null,false);
<!--将自定义的弹出框View添加至弹出框布局-->
CurrencyDialog quitDialog=new CurrencyDialog(getContext(), successView);
<!--自定义View弹出框View控件的初始化-->
Button cancel=quitView.findViewById(R.id.cancel);
Button confirm=quitView.findViewById(R.id.confirm);
<!--弹出框弹出和消失方法-->
quitDialog.show();
quitDialog.dismiss();
6.避免点击控件多次跳转问题
<!-- 全局变量-->
public static final int DELAY = 1000;
private static long lastClickTime = 0;
//避免重复点击,将需要执行的代码放到条件为true的判断里面
public static boolean isNotFastClick() {
long currentTime = System.currentTimeMillis();
if (currentTime - lastClickTime > DELAY) {
lastClickTime = currentTime;
return true;
} else {
return false;
}
}