I'm trying to use the .setText within a java class to try to change the value of a TextView on the activity_main XML file, so far i'm getting the NullpointerExeption error and I've read that its due an error when declaring my variable. How can i achieve this? Do i need to declare it first at the mainActivity.java?
On my activity_main.xml i have a button -> it opens a custom listView -> if you press the 2 item on the list view -> it opens a custom alert dialog -> the custom alert dialog it contains 2 buttons -> if you press the second button -> it has to set the text of a TextView that is on activity_main.xml
Any help is appreciated!
MainActivity.java
final TextView KMLabel = (TextView)findViewById(R.id.KMlabel);
activity.main.xml
<TextView
android:id="#+id/KMlabel"
android:layout_alignBottom="#+id/TVKm"
android:layout_toRightOf="#+id/TVKm"
android:textSize="22sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#e6c009"
android:text="KM/H"
android:textStyle="italic"/>
custom.java
public class custom extends BaseAdapter{
Context context;
String Item[];
String SubItem[];
int flags[];
LayoutInflater inflter;
public custom(Context applicationContext, String[] Item, String[] SubItem , int[] flags) {
this.context = context;
this.Item = Item;
this.SubItem = SubItem;
this.flags = flags;
inflter = (LayoutInflater.from(applicationContext));
}
#Override
public int getCount() {
return Item.length;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = inflter.inflate(R.layout.activity_items, null);
//TextView Prueba = (TextView)view.findViewById(R.id.KMlabel);
TextView item = (TextView) view.findViewById(R.id.item);
TextView subitem = (TextView) view.findViewById(R.id.subitem);
ImageView image = (ImageView) view.findViewById(R.id.image);
item.setText(Item[i]);
subitem.setText(SubItem[i]);
image.setImageResource(flags[i]);
return view;
}
viewdialog.java
public class ViewDialog {
public void showDialog(Activity activity, String msg){
final Dialog dialog = new Dialog(activity);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setCancelable(false);
dialog.setContentView(R.layout.custom_dialog);
//I'm declaring it like this
final TextView KMLabel = (TextView)activity.findViewById(R.id.KMlabel);
Button dialogButton = (Button) dialog.findViewById(R.id.btn_dialog);
dialogButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
Button KmPerHr = (Button)dialog.findViewById(R.id.KmPerH);
KmPerHr.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//and calling it this way:
KMLabel.setText("MLL/H");
}
});
dialog.show();
}
}
LOGCAT:
FATAL EXCEPTION: main
Process: com.example.dell.getspeed, PID: 3925
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.example.dell.getspeed.ViewDialog$2.onClick(ViewDialog.java:38)
at android.view.View.performClick(View.java:5721)
at android.widget.TextView.performClick(TextView.java:10936)
at android.view.View$PerformClick.run(View.java:22620)
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:7406)
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)
You have to move your code
Button KmPerHr = (Button)dialog.findViewById(R.id.KmPerH);
KmPerHr.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//and calling it this way:
KMLabel.setText("MLL/H");
}
});
final TextView KMLabel = (TextView)dialog.findViewById(R.id.KMlabel);
Button dialogButton = (Button) dialog.findViewById(R.id.btn_dialog);
dialogButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
below the dialog.show() code because code findViewById only work after you pop up dialog.
Create a Global class which extends to application class, then create a texview in Global
Textview t = null;
Then create two static methods to set and get this textview
Public static void setT(TextView p){
t = p;
}
And get it from
Public static TextView getT(){
return t;
}
Set TextView in your activity ,then access this textview from wherever you want until your activity is alive.
Try the code below:
MainActivity class:-------
public class MainActivity extends AppCompatActivity {
private TextView KMlabel;
private Button b;
private ViewDialog vd;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demo2);
vd = new ViewDialog();
KMlabel = (TextView) findViewById(R.id.KMlabel);
b = (Button) findViewById(R.id.b);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
vd.showDialog(MainActivity.this , KMlabel , "Your Message" , "Your Text");
}
});
}
}
ViewDialog class:------
public class ViewDialog {
public void showDialog(Context context, final TextView v , String msg , final String text) {
createYesNoInfoDialog(context, msg, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// do nothing
}
}, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
v.setText(text);
}
}).show();
}
private AlertDialog createYesNoInfoDialog(Context finalContext, String message,
DialogInterface.OnClickListener onNoListener, DialogInterface.OnClickListener onYesListener) {
AlertDialog a = new AlertDialog.Builder(finalContext).setTitle(
message)
.setNegativeButton("No", onNoListener)
.setPositiveButton("Yes", onYesListener).create();
return a;
}
}
demo2.xml:-----
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="xcxc"
android:id="#+id/KMlabel"/>
<Button
android:layout_width="match_parent"
android:text="Create Dialog"
android:layout_height="wrap_content"
android:id="#+id/b"/>
</LinearLayout>
R.id.KMlabel is on activity_main.xml so you have to initialize the TextView from MainActivity reference.
final TextView KMLabel = (TextView)activity.findViewById(R.id.KMlabel);
Edit:
You can use callback pattern for this:
ViewDialog:
public class ViewDialog {
// interface for callback
public interface OnSelectListener {
public void onOkSelect();
}
OnSelectListener mOnSelectListener;
public void showDialog(Activity activity, String msg, OnSelectListener mListener){
mOnSelectListener = mListener;
final Dialog dialog = new Dialog(activity);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setCancelable(false);
dialog.setContentView(R.layout.custom_dialog);
//I'm declaring it like this
final TextView KMLabel = (TextView)activity.findViewById(R.id.KMlabel);
Button dialogButton = (Button) dialog.findViewById(R.id.btn_dialog);
dialogButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
Button KmPerHr = (Button)dialog.findViewById(R.id.KmPerH);
KmPerHr.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//pass to the implementation if not null
if( mOnSelectListener != null){
mOnSelectListener.onOkSelect();
}
}
});
dialog.show();
}
}
In MainActivity:
// initialize interface
ViewDialog.OnSelectListener mOnSelectListener = new ViewDialog.OnSelectListener(){
public void onOkSelect(){
KMLabel.setText("MLL/H");
}
};
ViewDialog viewDialog = new ViewDialog();
viewDialog.showDialog(this, "Message", mOnSelectListener);
This happens since you are trying to call the TextView within the custom alert dialog. TextView only belongs to the MainActivity. You can call or change that only within the MainActivity class. So please try this below.
MainActivity.class
public class MainActivity extends AppCompatActivity {
private TextView KMlabel;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
KMlabel = (TextView) findViewById(R.id.KMlabel);
}
public void setTextKM(String string){
KMlabel.setText(string);
}
}
ViewDialog class
public class ViewDialog {
public void showDialog(Activity activity, String msg){
final Dialog dialog = new Dialog(activity);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setCancelable(false);
dialog.setContentView(R.layout.custom_dialog);
Button dialogButton = (Button) dialog.findViewById(R.id.btn_dialog);
dialogButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
Button KmPerHr = (Button)dialog.findViewById(R.id.KmPerH);
KmPerHr.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
MainActivity mainActivity = new MainActivity();
mainActivity.setTextKM("MLL/H");
}
});
dialog.show();
}
}
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 3 years ago.
I have added one button "btn". I have set onclicklistener, inside the button "btn" I have added another button "btnYes" to show display custom dialog when I add these "btnYes" apps get crash.
When I remove the "btnyes" button app is working.
Can we add onclicklistener for two button inside one button for different work?
Java Code
public class MainActivity extends AppCompatActivity {
private Button btn, btnYes, btnNo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = findViewById(R.id.click);
btnYes = findViewById(R.id.yes);
btnNo = findViewById(R.id.no);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder dialogBox = new AlertDialog.Builder(MainActivity.this);
LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
View myView = inflater.inflate(R.layout.custom_dialogbox, null);
dialogBox.setView(myView);
final AlertDialog mybuilder = dialogBox.create();
mybuilder.setCancelable(false);
btnYes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mybuilder.dismiss();
}
});
}
});
}
}
Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.example.customdialog.MainActivity$1.onClick(MainActivity.java:33)
If btnYes and btnNo are on the dialog, then you should initialize these buttons using the AlertDialog's View object.
You have to modify your code like following.
public class MainActivity extends AppCompatActivity {
private Button btn, btnYes, btnNo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = findViewById(R.id.click);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder dialogBox = new AlertDialog.Builder(MainActivity.this);
LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
View myView = inflater.inflate(R.layout.custom_dialogbox, null);
// these button should be initialize here.
btnYes = myView.findViewById(R.id.yes);
btnNo = myView.findViewById(R.id.no);
dialogBox.setView(myView);
final AlertDialog mybuilder = dialogBox.create();
mybuilder.setCancelable(false);
btnYes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mybuilder.dismiss();
}
});
}
});
}
}
Hope it helps you.
if you want to display Dialog with choices yes or no, use this
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(message)
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// action for yes
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// action for no
}
});
AlertDialog alert = builder.create();
alert.show();
But, if you want to use a custom dialog layout, you should do it like this.
final Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.YOUR_LAYOUT_HERE);
Button btnyes= dialog.findViewById(R.id.btnyes);
btnyes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.cancel();
}
});
I am trying to make Dialog that will consist 2x EditText and 1x Buttons. By clicking additional button you can add another 2x EditText and 1x Buttons. This 1x Button provide deleting this added pair. When i try to use button that should add another Views it's working properly. But button for deleting the View is working only for the first pairs. How can i do this with android:onClick, because i was trying buy it crashed.
Here is my code of Dialog class:
public class ExampleDialog extends AppCompatDialogFragment {
private EditText editTextUsername;
private EditText editTextPassword;
private ExampleDialogListener listener;
private LinearLayout parentLinearLayout;
private Context mContext;
Button dodaj,usun;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.dialog_template, null);
builder.setView(view)
.setTitle("Login")
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.setPositiveButton("ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
String username = editTextUsername.getText().toString();
String password = editTextPassword.getText().toString();
listener.applyTexts(username, password);
}
});
editTextUsername = view.findViewById(R.id.edit_username);
editTextPassword = view.findViewById(R.id.edit_password);
parentLinearLayout = (LinearLayout) view.findViewById(R.id.parent_linear_layout);
dodaj = view.findViewById(R.id.add_field_button);
usun = view.findViewById(R.id.delete_button);
dodaj.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View rowView = inflater.inflate(R.layout.field, null);
// Add the new row before the add field button.
parentLinearLayout.addView(rowView, parentLinearLayout.getChildCount() - 1);
}
});
usun.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
parentLinearLayout.removeView((View) v.getParent());
usun = v.findViewById(R.id.delete_button);
}
});
return builder.create();
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
listener = (ExampleDialogListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString() +
"must implement ExampleDialogListener");
}
}
public void contexta(Context context)
{
this.mContext = context;
}
public interface ExampleDialogListener {
void applyTexts(String username, String password);
}
}
And there is the conception of Dialog box on the picture below:
Picture
This issue may be due to view reference. Check whether v.getParent() is the view you want to delete or not.
For testing you can use "removeViewAt(int index)" method. Pass an index and check whether view is deleted at index or not.
I am trying to create a custom dialog where the button clicks could be handled by the main activity that instantiates it, something like how the AlertDialog.Builder assigns the listeners via its setPositiveButton() and setNegativeButton() methods.
This is what I've done:
// THE MAIN ACTIVITY
public class main_code extends AppCompatActivity {
private commonModule comMod;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
comMod = new commonModule(this);
}
private void showDialog() {
DialogInterface.OnClickListener dialogHandler =
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// process "PROCEED" button
}
};
commonModule.myDialog customDialog = comMod.new myDialog();
customDialog.inputBox(this, "Submit Results",
"Your results will be submitted.", dialogHandler);
}
}
// THE COMMON MODULE CLASS
public class commonModule {
public commonModule(Context context){
this.context = context;
this.activity = (Activity) context;
}
public class myDialog {
public void showDialog(Activity activity, String title, String message,
DialogInterface.OnClickListener dialogHandler) {
final Dialog panel = new Dialog(activity);
panel.requestWindowFeature(Window.FEATURE_NO_TITLE);
panel.setContentView(R.id.customLayout);
panel.setCancelable(false);
TextView panelTitle = (TextView) panel.findViewById(R.id.title);
panelTitle.setTypeface(fontRes(PlayRegular));
panelTitle.setText(title);
TextView msgboxText = (TextView) panel.findViewById(R.id.content);
msgboxText.setTypeface(fontRes(PlayRegular));
msgboxText.setText(message);
Button button1 = (Button) panel.findViewById(R.id.button1);
button1.setTypeface(fontRes(PlayRegular));
button1.setText("ABORT");
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
panel.dismiss();
}
});
Button button2 = (Button) panel.findViewById(R.id.button2);
button2.setTypeface(fontRes(PlayRegular));
button2.setText("PROCEED");
button2.setOnClickListener(dialogHandler);
// error: View.OnClickListener cannot be applied to Dialog.OnClickListener
panel.show();
}
}
}
I tried using View.OnClickListener() as well, but to no success. I would like the dialog builder to be common and generic, and as such, the click listener should be unique for each dialog.
Any suggestion would be really appreciated.
TIA.
Change your dialogHandler to View.OnClickListener instead of DialogInterface.OnClickListener :
private void showDialog() {
View.OnClickListener dialogHandler =
new View.OnClickListener() {
#Override
public void onClick(View v) {
// process "PROCEED" button
}
};
commonModule.myDialog customDialog = comMod.new myDialog();
customDialog.inputBox(this, "Submit Results",
"Your results will be submitted.", dialogHandler);
}
and in the common module:
public void showDialog(Activity activity, String title, String message,
View.OnClickListener dialogHandler) {
...
button2.setOnClickListener(dialogHandler);
panel.show();
}
I have bottom sheet dialog that displays when button clicked, so I have implemented all the logic for bottom sheet dialog into onClick method of button, how can I make separate class for showing bottom sheet dialog and just call method in onClick
Here is my code in onClick:
BottomSheetDialog mBottomSheetDialog = new BottomSheetDialog(this);
View sheetView = getLayoutInflater().inflate(R.layout.bottom_sheet, null);
NumberPicker minutePicker = (NumberPicker) sheetView.findViewById(R.id.np);
tv = (TextView) sheetView.findViewById(R.id.tv);
minutePicker.setMaxValue(100);
minutePicker.setMinValue(0);
minutePicker.setWrapSelectorWheel(false);
mBottomSheetDialog.setContentView(sheetView);
mBottomSheetDialog.show();
minutePicker.setOnValueChangedListener(
new NumberPicker.OnValueChangeListener() {
#Override
public void onValueChange(NumberPicker picker, int oldVal,
int newVal) {
tv.setText(Integer.toString(newVal));
}
});
}
To implement separation of concern and make your code modular
public class ClsBottomSheet{
public static TextView tv;
LayoutInflater inflater;
BottomSheetDialog mBottomSheetDialog;
public static NumberPicker minutePicker;
public ClsBottomSheet(Context context) {
mBottomSheetDialog = new BottomSheetDialog(context);
inflater = LayoutInflater.from(context);
}
public BottomSheetDialog showDialog(){
View sheetView = inflater.inflate(R.layout.bottom_sheet, null);
minutePicker = (NumberPicker) sheetView.findViewById(R.id.np);
tv = (TextView) sheetView.findViewById(R.id.tv);
Button btnOne = (Button) sheetView.findViewById(R.id.btn_one);
Button btnTwo = (Button) sheetView.findViewById(R.id.btn_two);
btnOne.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mBottomSheetDialog.cancel();
}
});
btnTwo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mBottomSheetDialog.dismiss();
}
});
minutePicker.setMaxValue(100);
minutePicker.setMinValue(0);
minutePicker.setWrapSelectorWheel(false);
mBottomSheetDialog.setContentView(sheetView);
minutePicker.setOnValueChangedListener(new ClsCallback());
return mBottomSheetDialog;
}
}
Im trying to make a Dialog close when button is pressed.But Every time i press the button the application crashes.
public class CanvasPaint extends Activity implements OnClickListener {
final Button widthbtn = (Button) findViewById(R.id.widthbtn);
final Button widthpopBtn = (Button) findViewById(R.id.widthpopBtn);
final Context context = this;
final Dialog widthDialog = new Dialog(context);
widthbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
widthpopBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
widthDialog.dismiss();
}
});
widthDialog.show();
}
});
}
That's some inception code. Why are you setting a click listener inside a click listener? It should be more like
widthbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
widthDialog.show();
}
});
widthpopBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
widthDialog.dismiss();
}
});
Your dialog layout is not properly inflated, and therefore, your widthpopBtn will be null. Try inflating the layout like this:
LayoutInflater inflater = getLayoutInflater();
View dialogView = inflater.inflate(R.layout.your_dialog_layout, null);
Button widthpopBtn = (Button) dialogView.findViewById(R.id.widthpopBtn);