我正在制作一个 Android 应用程序,最初用户会获得“GO”按钮。单击该按钮后,会出现一个新的相对布局,其中有几个选项按钮,即“加法”和“减法”。 然后,我尝试获取用户单击了哪个按钮,并相应地提出该组问题。 但是,一旦单击“GO”按钮,应用程序就会崩溃。 我检查点击哪个按钮的代码是 ---
public void start(View view)
{
startbutton.setVisibility(View.INVISIBLE);
Log.i("YO:", "Start button ok!");
optionRelativeLayout.setVisibility(RelativeLayout.VISIBLE);
int tag = (Integer) view.getTag();
if(tag==4)
additionrelativelayout.setVisibility(RelativeLayout.VISIBLE);
if(tag==5)
subtractionrelativelayout.setVisibility(RelativeLayout.VISIBLE);
}
XML 代码是
<Button
android:text="Go!"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:id="@+id/start_button"
android:textSize="80sp"
android:paddingBottom="50dp"
android:paddingEnd="50dp"
android:paddingLeft="50dp"
android:paddingRight="50dp"
android:paddingStart="50dp"
android:paddingTop="50dp"
android:background="@android:color/holo_green_light"
android:onClick="start"
android:visibility="visible" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/optionrelativlayout"
android:visibility="visible">
<Button
android:text="Addition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="4 "
android:layout_centerHorizontal="true"
android:layout_marginTop="45dp"
android:id="@+id/addition" />
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="5"
android:layout_centerHorizontal="true"
android:id="@+id/subtraction"
android:layout_marginTop="150dp" />
</RelativeLayout>
错误是
04-24 22:21:39.525 10853-10853/com.example.rohit_136.brain_trainer I/YO:: Start button ok!
04-24 22:21:39.527 10853-10853/com.example.rohit_136.brain_trainer E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.rohit_136.brain_trainer, PID: 10853
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
at android.view.View.performClick(View.java:5226)
at android.view.View$PerformClick.run(View.java:21350)
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:5582)
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.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:5226)
at android.view.View$PerformClick.run(View.java:21350)
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:5582)
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.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference
at com.example.rohit_136.brain_trainer.MainActivity.start(MainActivity.java:177)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:5226)
at android.view.View$PerformClick.run(View.java:21350)
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:5582)
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)
04-24 22:21:39.535 10853-10865/com.example.rohit_136.brain_trainer I/ActivityThreadEui: schedulePauseActivity com.example.rohit_136.brain_trainer.MainActivity finished=true userLeaving=false configChanges=0 dontReport=false
04-24 22:21:41.098 10853-10853/com.example.rohit_136.brain_trainer I/Process: Sending signal. PID: 10853 SIG: 9
为什么不使用这些按钮已有的 id?
public void start(View view)
{
startbutton.setVisibility(View.INVISIBLE);
Log.i("YO:", "Start button ok!");
optionRelativeLayout.setVisibility(RelativeLayout.VISIBLE);
int id = view.getId();
if(id==R.id.addition)
additionrelativelayout.setVisibility(RelativeLayout.VISIBLE);
if(id==R.id.subtraction)
subtractionrelativelayout.setVisibility(RelativeLayout.VISIBLE);
}
-- 编辑 --
我想我没有正确理解你想要实现的目标。
1 - 在您的
start()
方法中,删除以下内容:
int tag = (Integer) view.getTag();
if(tag==4)
additionrelativelayout.setVisibility(RelativeLayout.VISIBLE);
if(tag==5)
subtractionrelativelayout.setVisibility(RelativeLayout.VISIBLE);
2 - 创建两个新方法并将可见性线放入其中,如下所示:
public void displayAddition(View view){
additionrelativelayout.setVisibility(RelativeLayout.VISIBLE);
}
public void displaySubtraction(View view){
subtractionrelativelayout.setVisibility(RelativeLayout.VISIBLE);
}
3 - 在 XML 中,将它们添加到按钮中:
在
addition
按钮中添加以下行:
android:onClick="displayAddition"
在
subtraction
按钮中添加以下行:
android:onClick="displaySubtraction"
我知道这是一篇旧帖子,但即使四年后,我也很难找到针对您的确切问题的有用答案。我有 16 个按钮,它们都调用相同的方法(这是一个内存“匹配”游戏),它们需要将自己标识为 0 - 15 之间的索引,以匹配相应变量的数组。这花了一些功夫,但我终于弄清楚了这一点,并希望这可以帮助其他人。
按钮或视图上的“标签”属性实际上存储为Object,即使您使用 String 值定义它(输入 0 因为它不会存储 Int)。它可以用于引用资源(尽管不一定如此),因此您可以使用资源名称(例如 my_button_string)在按钮上设置标签,按该名称创建一个字符串资源,然后在调用时getTag() 它将以一种非常迂回的方式从资源中返回字符串。但是,如果您只是为其分配一个原始值,例如“0”,则可以使用 getTag() 返回 0,但同样是以一种非常迂回的方式。这就是为什么这么难!
Tag 存储为对象,因此当您调用 myButton.getTag() 时,它会返回一个通用 OBJECT 类型,该类型不喜欢被转换为 Integer。它甚至不喜欢被转换为字符串,即使这就是您首先定义它的方式!但对于您(和我)的用例,我们需要一个 Int 来将我们的按钮标识为索引或枚举用例等。顺便说一句,我还以数字方式命名了我的按钮,这样我就可以迭代它们的名称来添加它们的 clickListener 或对它们执行其他组更改,所以我也会包含这部分,因为如果您有很多所有按钮都通过一个方法,并且想要简单地识别它们以用于 Switch/Case 或其他东西,这可能会帮助某些人。
我的按钮全部命名为:
button_0
button_1
button_2....
对应的“标签”值为 0、1、2 等...
在我的 MainActivity 的 OnCreate() 方法中:
//Add clickListener to each button
for(int i = 0; i <= 15; i++) {
//Get ResourceID of each button by iterating their name Strings using loop index as suffix
int buttonID = getResources().getIdentifier("button_" + i, "id", this.getPackageName());
//Get button from the ResourceID returned from its name
Button btn = findViewById(buttonID);
//Get String value of the button's tag object value
String tagString = String.valueOf(btn.getTag());
//Parse the String value (which is known to be an Integer) to its Integer value
int btnTag = Integer.parseInt(tagString);
//Set the button's clickListener to call the onButtonTap method and pass
//the tag value as its argument, identifying the button to the method
btn.setOnClickListener(v -> onButtonTap(btnTag));
}
...然后我的按钮 onTap 方法接收标签
void onButtonTap(int tag) {
Log.i(TAG, "Button with tag " + tag + "was tapped!");
}
您可以在 getTag() 方法中看到我必须使用的...
String.valueOf(btn.getTag())
...从返回对象中获取原始值。我不能只是将它转换为字符串。得到String值后,它就可以解析成Integer了。让我感到非常惊讶的是,Java 做出了如此简单而有用的想法,而标签却如此令人困惑。我确实意识到标签可以引用资源这一事实确实给了它一些更多的内置功能,但就我个人而言,我永远不会按照他们似乎想要的方式使用标签,但这只是我。我习惯了它们在 Obj C / Swift 中的使用方式,它只是一个简单的 Int,但同样,这只是我。希望这可以帮助其他遇到此问题的人!
public void callWhenClick(View view){
Button btn = (Button) view;
int myTag = Integer.parseInt(btn.getTag().toString());
}
您正在使用
view.getTag()
,但问题是视图不是按钮变量
用这个:
Button button = (Button) view;
int Tag = button.getTag();
//Do what ever you wanna do with the tag from here on...
希望这有帮助