我试图创建一个启动器应用程序,但我有问题时,试图改变API 30编程windowLightStatusBar
和相同的代码工作完美的罚款below,我希望如果有人能帮我:)
下面是完整的类源代码:
public final class AppDrawer extends BottomSheetBehavior.BottomSheetCallback implements OnApplyWindowInsetsListener {
private static boolean ALREADY_CREATED = false;
private AppCompatActivity activity;
private boolean dragging = false;
private float radius;
private int left, right, height, peekOver, oldState;
private Rect displayRect = new Rect();
private DisplayMetrics displayMetrics = new DisplayMetrics();
private Insets navigationBarInsets = Insets.of(0, 0, 0, 0), cutoutInsets = navigationBarInsets;
private WindowInsetsControllerCompat windowInsetsController;
private Configuration oldConfiguration;
private CardView cardView;
private FrameLayout frameLayout;
private BottomSheetBehavior<FrameLayout> bottomSheetBehavior;
public AppDrawer(AppCompatActivity activity){
if(ALREADY_CREATED) throw new IllegalArgumentException("The appDrawer object cannot be created more than once, clear the existing one from the memory first.");
this.activity = activity;
ALREADY_CREATED = true;
}
public void destroy(){
activity = null;
radius = 0.0f;
left = right = height = peekOver = oldState = 0;
displayRect = null;
displayMetrics = null;
navigationBarInsets = cutoutInsets = navigationBarInsets = null;
windowInsetsController = null;
oldConfiguration = null;
cardView = null;
frameLayout = null;
bottomSheetBehavior = null;
ALREADY_CREATED = false;
}
// WindowInsetControllerCompat is created and set from the activity that created this class
public void setWindowInsetsController(@NonNull WindowInsetsControllerCompat windowInsetsController) { this.windowInsetsController = windowInsetsController; }
public void initViews(View contentView){
oldConfiguration = activity.getResources().getConfiguration();
cardView = activity.findViewById(R.id.app_drawer_card_view);
frameLayout = activity.findViewById(R.id.app_drawer_container);
bottomSheetBehavior = BottomSheetBehavior.from(frameLayout);
bottomSheetBehavior.addBottomSheetCallback(this);
ViewCompat.setOnApplyWindowInsetsListener(contentView, this);
updateVars();
}
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
if(dragging) return insets;
cutoutInsets = insets.getInsets(WindowInsetsCompat.Type.displayCutout());
navigationBarInsets = insets.getInsets(WindowInsetsCompat.Type.navigationBars());
updateVars();
if(bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_COLLAPSED) frameLayout.setPadding(left + navigationBarInsets.left, 0, right + navigationBarInsets.right, 0);
return insets;
}
public void setConfiguration(Configuration configuration) { this.oldConfiguration = configuration; }
private void updateWindowInsetsBars(int state){
// here is the one i used
if (state != BottomSheetBehavior.STATE_COLLAPSED && (oldConfiguration.uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_NO) {
windowInsetsController.setAppearanceLightNavigationBars(true);
windowInsetsController.setAppearanceLightStatusBars(true);
} else {
windowInsetsController.setAppearanceLightNavigationBars(false);
windowInsetsController.setAppearanceLightStatusBars(false);
}
// here is the one of @Zain answer
if (state != BottomSheetBehavior.STATE_COLLAPSED && (oldConfiguration.uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_NO) {
new WindowInsetsControllerCompat(activity.getWindow(), activity.getWindow().getDecorView()).setAppearanceLightStatusBars(true);
new WindowInsetsControllerCompat(activity.getWindow(), activity.getWindow().getDecorView()).setAppearanceLightNavigationBars(true);
} else {
new WindowInsetsControllerCompat(activity.getWindow(), activity.getWindow().getDecorView()).setAppearanceLightStatusBars(false);
new WindowInsetsControllerCompat(activity.getWindow(), activity.getWindow().getDecorView()).setAppearanceLightNavigationBars(false);
}
}
private void updateCardViewState(float slideOffset){
float a = 1.f - slideOffset;
cardView.setRadius(radius * a);
frameLayout.setPadding((int) ((left + navigationBarInsets.left) * a) , 0, (int) ((right + navigationBarInsets.right) * a), 0);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) cardView.getLayoutParams();
layoutParams.height = (int) ((displayRect.height() + navigationBarInsets.bottom + cutoutInsets.top + cutoutInsets.bottom) * slideOffset + height * a);
Log.d("AppDrawer", "card height: " + layoutParams.height + ", screen height: " + displayRect.height());
//cardView.setAlpha(Math.min(slideOffset * 1.1f, 1.0f));
cardView.setLayoutParams(layoutParams);
}
private void updateDisplayMetrics(){
WindowManager windowManager = this.activity.getWindowManager();
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R){
displayRect.set(windowManager.getCurrentWindowMetrics().getBounds());
displayRect.bottom -= navigationBarInsets.bottom + cutoutInsets.top + cutoutInsets.bottom;
displayRect.right -= navigationBarInsets.right + cutoutInsets.left + cutoutInsets.right;
} else {
displayRect.top = 0;
displayRect.bottom = displayMetrics.heightPixels;
displayRect.left = 0;
displayRect.right = displayMetrics.widthPixels;
}
}
private void updateVars(){
updateDisplayMetrics();
peekOver = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10f, displayMetrics);
radius = radius == 0 ? cardView.getRadius() : radius;
left = left == 0 ? frameLayout.getPaddingLeft() : left;
right = right == 0 ? frameLayout.getPaddingRight() : right;
height = height == 0 ? cardView.getLayoutParams().height : height;
bottomSheetBehavior.setPeekHeight(height + navigationBarInsets.bottom + peekOver);
if(oldState != 0) updateCardViewState(oldState == BottomSheetBehavior.STATE_COLLAPSED ? 0.0f : 1.0f);
}
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
dragging = newState == BottomSheetBehavior.STATE_DRAGGING;
updateWindowInsetsBars(newState);
oldState = newState;
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) { updateCardViewState(slideOffset); }
}
在API 30上,您可以看到navigationbar
是白色的,而statusbar
仍然是黑色的,即使两者都设置为false
,但它根本不影响statusbar
。
Screenshot-1 on API 30
Screenshot-2 on API 30
但在API 29(低于API 29也能很好地工作)上,它们都很好地进行了更改。
Screenshot-1 on API 29
Screenshot-2 on API 29
3条答案
按热度按时间pdsfdshx1#
这是一个平台错误。https://issuetracker.google.com/issues/180881870
要解决此问题,您只需将
androidx.core:core-ktx
更新为1.8.0-alpha03
或更高版本。详情请参考API变更https://developer.android.com/jetpack/androidx/releases/core#1.8.0-alpha03
fhity93d2#
在测试了一些不同的东西之后,我找到了导致这个问题的原因。
当Activity调用
onCreate()
方法时,setup()
方法会使状态栏/导航栏透明,除了一件事之外,一切都很好,我没有设置window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
,状态栏的变化也很好。希望有人会发现这个有用,而不是像我一样犯愚蠢的错误😅
我发现了真正导致问题的原因,是它补充说:
到themes.xml文件使得设置
statusbar
为光编程不工作,我不知道是什么使导致的问题,但现在我知道了,我不必使用window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
,因为它是在API 30和更高版本的弃用,如@Zain指出。oxosxuxt3#
对我来说,这是因为:
这是阻止我作出改变,以状态栏文本颜色编程!删除后,我可以改变状态栏文本颜色编程再次!我希望这是有用的人!