android - 单击具有自定义主题的按钮时崩溃

标签 android android-layout android-activity

我正在为按钮创建一个自定义主题,并使用来自 xml 本身的 Button 的 android:onClick 事件来处理 Button 的点击。

由于某些原因它崩溃并出现以下异常

java.lang.IllegalStateException: 无法在 Activity 类 android.view.ContextThemeWrapper 中找到方法 MyOnClick(View) for onClick handler on view class android.widget.Button with id 'button1'

如果我只是从 Button 中删除 theme 属性,它工作正常,下面是我的 Button 主题

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

我的 Button 在 xml 中定义如下,

    <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代码,

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;
        }

    }

那么,崩溃的原因可能是什么?如果我从 xml 中的 Button Widget 中删除 android:theme="@style/ButtonTheme" 属性,我就能够处理点击事件。

最佳答案

我从未见过有人将 android:theme 属性应用于单个 View,但经过一番谷歌搜索后我发现这确实是可能的,但是仅从 Android 5.0 开始。

这一点的暗示可以在最后看到 here .

还有更多细节 here .

正如第二个链接所解释的,ContextThemeWrapper 用于修改与基础 Context 关联的主题。但是,由于您的 Activity 需要坚持自己的主题,我只能想象创建一个新的 ContextThemeWrapper 并将其分配为新的 ContextView 的。由于这个新的 Context 不再是您的 Activity,您的回调函数在这里不存在,您会得到您描述的错误。

你可以自己使用调试器来证明这一点(我使用的是 Android Studio,但你可以使用你选择的 IDE,细节可能会有所不同)。

  1. 在设置了 theme 属性的 Debug模式下运行应用程序。
  2. 当您遇到异常时,堆栈跟踪将包含对调用 onClickView 类的引用。
  3. 使用它在异常发生之前添加一个断点。
  4. 现在在 Debug模式下再次运行应用,点击按钮
  5. 当您到达断点时,计算表达式 getContext()。你会看到这会返回一个 ContextThemeWrapper 类型的对象,它会有一个成员 mBase 指向你实际的 Activity,所以 getContext() 本身返回您的Activity 并且具有您在Activity 上定义的回调函数
  6. 现在删除 theme 属性,离开断点并再次运行应用程序。
  7. 当您到达断点时,再次计算表达式 getContext(),您将看到这次它直接返回您的 Activity,这就是您的回调有效的原因,如果您没有设置 theme 属性。

简而言之,如果您想使用这个新功能,您似乎不能使用 android:onClick 属性,您将不得不手动分配一个 OnClickListener如描述here

关于android - 单击具有自定义主题的按钮时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31653126/

相关文章:

android-如何在 View 鳍状肢更改图像之间制作动画

android - Android React Native 中的多个可扩展 ListView

android - RelativeLayout.RIGHT_OF 不起作用

IntentService的onHandleIntent方法中的android.os.NetworkOnMainThreadException

android - 如何从子子 Activity 转到父 Activity ?

Android Kotlin 检测测试是否在调用 finish() 开始另一个 Activity 后结束/完成一个 Activity

android - Searchview 使应用程序崩溃

android - 如何在弹出窗口中显示数字选择器

android-layout - 在 android studio 中创建响应式网格布局

android - 将android布局转换为PDF文件