Android: finding button by id - java

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.

Related

Android Studio: Getting id of Dialog TextView in another class?

I'm trying to create a couple of Progress Bars inside a Dialog "remaining_amount_report" in Activtiy A:
public void setProgressBars(){
ProgressBar_Setup setup = new ProgressBar_Setup();
setup.createProgressBar(1, "product1", 80);
setup.createProgressBar(2, "product2", 60);
setup.createProgressBar(3, "product3", 100);
setup.createProgressBar(4, "product4", 20);
}
Therefore I've created a Class "ProgressBar_Setup" where the Method is reachable.
But the problem is, since I want to overwrite some TextView Texts of the Dialog, I need to get access to the Dialog inside the Class.
The Class extends Activity A, so I normally should get access just like this:
public void createProgressBar(int position, String productname, int progress) {
mposition = position;
switch(mposition){
case 1:
progressbar[0].setProductname(((TextView) remaining_amount_report.findViewById(R.id.remaining_amount_productname_1)));
But I get an Null Object Reference Error, by doing this.
Then I tried a different way, by adding a Dialog Variable to the "createProgressBar"-Method (not really good behavour, I guess):
public void setProgressBars(){
ProgressBar_Setup setup = new ProgressBar_Setup();
setup.createProgressBar(1, "product1", 80, remaining_amount_report);
setup.createProgressBar(2, "product2", 60, remaining_amount_report);
setup.createProgressBar(3, "product3", 100, remaining_amount_report);
setup.createProgressBar(4, "product4", 20, remaining_amount_report);
And in the ProgressBar_Setup-Class
public void createProgressBar(int position, String productname, int progress, Dialog dialog) {
mposition = position;
switch(mposition){
case 1:
progressbar[0].setProductname(((TextView) dialog.findViewById(R.id.remaining_amount_productname_1)));
But still the same error.
Could you help me here?
Thank you!
I think you need to use findViewById to first link the views in progressbar.

How to use Databinding with DialogFragment

In my app I have an ElementListFragment of items represented by a code object Element. I've data-bound these elements to the list and they display the correct information.
However, to continue filling in the information in each item I put a button on each element that shows a Dialog with additional fields.
But when the Dialog opens the fields are all blank (where one at least ought to be filled) and any fields I fill don't save the data (and don't effect changes on the list).
Appart from the values not being bound (displayed or written), the application works fine. I've essentially tried multiple variations of the sugestions in this question. Here is the code:
public class ElementDialogFragment extends DialogFragment {
private Element mElement;
private Dialog dialog;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View v = inflater.inflate(R.layout.dialog_element, null);
final DialogSkillelementBinding binding = DialogElementBinding.inflate(LayoutInflater.from(getContext()));
builder.setView(v)
// Add action buttons
.setPositiveButton(R.string.save, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
//this was just an attempt to make it work
binding.executePendingBindings();
dialog.dismiss();
}
});
TextView Title = v.findViewById(R.id.skill_e_dialog_title);
Title.setText(ResourceLocator.getSkillName(mElement.getSkill()));
dialog = builder.create();
dialog.setContentView(binding.getRoot());
binding.setElement(mElement);
binding.executePendingBindings();
return dialog;
}
}
When debuging I've confirmed that mElement is correctly attributed, however it's also bound to the list shown beneath the dialog. The title is also displayed correctly.
Is there a problem double-binding an object?
Are some of the steps on the function maybe out of order?
Is the DialogBuilder somehow incompatible with databinding?
You should set LyfecycleOwner for your binding class for data updating.
binding.setLifecycleOwner(requireActivity())

Alert Dialogue null object reference

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.

EditText in DialogFragment always return empty string

I have implemented form in my dialog, and when positive button is clicked I create new object to ma database. I've created global variable for EditText's but still not work. Where I want get text value from them I always get empty string.
here is code:
EditText name, desc;
#Override
#NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
view = inflater.inflate(R.layout.new_dialog, null);
name = (EditText) view.findViewById(R.id.workout_name);
desc = (EditText) view.findViewById(R.id.workout_description);
builder.setView(inflater.inflate(R.layout.new_dialog, null)).setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
MyDbHelper helper = new MyDbHelper (getActivity());
MyObj w = new MyObj ();
w.setName(name.getText().toString(););
w.setDescription(desc.getText().toString());
w.setLevel(1);
long id = helper.createWorkout(w);
Toast.makeText(getActivity(), id+"", Toast.LENGTH_LONG).show();
callback.onPositiveButtonClick();
}
}).setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
callback.onNegativeButtonClick();
}
});
return builder.create();
}
Any ideas please?
I stumbled upon the same issue. You can get the views inflated in the dialog using getDialog() provided by the onClick.
((EditText) getDialog().findViewById(R.id.your_editText_ID)).getText().toString()
In below code, you are inflating new_dialog layout and your name and desc EditTexts belong to this layout.
view = inflater.inflate(R.layout.new_dialog, null);
name = (EditText) view.findViewById(R.id.workout_name);
desc = (EditText) view.findViewById(R.id.workout_description);
But when you are setting the layout of the dialog you are setting new_workout_dialog. your name and desc do not belong to this layout.
builder.setView(inflater.inflate(R.layout.new_workout_dialog, null))
Furthermore, even if you used new_dialog while setting the builders view, name and desc would still be irrelevant. Because you are completely creating a new view inside setView method.
Use the view variable as following:
builder.setView(view, null))

Custom style on DialogFragment

Possible duplicate here, sorry in that case...
I can't get my head around how to add a custom style to my DialogFragment. At the moment I have a class
public final class SelectFragment extends DialogFragment {
which I call from different parts of my app. E.g from my "CreateInvoice" class like this:
private void showFragment(int selectedIndex) {
SelectFragment fragment = SelectFragment.newInstance(selectedIndex, getOnOptionSelectListener());
fragment.setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Holo_Light_Dialog);
fragment.show(getActivity().getSupportFragmentManager(), "");
}
What I want to do is to change the fragment.setStyle to a custom one, for example with my own color scheme as color on the border, background etc.. And I would really appreciate if someone could walk me through it since it's the first time I've worked with fragments. :-)
Thanks!
The way I would do it is to simply write your own layout for your dialog, then load it up when you show the fragment
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
View v = inflater.inflate(R.layout.custom_dialog_layout, null, false);
builder.setView(v)
// Add action buttons
.setPositiveButton(R.string.save_note, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
// do stuff
}
})
.setNegativeButton(R.string.note_cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//do stuff
}
});

Categories

Resources