单击具有自定义主题

时间:2015-07-27 12:28:43

标签: android android-layout android-activity

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

由于某种原因,它崩溃了以下异常

java.lang.IllegalStateException: Could not find a method MyOnClick(View) in the activity class android.view.ContextThemeWrapper for onClick handler on view class android.widget.Button with id 'button1'

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

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

我的按钮在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"属性,我就能处理click事件。

3 个答案:

答案 0 :(得分:3)

我从未见过有人将android:theme属性应用于个人View,但经过一段谷歌搜索后我发现这确实可行,但仅限Android 5.0。 / p>

最后可以看到这一点here

还有一些细节here

正如第二个链接所解释的那样,ContextThemeWrapper用于修改与基座Context相关联的主题。但是,由于您的Activity需要保留自己的主题,因此我只能想象创建一个新ContextThemeWrapper并将其指定为Context的新View 。由于新的Context不再是您的Activity,因此您的回调函数不会存在,并且您会收到您描述的错误。

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

  1. 在调试模式下运行应用程序,并设置theme属性。
  2. 当您收到异常时,堆栈跟踪将包含对View类的引用,它将调用onClick
  3. 使用此选项在发生异常之前添加断点
  4. 现在再次以调试模式运行应用程序,单击按钮
  5. 当您点击断点时,请评估表达式getContext()。您将看到这会返回ContextThemeWrapper类型的对象,并且会有一个成员mBase,该成员会指向您的实际Activity,因此getContext()本身不会 返回您的Activity并且具有您在Activity上定义的回调函数。
  6. 现在删除theme属性,保留断点并再次运行应用程序。
  7. 当您点击断点时,再次评估表达式getContext(),您会看到这次它直接返回Activity,这就是为什么您的回调有效,如果您没有设置theme属性。
  8. 简而言之,如果您想要使用此新功能,似乎无法使用android:onClick属性,并且您必须按照所述OnClickListener手动分配Cursor {3}}

答案 1 :(得分:0)

有时我们将样式添加到<!-- store the initial message content --> <enrich> <source type="body" clone="true"/> <target type="property" property="BodyBackup"/> </enrich> <sequence key="sequence1"/> <!-- restore the message content --> <enrich> <source type="property" property="BodyBackup"/> <target type="body"/> </enrich> <sequence key="sequence2"/> 它会影响默认的android可点击行为。

尝试在Button

中添加属性clickable="true"

或者

您还可以将<Button... />添加到按钮样式。

答案 2 :(得分:0)

花了这么多时间之后,对我有用的事情就是在onCreate()中的代码setTheme(R.style.AppToolbar);中应用主题,而不是从所有布局中删除所有的android:OnClick。