点击按钮时崩溃与自定义主题自定义、按钮、主题

2023-09-12 04:40:53 作者:痴守过去

我创建一个自定义主题按钮,使用机器人:的onClick 按钮的情况下,从XML本身来处理按钮的点击

I am creating a custom theme for button and using android:onClick event of Button from xml itself to handle the click of Button.

由于某种原因崩溃与下面的异常

Due to some reason its crashing with below exception

java.lang.IllegalStateException:找不到在活动课android.view.ContextThemeWrapper为onclick处理方法MyOnClick(视图)的视图类android.widget.Button ID为Button1的

和它的工作很好,如果我只是删除按钮主题属性,下面是我的主题按钮

And its working fine if I just remove the theme attribute from the Button, below is my theme for Button

    <style name="ButtonTheme" parent="@android:style/Widget.Button">
        <item name="android:textColor">#FF0000</item>
        <item name="android:shadowColor">#FF000000</item>
    </style>

和我的按钮在XML定义如下,

And my Button defined in xml as below,

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_margin="20dp"
        android:onClick="MyOnClick"
        android:theme="@style/ButtonTheme"
        android:text="Button" />

下面是我的Java code,以及,

Here is my java code as well,

public void MyOnClick(View view) {
        switch (view.getId()) {
        case R.id.button1:
            getWindow().setStatusBarColor(getResources()
                                   .getColor(R.color.statusBarColor));
            getWindow().setNavigationBarColor(getResources()
                                   .getColor(R.color.statusBarColor));
            break;

        default:
            break;
        }

    }

那么,什么可能是崩溃的原因是什么?我能够处理click事件,如果我删除 Android的:从XML从Button控件主题=@风格/ ButtonTheme属性

推荐答案

我从来没有见过任何人施加安卓主题属性为一个单独的查看,但有点谷歌搜索后,我发现,这确实是可能的,但只是由于Android 5.0。

I've never seen anybody applying the android:theme attribute to an individual View, but after a bit of googling I found out that this is indeed possible, but only since Android 5.0.

这方面的一个暗示可能在年底这里可以看到。

A hint of this can be seen at the end here.

和一些细节这里。

随着第二个链接说明,一个 ContextThemeWrapper 用于修改与基地相关联的主题上下文。然而,由于你的活动将需要保住自己的主题,我只能想象,新的 ContextThemeWrapper 是创建和分配作为新的背景查看。由于这个新的上下文不是你活动更多,你的回调函数不存在这里,你会得到错误你形容。

As the second link explains, a ContextThemeWrapper is used to modify the theme associated with the base Context. However, since your Activity will need to hold on to its own theme, I can only imagine that a new ContextThemeWrapper is created and assigned as the new Context of your View. Since this new Context is not your Activity any more, your callback functions don't exist here and you get the error you describe.

您可以使用调试器来证明这自己(我用Android的工作室,但你也许可以使用自己选择的IDE,细节可能会有所不同)。

You can use the debugger to prove this yourself (I used Android Studio, but you can probably use the IDE of your choice, the details might be different).

运行在调试模式下的应用程序与主题属性设置。 当你得到的异常,堆栈跟踪将包含引用查看类的地方调用的onClick 。 使用此选项可添加之前断点的 的异常发生。 现在,又在调试模式下运行应用程序,点击按钮 当你命中断点评估EX pression 的getContext()。你会看到,这个返回类型的对象 ContextThemeWrapper ,它将有一个成员 MBASE 指向回到您的实际活动,所以的getContext()本身确实的没有的回报您的活动并执行的没有的有你在你的活动定义的回调函数。 现在,删除主题属性,离开了断点,并再次运行该应用程序。 当你打的断点,再次评估前pression 的getContext()键,你会看到,这一次它返回你的活动直接,这就是为什么你的回调的工作,如果你不设置主题属性。 Run the app in debug mode with theme attribute set. When you get the exception, the stacktrace will contain a reference to the View class where it invokes onClick. Use this to add a breakpoint before the exception occurs. Now run the app again in debug mode, click the button When you hit the breakpoint evaluate the expression getContext(). You will see that this returns an object of type ContextThemeWrapper and it will have a member mBase which points back to your actual Activity, so getContext() itself does not return your Activity and does not have the callback functions you defined on your Activity. Now remove the theme attribute, leave the breakpoint and run the app again. When you hit the breakpoint, evaluate the expression getContext() again and you will see that this time it returns your Activity directly, which is why your callbacks work, if you don't set the theme attribute.

总之,好像你不能使用安卓的onClick 属性,如果你想使用这项新功能,您将不得不手动分配一个 OnClickListener 所描述的这里

In short, it seems like you can't use the android:onClick attribute if you want to make use of this new feature, and you will have to manually assign an OnClickListener as described here