样式android:应用自定义样式时DatePickerDialog崩溃

时间:2016-04-28 09:32:11

标签: android dialog styles android-datepicker

我尝试自定义应用对话框样式(包括日期选择器对话框)。

如果我没有指定任何自定义对话框主题,一切正常,但如果我尝试应用自定义主题,则AlertDialog会继续正常工作,而DatePickerDialog会导致我的应用崩溃。

例外情况如下:

E/AndroidRuntime: FATAL EXCEPTION: main 
                  Process: it.bmsoftware.serendipity, PID: 5950
                  android.view.InflateException: Binary XML file line #20: Binary XML file line #20: Error inflating class android.widget.DatePicker
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
                     at android.app.DatePickerDialog.<init>(DatePickerDialog.java:112)
                     at android.app.DatePickerDialog.<init>(DatePickerDialog.java:82)
                     at it.bmsoftware.ui.dialog.DatePickerFragment.onCreateDialog(DatePickerFragment.java:72)
                     at android.support.v4.app.DialogFragment.getLayoutInflater(DialogFragment.java:308)
                     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
                     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
                     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742)
                     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
                     at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517)
                     at android.os.Handler.handleCallback(Handler.java:739)
                     at android.os.Handler.dispatchMessage(Handler.java:95)
                     at android.os.Looper.loop(Looper.java:148)
                     at android.app.ActivityThread.main(ActivityThread.java:5422)
                     at java.lang.reflect.Method.invoke(Native Method)
                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                  Caused by: android.view.InflateException: Binary XML file line #20: Error inflating class android.widget.DatePicker
                     at android.view.LayoutInflater.createView(LayoutInflater.java:645)
                     at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58)
                     at android.view.LayoutInflater.onCreateView(LayoutInflater.java:694)
                     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:762)
                     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:374) 
                     at android.app.DatePickerDialog.<init>(DatePickerDialog.java:112) 
                     at android.app.DatePickerDialog.<init>(DatePickerDialog.java:82) 
                     at it.bmsoftware.ui.dialog.DatePickerFragment.onCreateDialog(DatePickerFragment.java:72) 
                     at android.support.v4.app.DialogFragment.getLayoutInflater(DialogFragment.java:308) 
                     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067) 
                     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252) 
                     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742) 
                     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617) 
                     at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517) 
                     at android.os.Handler.handleCallback(Handler.java:739) 
                     at android.os.Handler.dispatchMessage(Handler.java:95) 
                     at android.os.Looper.loop(Looper.java:148) 
                     at android.app.ActivityThread.main(ActivityThread.java:5422) 
                     at java.lang.reflect.Method.invoke(Native Method) 
                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
                  Caused by: java.lang.reflect.InvocationTargetException
                     at java.lang.reflect.Constructor.newInstance(Native Method)
                     at android.view.LayoutInflater.createView(LayoutInflater.java:619)
                     at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58) 
                     at android.view.LayoutInflater.onCreateView(LayoutInflater.java:694) 
                     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:762) 
                     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704) 
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:492) 
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:374) 
                     at android.app.DatePickerDialog.<init>(DatePickerDialog.java:112) 
                     at android.app.DatePickerDialog.<init>(DatePickerDialog.java:82) 
                     at it.bmsoftware.ui.dialog.DatePickerFragment.onCreateDialog(DatePickerFragment.java:72) 
                     at android.support.v4.app.DialogFragment.getLayoutInflater(DialogFragment.java:308) 
                     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067) 
                     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252) 
                     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742) 
                     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617) 
                     at [...]
                  Caused by: android.view.InflateException: Binary XML file line #23: Binary XML file line #29: Error inflating class TextView
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
                     at android.widget.DatePickerCalendarDelegate.<init>(DatePickerCalendarDelegate.java:118)
                     at android.widget.DatePicker.createCalendarUIDelegate(DatePicker.java:160)
                     at android.widget.DatePicker.<init>(DatePicker.java:140)
                     at android.widget.DatePicker.<init>(DatePicker.java:126)
                     at android.widget.DatePicker.<init>(DatePicker.java:122)
                     at java.lang.reflect.Constructor.newInstance(Native Method) 
                     at android.view.LayoutInflater.createView(LayoutInflater.java:619) 
                     at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58) 
                     at android.view.LayoutInflater.onCreateView(LayoutInflater.java:694) 
                     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:762) 
                     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704) 
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:492) 
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:374) 
                     at android.app.DatePickerDialog.<init>(DatePickerDialog.java:112) 
                     at android.app.DatePickerDialog.<init>(DatePickerDialog.java:82) 
                     at it.bmsoftware.ui.dialog.DatePickerFragment.onCreateDialog(DatePickerFragment.java:72) 
                     at android.support.v4.app.DialogFragment.getLayoutInflater(DialogFragment.java:308) 
                     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067) 
                     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252) 
                     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742) 
                     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617) 
                     at [...] 
                  Caused by: android.view.InflateException: Binary XML file line #29: Error inflating class TextView
                     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:782)
                     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
                     at android.view.LayoutInflater.rInflate(LayoutInflater.java:835)
                     at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
                     at android.view.LayoutInflater.parseInclude(LayoutInflater.java:971)
                     at android.view.LayoutInflater.rInflate(LayoutInflater.java:831)
                     at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
                     at android.widget.DatePickerCalendarDelegate.<init>(DatePickerCalendarDelegate.java:118) 
                     at android.widget.DatePicker.createCalendarUIDelegate(DatePicker.java:160) 
                     at android.widget.DatePicker.<init>(DatePicker.java:140) 
                     at android.widget.DatePicker.<init>(DatePicker.java:126) 
                     at android.widget.DatePicker.<init>(DatePicker.java:122) 
                     at java.lang.reflect.Constructor.newInstance(Native Method) 
                     at android.view.LayoutInflater.createView(LayoutInflater.java:619) 
                     at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58) 
                     at android.view.LayoutInflater.onCreateView(LayoutInflater.java:694) 
                     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:762) 
                     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704) 
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:492) 
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
                     at android.view.LayoutInflater.inflate(LayoutInflater.java:374) 
                     at android.app.DatePickerDialog.<init>(DatePickerDialog.java:112) 
                     at android.app.DatePickerDialog.<init>(DatePickerDialog.java:82) 
                     at it.bmsoftware.ui.dialog.DatePickerFragment.onCreateDialog(DatePickerFragment.java:72) 
                     at android.support.v4.app.DialogFragment.getLayoutInflater(DialogFragment.java:308) 
                     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067) 
                     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252) 
                     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742) 
                     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617) 
                     at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517) 
                     at android.os.Handler.handleCallback(Handler.java:739) 
                     at android.os.Handler.dispatchMessage(Handler.java:95) 
                     at android.os.Looper.loop(Looper.java:148) 
                     at android.app.ActivityThread.main(ActivityThread.java:5422) 
                     at java.lang.reflect.Method.invoke(Native Method) 
                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
                  Caused by: java.lang.UnsupportedOperationException: Failed to resolve attribute at index 6: TypedValue{t=0x2/d=0x101009b a=1}
                     at android.content.res.TypedArray.getColorStateList(TypedArray.java:482)
                     at android.widget.TextView.<init>(TextView.java:753)
                     at android.widget.TextView.<init>(TextView.java:674)
                     at android.support.v7.widget.AppCompatTextView.<init>(AppCompatTextView.java:60)
                     at android.support.v7.widget.AppCompatTextView.<init>(AppCompatTextView.j

我定义了以下样式:

<style name="AppTheme.Dialog" parent="SlidingUpDialog">
    <item name="colorPrimary">?colorPrimary</item>
    <item name="colorPrimaryDark">?colorPrimaryDark</item>
    <item name="colorAccent">?colorAccent</item>
</style>

<style name="SlidingUpDialog" parent="@style/Theme.AppCompat.Light.Dialog">
    <item name="android:windowAnimationStyle">@style/SlidingUpDialogAnimations</item>
</style>

<style name="SlidingUpDialogAnimations">
    <item name="android:windowEnterAnimation">@anim/push_up_in</item>
    <item name="android:windowExitAnimation">@anim/push_up_out</item>
</style>

然后我在App主题(基础)中指定了以下属性:

<style name="AppTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">

    [...other settings...]

    <item name="android:dialogTheme">@style/AppTheme.Dialog</item>
</style>

<style name="AppTheme.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

应用主题v-19是:

<style name="AppTheme.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    <item name="android:windowTranslucentStatus">true</item>
</style>

应用主题v-21是:

<style name="AppTheme.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>

    <!-- Transitions -->
    <item name="android:windowContentTransitions">true</item>

    <!-- specify enter and exit transitions -->
    <!-- options are: explode, slide, fade -->
    <!--<item name="android:windowEnterTransition">@android:transition/fade</item>-->
    <!--<item name="android:windowExitTransition">@android:transition/fade</item>-->

    <!-- specify shared element transitions -->
    <!--<item name="android:windowSharedElementEnterTransition">@android:transition/fade</item>-->
    <!--<item name="android:windowSharedElementExitTransition">@android:transition/fade</item>-->
</style>

该配置中缺少什么? 为什么日期选择器对话框导致上述异常而普通的aler对话框没有?

我想借此机会再问一件事。在样式化时,这三个声明之间有什么区别?

<style name="AppTheme" parent="[STYLE]">
</style>

<style name="AppTheme" parent="@style/[STYLE]">
</style>

<style name="AppTheme" parent="android:[STYLE]">
</style>

此外,在这些之间?

<style name="AppTheme">
   <item name="colorPrimary">@color/colorPrimary</item>
   [...]
</style>

<style name="AppTheme">
   <item name="android:colorPrimary">@color/colorPrimary</item>
   [...]
</style>

编辑:xml布局和java代码

这是打开datepicker对话框的活动的代码片段:

 public void showDatePickerDialog(View v) {
    String currentDate = mBinding.childForm.birthday.getText().toString();

    int[] currentDateParts = LocaleController.getDateParts(currentDate);
    int currYear = currentDateParts[0];
    int currMonth = currentDateParts[1];
    int currDay = currentDateParts[2];

    new DatePickerDialog(context,
            (datePicker, year, monthOfYear, dayOfMonth) -> {
                if(onDateSetAction != null)
                    onDateSetAction.call(year, monthOfYear, dayOfMonth);
    }, currYear, currMonth, currDay).show();
}

这是活动的xml布局文件:

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

<data>
    <import type="it.bmsoftware.serendipity.activity.signup.binding.SignUpViewModel" />
    <variable
        name="viewModel"
        type="SignUpViewModel" />
</data>

<android.support.design.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".activity.signup.SignUpActivity">

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

    <ViewFlipper
        android:id="@+id/viewFlipper"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:ignore="UselessParent">

        <include android:id="@+id/child_form"
            layout="@layout/include_signup_form"
            app:viewModel="@{viewModel}" />

        <include android:id="@+id/child_progress"
            layout="@layout/include_progress_full"
            app:status="@{@string/login_progress_signing_up}" />

        <include android:id="@+id/child_complete"
            layout="@layout/include_signup_complete"
            app:viewModel="@{viewModel}" />
    </ViewFlipper>

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

这是感兴趣的包含布局:

<?xml version="1.0" encoding="UTF-8"?>
<layout 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">

<data>
    <import type="android.view.View"/>
    <import type="it.bmsoftware.serendipity.R" />
    <import type="it.bmsoftware.helper.LocaleController" />
    <import type="it.bmsoftware.serendipity.activity.signup.binding.SignUpViewModel" />
    <variable
        name="viewModel"
        type="SignUpViewModel" />
</data>

<RelativeLayout
    android:id="@+id/formLayout"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activity.signup.SignUpActivity">

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/formScroll"
        android:layout_above="@+id/buttonsLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingBottom="@dimen/activity_vertical_margin"
            android:paddingLeft="@dimen/activity_horizontal_margin"
            android:paddingRight="@dimen/activity_horizontal_margin"
            android:paddingTop="@dimen/activity_vertical_margin">

            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <android.support.design.widget.TextInputEditText
                    android:id="@+id/firstName"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/first_name"
                    android:inputType="text"
                    android:maxLines="1"
                    android:singleLine="true"
                    app:binding="@{viewModel.firstName}" />
            </android.support.design.widget.TextInputLayout>

            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <android.support.design.widget.TextInputEditText
                    android:id="@+id/lastName"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/last_name"
                    android:inputType="text"
                    android:maxLines="1"
                    android:singleLine="true"
                    app:binding="@{viewModel.lastName}" />
            </android.support.design.widget.TextInputLayout>

            <LinearLayout
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingBottom="8dp">
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:paddingLeft="4dp"
                    android:paddingRight="4dp"
                    android:textAppearance="@style/TextAppearance.AppCompat.Caption"
                    android:text="@string/birthday" />
                <Button
                    android:id="@+id/birthday"
                    style="@android:style/Widget.Holo.Light.Spinner"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium"
                    app:binding="@{viewModel.birthday}"
                    android:onClick="showDatePickerDialog" />
            </LinearLayout>

            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <android.support.design.widget.TextInputEditText
                    android:id="@+id/email"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/email"
                    android:inputType="textEmailAddress"
                    android:maxLines="1"
                    android:singleLine="true"
                    app:binding="@{viewModel.email}" />
            </android.support.design.widget.TextInputLayout>

            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <android.support.design.widget.TextInputEditText
                    android:id="@+id/username"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/username"
                    android:inputType="text"
                    android:maxLines="1"
                    android:singleLine="true"
                    app:binding="@{viewModel.username}" />
            </android.support.design.widget.TextInputLayout>

            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <android.support.design.widget.TextInputEditText
                    android:id="@+id/password"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/password"
                    android:inputType="textPassword"
                    android:maxLines="1"
                    android:singleLine="true"
                    app:binding="@{viewModel.password}" />
            </android.support.design.widget.TextInputLayout>

            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <android.support.design.widget.TextInputEditText
                    android:id="@+id/passwordConfirm"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/password_confirm"
                    android:inputType="textPassword"
                    android:maxLines="1"
                    android:singleLine="true"
                    app:binding="@{viewModel.passwordConfirm}" />
            </android.support.design.widget.TextInputLayout>

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="20dp">
                <CheckBox
                    android:id="@+id/privacyCb"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="@android:color/secondary_text_light"
                    android:textSize="12sp"
                    android:textStyle="italic"
                    android:text=""
                    android:checked="false" />

                <TextView
                    android:id="@+id/privacyCbText"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_toEndOf="@+id/privacyCb"
                    android:layout_toRightOf="@+id/privacyCb"
                    android:layout_centerInParent="true"
                    android:textColor="@android:color/secondary_text_light"
                    android:textSize="12sp"
                    android:layout_marginEnd="3dp"
                    android:layout_marginRight="3dp"
                    android:textStyle="italic" />

            </RelativeLayout>
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>

    <LinearLayout android:id="@+id/buttonsLayout"
        style="?android:attr/buttonBarStyle"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true">

        <Button android:id="@+id/cancelButton"
            style="?android:attr/buttonBarButtonStyle"
            android:layout_width="0dp"
            android:layout_weight="0.5"
            android:layout_height="wrap_content"
            android:text="@string/cancel"
            android:onClick="formCancel"
            />

        <Button android:id="@+id/confirmButton"
            style="?android:attr/buttonBarButtonStyle"
            android:layout_width="0dp"
            android:layout_weight="0.5"
            android:layout_height="wrap_content"
            android:text="@string/confirm"
            android:onClick="formConfirm"
            />
    </LinearLayout>

</RelativeLayout>

提前感谢您的帮助:)

0 个答案:

没有答案