4

为了使用 anko DSL 测试 kotlin,我决定在最后一个 android studio ide (2.1.3) 中启动一个新项目,使用 kotlin 插件 (1.0.3) 和最新的 anko 库 (0.9)

我使用了默认的导航抽屉活动,所以我只需要将主xml转换为anko。

这是xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <android.support.design.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <android.support.design.widget.AppBarLayout
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:theme="@style/AppTheme.AppBarOverlay">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

        </android.support.design.widget.AppBarLayout>

        <RelativeLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:paddingLeft="@dimen/activity_horizontal_margin"
            android:paddingRight="@dimen/activity_horizontal_margin"
            android:paddingTop="@dimen/activity_vertical_margin"
            android:paddingBottom="@dimen/activity_vertical_margin"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" >

            <TextView
                android:text="Hello World!"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

        </RelativeLayout>

    </android.support.design.widget.CoordinatorLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

</android.support.v4.widget.DrawerLayout>

正如您在此处看到的那样,它运行良好: [xml]

使用 anko,我尝试从 xml 中复制每个细节,得到以下代码:

class MainActivityUi: AnkoComponent<MainActivity> {
    override fun createView(ui: AnkoContext<MainActivity>) = with(ui) {

        drawerLayout {
            id = R.id.drawer_layout
            fitsSystemWindows = true

            coordinatorLayout {

                appBarLayout(R.style.AppTheme_AppBarOverlay) {

                    toolbar {
                        id = R.id.toolbar
                        backgroundColor = colorAttr(R.attr.colorPrimary)
                        popupTheme = R.style.AppTheme_PopupOverlay
                    }.lparams(height=dimenAttr(R.attr.actionBarSize),width=matchParent)

                }.lparams(width=matchParent)

                relativeLayout {
                    padding = dip(16)

                    textView("Hello World!")

                }.lparams(height=matchParent,width=matchParent) {
                   behavior = AppBarLayout.ScrollingViewBehavior()
                }

            }.lparams(height=matchParent,width=matchParent)

            navigationView {
                id = R.id.nav_view
                inflateHeaderView(R.layout.nav_header_main)
                inflateMenu(R.menu.activity_main_drawer)

            }.lparams(height=matchParent) {
                gravity = Gravity.START
                fitsSystemWindows = true
            }
        }
    }
}

相反,我得到了这个白色的状态栏:安科

我所做的唯一更改是在 MainActivity 中将 setContentView(R.layout.activity_main) 更改为 MainActivityUi.setContentView(this)。

所以,我的问题是,为什么当它们是相同的视图和布局时会发生这种情况?我该如何解决?

编辑:我使用的是在 Android Studio 中创建的默认项目,您选择新项目,然后选择 DrawerNavigationActivity。如果在 setContentView 我选择显示 xml 的视图,状态栏是蓝色的(第一个屏幕截图),但如果我选择显示 anko 的视图,我会得到白色的状态栏。

在这两种情况下,我都使用相同的主题、颜色等,并且在使用 xml 布局时,一切都运行良好,所以这一定是 anko 的问题

4

3 回答 3

2

试着做

window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)

在 onCreate() 里面

它对我有用

参考

编辑:也是我的代码

drawerLayout {
  lparams(width = matchParent, height = matchParent)

  coordinatorLayout {
     setPadding(0, dip(24), 0, 0)

     appBarLayout {
        toolbar {
           backgroundColor = primaryColor
           setTitleTextColor(primaryColorText)
        }.lparams(width = matchParent, height = dip(toolbar_size))

     }.lparams(width = matchParent, height = dip(toolbar_size))

  }.lparams(width = matchParent, height = matchParent)

  navigationView {

  }.lparams(width = dip(302), height = matchParent) {
     gravity = Gravity.START
  }
}

编辑 2:通过查看androidx 的源代码,他们添加了一些代码来处理“fitsSystemWindows”。我们可以复制粘贴来存档同样的效果。尽管 Anko 已经死了,但以编程方式创建 Drawerlayout 仍然有用(以及使用任何其他 DSL 库)

if (ViewCompat.getFitsSystemWindows(this)) {
    if (Build.VERSION.SDK_INT >= 21) {
        setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
            @Override
            public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) {
                final DrawerLayout drawerLayout = (DrawerLayout) view;
                drawerLayout.setChildInsets(insets, insets.getSystemWindowInsetTop() > 0);
                return insets.consumeSystemWindowInsets();
            }
        });
        setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
        final TypedArray a = context.obtainStyledAttributes(THEME_ATTRS);
        try {
            mStatusBarBackground = a.getDrawable(0);
        } finally {
            a.recycle();
        }
    } else {
        mStatusBarBackground = null;
    }
}
于 2017-03-12T14:54:10.337 回答
0

你错误地认为状态栏是transparent默认的。

根据这张图

在此处输入图像描述

取自 Android 开发者参考。检查:https ://developer.android.com/training/material/theme.html

状态栏颜色取决于您在文件夹中colors.xml或文件夹中定义的内容,因此它不是透明的。styles.xmlvaluescolorPrimaryDark

您的问题不是white状态栏中的颜色对于透明度是正确的,而是在 Android 应用程序中使用主题的知识不足。

编辑:更改状态栏颜色(Java):

Window window = activity.getWindow();

// clear FLAG_TRANSLUCENT_STATUS flag:
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

// add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

// finally change the color
window.setStatusBarColor(activity.getResources().getColor(R.color.my_statusbar_color));

或者

 public void setStatusBarColor(View statusBar,int color){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
           Window w = getWindow();
           w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
           //status bar height
           int actionBarHeight = getActionBarHeight();
           int statusBarHeight = getStatusBarHeight();
           //action bar height
           statusBar.getLayoutParams().height = actionBarHeight + statusBarHeight;
           statusBar.setBackgroundColor(color);
     }
}

希望它会有所帮助

于 2016-09-02T17:10:11.217 回答
0

这不是您的状态栏颜色问题。
如果我错了,请纠正我,我相信您使用的是Cyanogenmod OS 13.0 版本,从电池符号的外观来看。将其切换回主题部分中的默认主题。colors.xml如果您的文件仍然存在问题,请报告。


有关您的 Kotlin 半透明状态栏问题,请在此处参考此链接。
https://github.com/fython/MaterialStatusBarCompat

于 2016-09-02T17:47:24.637 回答