Alert Dialogue null object reference - java

I have an alertDialogue popup when a user wants to create a game, and it asks the user how many points they would like to gamble in the game, but it keeps throwing a null reference error and I am not too sure why.
This is my alertDialogue positive button click listener
alertDialog.setPositiveButton("Confirm Wager", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
createLobbyGame();
double wagerD;
String wager;
TextView wagerRV = findViewById(R.id.wagerRV);
wagerD = Double.parseDouble(edittext.getText().toString());
wager = Double.toString(wagerD);
boolean wage = wager.endsWith("0");
if(wage) {
wagerRV.setText(wager+"0");
} else {
wagerRV.setText(wager);
}
}
});
It throws an error when it tries to setText. This is the error it throws
Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
I know I had this working in the past, but I must have changed something to make it not work properly anymore but I have no idea what I would have changed.
I know this is a very common and simple problem, but I have looked at many other answers and have not found a solution that works for me.
Any help?
TextView declaration:
TextView wagerRV = (TextView) ((AlertDialog.Builder) alertDialog).findViewById(R.id.wagerRV);
How I am defining alertDialog:
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(FlipCoinLobby.this);
final EditText edittext = new EditText(FlipCoinLobby.this);
alertDialog.setView(edittext);

Your wagerRV is null because it can't find R.id.wagerRV.
You need to retrieve views from within onClick() using the dialog reference.
Change
TextView wagerRV = findViewById(R.id.wagerRV);
to
TextView wagerRV = (TextView) ((AlertDialog) alertDialog).findViewById(R.id.wagerRV);
Remove any unnecessary casting (I don't have IDE at the moment).
Update based on comments and question edit:-
alertDialog.setView(edittext) --> your alertDialog does not have any TextView with id R.id.wagerRV. Please check out some examples online on setting the content view with XML and that XML should have that TextView. If your wagerRV is in the activity and not inside the dialog, then declare it at the activity level, not inside onClick of alertDialog.
Update 2
You need to change your builder to the actual AlertDialog using AlertDialog alertDialog = alertDialogBuilder.create();. And then the casting will work too.

Related

Android: Getting Resource ID before AlertDialog is created and shown?

I'm currently working on letting a user tap an image that will then display an AlertDialog with a zoomed in version of that image. I'm not too sure if the AlertDialog is the best way to go about this but it's my solution for now.
I'm finding myself struggling getting the Resource ID for an ImageView before I show the alert dialog. Here is the exact piece of code where the error is occurring (The comments are failed fix attempts):
mPhotoView.setOnClickListener(new View.OnClickListener() {
#SuppressLint("ResourceType")
#Override
public void onClick(View view) {
if(mPhotoView != null){
AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = requireActivity().getLayoutInflater();
dialog.setView(inflater.inflate(R.layout.zoomed_image, null)).create();
//medImg.setImageResource(dialog.getContext().getResources().getLayout(R.layout.zoomed_image).getIdAttributeResourceValue(R.id.ivZoomedImg));
//ivZoomedImg = getActivity().findViewById(R.id.ivZoomedImg);
//ivZoomedImg = view.findViewById(R.id.ivZoomedImg);
Bitmap bm = PictureUtils.getScaledBitmap(mPhotoFile.getPath(), getActivity());
ivZoomedImg.setImageBitmap(bm); // <- null reference
dialog.show();
}
}
});
Specifically, I can't seem to figure out a way to access the R.id.ivZoomedImg that should have been instantiated through the LayoutInflator? I'm not even sure if that's possible to be honest, though I don't see why it wouldn't. Does anyone know what would be the best way to go around this?
Some things to note:
R.layout.zoomed_image is just an XML layout containing a single ImageView with the id of R.id.ivZoomedImg
mPhotoView is the image being clicked on to have it displayed bigger
The fix involved simply instantiating an independent View where you can pull the ImageView resource Id from!
Lines of coded added:
View v = inflater.inflate(R.layout.zoomed_image, null);
ivZoomedImg = v.findViewById(R.id.ivZoomedImg);
dialog.setView(v).create();

Star Rating in Dialogbox won't change saved value

// Custom Dialog Box
final AlertDialog.Builder mBuilder = new AlertDialog.Builder(MainActivity.this, R.style.Theme_AppCompat_Dialog_Alert);
final View mView = getLayoutInflater().inflate(R.layout.completed, null);
ImageButton imgForm = (ImageButton) mView.findViewById(R.id.RateButton);
mBuilder.setCancelable(false);
mBuilder.setView(mView);
final AlertDialog dialog = mBuilder.create();
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.show(); // Dialogbox appears
// Interest Rating
final AlertDialog.Builder nBuilder = new AlertDialog.Builder( MainActivity.this, R.style.Theme_AppCompat_Light_Dialog_Alert);
final View nView = getLayoutInflater().inflate(R.layout.intrst, null);
Save_Intrst = (Button) nView.findViewById(R.id.SaveIntrst);
nBuilder.setCancelable(false);
nBuilder.setView(nView);
final AlertDialog dilog = nBuilder.create();
// LongPress Image Button
imgForm.setOnLongClickListener(new View.OnLongClickListener(){
#Override
public boolean onLongClick(View view){
dialog.dismiss();
dilog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dilog.show(); // Dialogbox appears
return true;
}
});
Save_Intrst.setOnClickListener(new View.OnClickListener(){
String IntrstLvl;
#Override
public void onClick(View v){
RatingBar rBar = (RatingBar)nView.findViewById(R.id.ratingStar);
IntrstLvl = Integer.toString(rBar.getNumStars());
addData(IntrstLvl);
dilog.dismiss();
Log.d(TAG,"Dismissed");
}
});
Whenever I select "save" within the Save_Intrst it saves 5 stars regardless of what I choose. I'm still fairly new to Android development and have been java coding for a bit now.
This is just a snippet of code of the project and I believe it will be enough, it shows my submit button, the submit button will launch a dialog box that will have a secret button in an image (ImgForm) the image doesn't show but that's not the problem, after long pressing it will launch another dialog that has a 5 Star Rating Bar and a Save button, this is used for rating after the person completes the previous requirements. The rating will always save "5" regardless of what was inserted, even after a reinstall of app onto the device.
getNumStars() will tell you the maximum number of stars shown and will always be 5 as you have defined it. If you want the actual selected rating, you will need getRating(). See this documentation.
You need to use the rBar.getRating()
RatingBar rBar = (RatingBar)nView.findViewById(R.id.ratingStar);
IntrstLvl = Integer.toString(rBar.getRating());
https://developer.android.com/reference/android/widget/RatingBar.html
You are calling getNumStars() which according to the documentation "Returns the number of stars shown." which means the total number of stars a user can select. You should instead be checking getRating() which returns the number of stars currently selected.
https://developer.android.com/reference/android/widget/RatingBar.html#getRating()

Android: finding button by id

I have a problem with finding buttons. I have an AlertDialog where I choose one of 5 options. When I choose an option I want change the color of the button I clicked. I declared buttons in xml file inside <RealativeLayout> but when I'm trying to find my button by id (id's are like "id1","id2"...)using the findViewById method, there is a mistake, which says that I can't use this method like I do:
AlertDialog.Builder builder = new AlertDialog.Builder(StartGameActivity.this);
builder.setTitle(R.string.pickColor);
builder.setItems(R.array.colorArray, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Button btn_tmp;
String theButtonId = "id";
theButtonId = theButtonId+(String.valueOf(which));
btn_tmp = (Button) findViewById(theButtonId);
}
});
How can I fix that or maybe I should use other method?
EDIT:
I think I solved my problem. I used one of Button's method: getId() like this:
final int id = clickedButton.getId();
final ImageButton btn_tmp;
btn_tmp = (ImageButton)findViewById(id);
Background: IDs are esentially variables
In the XML files we give IDs to the resources, and then the compilers use all these to generate the gen/R.java. So essentially, these IDs are int variables belonging in class R.
An example of R.java:
// btw this file should never be edited!
public final class R {
public static final class id {
public static final int id1=0x7f0100aa;
public static final int id2=0x7f0100ab;
}
}
Just because a String exists that contains a valid name of a variable (R.id.id1), it can't magically access that variable. To do this, one can use reflection. However, in this case I believe it is an unnecessary complication, and will even be slower.
findViewById needs an ID (integer variable):
You cannot supply a String to this function. You should use an integer value, and specifically the ones that correspont to int variables in R.java.
For example:
findViewById(R.id.id1) // for your 1st button
Solution:
You can dynamically select the integer value:
AlertDialog.Builder builder = new AlertDialog.Builder(StartGameActivity.this);
builder.setTitle(R.string.pickColor);
builder.setItems(R.array.colorArray, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Button btn_tmp;
int chosenID=-1;
switch (which) {
case 1: chosenID=R.id.id1;
break;
case 2: chosenID=R.id.id2;
break;
}
btn_tmp = (Button) findViewById(chosenID);
}
});
It is also suggested to use more explanatory IDs, like: buttonDoThis, buttonDoThat.
btn_tmp = (Button)findViewById(R.id.YourButtonId);
You are passing string instead of integer.
If you are using your own layout.xml for the dialog, you need to inflate it first and give the view to your dialog builder.
LayoutInflater layoutInflater = (LayoutInflater) StartGameActivity.this.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
final RelativeLayout customDialogView= (RelativeLayout) layoutInflater.inflate(R.layout.custom_dialog_view, null);
AlertDialog.Builder builder = new AlertDialog.Builder(StartGameActivity.this);
builder.setTitle(R.string.pickColor);
//give the custom view to your dialog builder.
builder.setView(customDialogView);
builder.setItems(R.array.colorArray, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Button btn_tmp;
switch(which){
//....cases
case 1:
btn_tmp = (Button) customDialogView.findViewById(R.id.button1);
//set the color of the button selected
break;
case 2:
btn_tmp = (Button) customDialogView.findViewById(R.id.button2);
//set the color of the button selected
break;
}
//....cases
}
});
You are trying to use findViewById() with a String that holds the variable name of the ID. Java doesn't support this kind of dynamic variable names since variable names are only known at compile time, not run time. What are you trying to do? You will need to find another way to solve this problem. Please explain further and we can give suggestions.

