我正在尝试制作一个应用程序,其中一个循环生成算术表达式并将它们作为线性布局中的单个TextView列出。点击其中一个表达式后,弹出窗口会显示该表达式以及一个供用户输入解决方案的输入字段。下面有一个提交解决方案的按钮。我将按钮定位在XML中。问题是,当我使用onClickListener时,当我点击要弹出的窗口的表达式时,应用程序崩溃。如果我删除整个onClickListener,则窗口出现,但按钮无功能。 这会导致错误:
Button btnDone = (Button) findViewById(R.id.buttonDone);
btnDone.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
answerWindow.dismiss();
}
});
这是该函数的其余部分:
package klosinski.kamil.arithmeticproblems;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.ScrollView;
import android.widget.TextView;
import java.util.Random;
public class QuizGenerate extends AppCompatActivity {
boolean usePlus, useMinus, useMult, useDivide;
int count, maxValue;
Equation equation[] = new Equation[20];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz_generate);
SharedPreferences quizSettings = getSharedPreferences("QuizSettings", MODE_PRIVATE);
usePlus = quizSettings.getBoolean("usePlus", true);
useMinus = quizSettings.getBoolean("useMinus", true);
useMult = quizSettings.getBoolean("useMult", true);
useDivide = quizSettings.getBoolean("useDivide", true);
count = quizSettings.getInt("count",0);
maxValue = quizSettings.getInt("maxValue",0);
generateQuiz(); //Populate Equation class with generated equations
displayQuiz(); //Display the equations to the screen
}
//Method to display the contents of Equation class to the screen
public void displayQuiz(){
ScrollView scrollView = (ScrollView) findViewById(R.id.scrollViewx);
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setOrientation(LinearLayout.VERTICAL);
scrollView.addView(linearLayout);
for(int i = 0; i < count; i++){
int value1 = equation[i].getValue1();
int value2 = equation[i].getValue2();
char operator = equation[i].getOperator();
String value1Str = Integer.toString(value1);
String value2Str = Integer.toString(value2);
TextView textView = new TextView(this);
textView.setTextSize(getResources().getDimension(R.dimen.equationSize));
if(operator == '/'){
operator = '\u00F7';
}
textView.setText(value1Str + " " + operator + " " + value2Str + "=");
textView.setId(i);
textView.setOnClickListener(displayAnswerForm);
textView.setClickable(true);
linearLayout.addView(textView);
}
this.setContentView(scrollView);
}
// OnClickListener runs after equation is pressed.
// Displays a popup window with the pressed equation and editText for answer.
public View.OnClickListener displayAnswerForm = new View.OnClickListener() {
public void onClick(View v) {
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View popupView = inflater.inflate(R.layout.popup_window, null);
// Create the popup window
int width = LinearLayout.LayoutParams.MATCH_PARENT; // Width of the popup window
int height = LinearLayout.LayoutParams.MATCH_PARENT; // Height of the popup window
final PopupWindow answerWindow = new PopupWindow(popupView, width, height, true);
int equationTextViewId= v.getId(); // The ID of the text view that was pressed
// Getting the values and operator to display as equation.
String value1 = Integer.toString(equation[equationTextViewId].getValue1());
String value2 = Integer.toString(equation[equationTextViewId].getValue2());
char operator = equation[equationTextViewId].getOperator();
// If operator is a '/' (divide) then display it as a divider symbol.
if(operator == '/'){
operator = '\u00F7';
}
String equationToDisplay = value1+" "+operator+" "+value2+"="; // Complete string with the equation.
//Display our equation on the popup window.
((TextView)answerWindow.getContentView().findViewById(R.id.answerWindowTextView)).setText(equationToDisplay);
// Display the popup window.
answerWindow.showAtLocation(v, Gravity.CENTER, 0, 0);
////
////
//// setOnClickListener or the function causes a crash.
////
////
Button btnDone = (Button) findViewById(R.id.buttonDone);
btnDone.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
answerWindow.dismiss();
}
});
}
};
//Method to populate Equation class with generated equations
public void generateQuiz(){
char operator = '+';
for(int i = 0; i < count; i++){
switch(getRandomNumber(1, 4)){
case 1:
operator = '+';
break;
case 2:
operator = '-';
break;
case 3:
operator = '*';
break;
case 4:
operator = '/';
break;
default:
break;
}
equation[i] = new Equation(getRandomNumber(1, maxValue), getRandomNumber(1, maxValue), operator);
}
}
private int getRandomNumber(int min,int max) {
return (new Random()).nextInt((max - min) + 1) + min;
}
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorAccent"
android:gravity="center"
android:visibility="visible">
<TextView
android:id="@+id/answerWindowTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="5 + 2="
android:textAllCaps="false"
android:textSize="50sp"
app:layout_constraintBottom_toTopOf="@+id/editText8"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<EditText
android:id="@+id/editText8"
style="@style/Widget.AppCompat.AutoCompleteTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:backgroundTint="@color/colorEditText"
android:ems="10"
android:gravity="center"
android:hint="eg. 28"
android:inputType="number"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.527"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/answerWindowTextView" />
<Button
android:id="@+id/buttonDone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="DONE"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/editText8" />
</android.support.constraint.ConstraintLayout>
Google已将我引向一些“相关”主题,但没有一个对我有帮助。可能与View有关吗?
关于, 卡米尔(Kamil)
@edit
08-02 15:50:18.731 12741-12741/klosinski.kamil.arithmeticproblems E/AndroidRuntime: FATAL EXCEPTION: main
Process: klosinski.kamil.arithmeticproblems, PID: 12741
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at klosinski.kamil.arithmeticproblems.QuizGenerate$1.onClick(QuizGenerate.java:110)
at android.view.View.performClick(View.java:5698)
at android.widget.TextView.performClick(TextView.java:10846)
at android.view.View$PerformClick.run(View.java:22565)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7230)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
答案 0 :(得分:0)
此行at klosinski.kamil.arithmeticproblems.QuizGenerate$1.onClick(QuizGenerate.java:110)
告诉您崩溃发生在110行的QuizGenerate.java文件中。
错误java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
表明btnDone为空。
findViewById仅在您要查找的视图属于作用域中的当前上下文时才有效。即,如果您在Activity中调用findViewById,则该视图应属于该Activity,否则它将返回null。如果要在Fragment中调用findViewById,则视图应属于该片段,否则它将返回null。你明白了。
因此,请确保您从正确的位置致电Button btnDone = (Button) findViewById(R.id.buttonDone);
。
答案 1 :(得分:0)
您不应使用setContentView();像这样。仅在onCreate()中仅调用一次。如果要更改内容,请使用片段或开始其他活动。如果更改内容,则无法再通过findViewById查找视图。