Problems with error: android.widget.LinearLayout cannot be cast to android.widget.EditText

I'm creating an EditText in onOptionsItemSelected() and trying to get it's information in onClick(). Here's the offending code:
onOptionItemSelected(MenuItem item){
...
EditText mealCalories = new EditText(context);
mealCalories.setId(MealCalId) //in this example it's just an integer 1.
...
}
onclick(View v){
EditText mealCaloriesInBox = (EditText)findViewById(mealCalId);
}
When I haven't selected an item from the menu (and thus haven't called onOptionItemSelected();) it doesn't crash when I click the button. However, when I actually have created the EditText and I click the button it crashes as it's trying to create the instance, giving me the aforementioned error. Any ideas on why it could be doing that?
EDIT
Here's more of my code:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Context context = getApplicationContext();
switch(item.getItemId()) {
case R.id.addMeal:
trackMealItems++;
mealCalId++;
mealFatId++;
mealCarbId++;
mealProteinId++;
//the base layout
LinearLayout root = (LinearLayout)findViewById(R.id.linearLayout1);
//make the layout that holds the meal item and add it to the base layout
LinearLayout mealItem = new LinearLayout(context);
mealItem.setId(trackMealItems);
mealItem.setOrientation(LinearLayout.VERTICAL);
mealItem.setLayoutParams(mealItemParams);
root.addView(mealItem);
//make the TextView that holds the name of the meal and add it to the mealItem layout
EditText mealName = new EditText(context);
mealName.setLayoutParams(mealNameParams);
mealItem.addView(mealName);
//make the TextViews that hold the information about the meal and stick them in a
//horizontal LinearLayout
LinearLayout mealStats = new LinearLayout(context);
mealStats.setOrientation(LinearLayout.HORIZONTAL);
mealStats.setLayoutParams(mealStatParams);
mealItem.addView(mealStats);
EditText mealCalories = new EditText(context);
mealCalories.setId(mealCalId);
mealCalories.setLayoutParams(mealStatParams);
mealStats.addView(mealCalories);
EditText mealFat = new EditText(context);
mealFat.setId(mealFatId);
mealFat.setLayoutParams(mealStatParams);
mealStats.addView(mealFat);
EditText mealCarbs = new EditText(context);
mealCarbs.setId(mealCarbId);
mealCarbs.setLayoutParams(mealStatParams);
mealStats.addView(mealCarbs);
EditText mealProtein = new EditText(context);
mealProtein.setId(mealProteinId);
mealProtein.setLayoutParams(mealStatParams);
mealStats.addView(mealProtein);
return true;
case R.id.removeMeal:
LinearLayout removeMe = (LinearLayout)findViewById(trackMealItems);
removeMe.setVisibility(View.GONE);
trackMealItems--;
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View v){
EditText mealCaloriesInTextBox = (EditText)findViewById(mealCalId);
}
You seem to be using two different values: MealCalId when you create your EditText and mealCalId when you call findViewById. That's one possible problem. The other is that if you have more than one view with the same id, findViewById will not necessarily return the one you want.
EDIT
At first glance, your code looks like it should work. I don't know what's going wrong, but I have a suggestion for a work-around. When you create the view, instead of assigning it an ID, assign it a tag:
mealCalories.setTag(mealCalId);
(The int value will be autoboxed to an Integer.) Then in your onClick handler, retrieve it by tag:
EditText mealCaloriesInTextBox =
(EditText) getContentView().findViewWithTag(mealCalId);
If there's any kind of funny interaction with view IDs, this technique will avoid them.
If that doesn't work (or if you prefer anyway) you can also try diagnosing the ID-based retrieval using the Hierarchy Viewer.
For those who are having this error for the same reason I did....
Just try cleaning your project and re-building.
Solved it for me.
i tried to run your code and what i found is that
when menu item is not clicked and button is clicked, the edit text is null.
So if you will call any method on this object, it will crash with NULLPointerException
When menu item is clicked and then button is clicked, the edit text is not null so you call any method on this object.

onCreateDialog and dynamic dialogs (Android)

I have a little problem. In my program I defined
protected Dialog onCreateDialog(int id) {
if (id == CONTEXT_MENU_ID) {
return createMyDialog();
}
return super.onCreateDialog(id);
}
and then show the dialog calling
showDialog(CONTEXT_MENU_ID)
My problem is that sometimes I want to change the texts of the Dialog dynamically between executions. But with that method the Dialog is never recreated. How can I make the createMyDialog() to be called before showing the Dialog?
Thanks
If you want to change dialog settings (text, etc.) you need to do it in onPrepareDialogMethod it will be called each time you call showDialog method
This might be worth a try. I haven't tested it out. To the dialog if you set the textview as its content, then you can set an id to it.
TextView text = new TextView(this);
ViewGroup.LayoutParams vp = new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
text.setLayoutParams(vp);
text.setText("HI");
text.setId(1005);
dialog.setContentView(text);
So the next time when you try to update the textview, you might be able to access it using the id.
((TextView)dialog.getWindow().getDecorView().findViewById(1005))
.setText("New Text");

Categories

Resources