Android Development: Button- findViewById? - java

What is the intent behind this piece of code?
Button sButton = (Button) findViewById(R.id.button_1);

In your XML files, you create IDs for the widgets you put on the screen.
In that code, you are creating a button reference (sButton) to be the button corresponding to the ID of button_1
findViewById searches for a button based on its ID - the ID is located in the R.java file of your project: Project Folder > gen > package > R.java
The R.java file holds references to everything (or basically everything?) in your project. It's an essential part of it.
That is why the parameter of findViewById is R.id.button_1 because you are searching for the ID of button_1 in the R class (it's a static field).
You are then casting that ID of the button_1 to a button with the (Button) in front of the findViewById.
Extra note:
If you look at the R.java class, you have it declared as: public final class R { so that's where the R in R.id.button_1 comes from.
Then you have another inner class like this: public static final class id { so that's where the id comes from in R.id.button_1
Then, in the id inner class, you have this (amoung other things):
public static final int button_1=...; where the ... would be some code to represent the int value. That's where the button_1 comes from in R.id.button_1
So bascially, R.id.button_1 goes to the R class, then the id inner class, then accesses the actual int value of the id name.

it finds a view in the associated layout XML by it's id, and casts it to a Button. Was it what you were asking?

Its used to find a Button which you have created in XML and bring it into the Java code so you can work with it. If you didnt do this you would not be able to give the button anything to do.

Related

Deleting a View in a class method

In my activity I try to call a method from a class but it's not getting the right values.
This is ActivityTwo:
int id = intent.getIntExtra("id", 0);
LayoutInflater inflater = getLayoutInflater();
View mainActivity = inflater.inflate(R.layout.activity_main, null);
LinearLayout eventsLayout = mainActivity.findViewById(R.id.eventsLayout);
Log.d("ACTIVITY_eventlayout", String.valueOf(eventsLayout)); // gives the layout perfectly
Event.RemoveSpecific(eventsLayout, id);
finish();
This is the class(Event) with the method:
public static void RemoveSpecific(LinearLayout layout, int id){
View event = layout.findViewById(id);
Log.d("INSIDE_removespecific", String.valueOf(event));// event is null
layout.removeView(event);
}
And in my MainActivity it's working fine:
LinearLayout eventsLayout = findViewById(R.id.eventsLayout);
View event = eventsLayout.findViewById(id);
//Log.d("MAIN_event", String.valueOf(event1)); // gives it perfectly
eventsLayout.removeView(event);
I also add this view in my MainActivity and use .setId(id) to give it the right id. So my question is, why is the View in my class method null, while I pass the right LinearLayout from my activityTwo?
Where does the id come from?
I have the Event class which contains an id, name, date, & description. This class also has a static ArrayList called eventsList. Whenever the user creates a new reminder I create a new Event using my class and giving it an id as Event.eventsList().size() (after adding it to my eventsList [so the first event id is always 1]), then I create a new View and pass the recently created Event details and use setId() to give it an id [1]. Then in this View I have a button which has an onClickListener which passes the given View id and the LinearLayout (where the View was added) to my Event.removeSpecific() method.
App flow:
The user clicks a button in MainActivity to create an event, then the button click then use startActivityForResult() with an intent to open a new Activity where the user puts in a name,description and date for the event, then I create an intent with putExtra() methods and then use setResult(RESULT_OK, resultintent) to send the data back to MainActivity. Now when the MainActivity gets the data back I use .getStringExtra() to create a new Event object with the data and add it to may Event.eventsList ArrayList, then I use the following:
LayoutInflater inflater = getLayoutInflater();
View event_Exmaple = inflater.inflate(R.layout.event_example, null);
and set the textView's with the data I got, and use event_example.setId(Event.eventsList.size()) to give it an id.
After that I add this to my LinearLayout (which I declared already in the MainActivity):
eventsLayout.addView(event_example)
Now I mentioned that the Event class has a date field. I use that to set up an alarm with AlarmManager. With the AlarmManager I send the current Event object's data through the intent and when the user gets the notification it opens up a new Activity which gets the given Event object data (with intent.putExtra()'s) and that's the part where the user clicks on a Button. I want to remove the given Event object's View from my LinearLayout in the MainActivity XML.
well since you didn't share where the id value come from (from where the intent gets its data/how you put the values in it/where the values come from), I assumed this solution :
whenever I use a 'switch' statement with View Ids it tells me a very important warning which is
Resource IDs will be non-final in Android Gradle Plugin version 5.0, avoid using them in switch case statements
that means that view Ids doesn't have a stable id in some cases that you shouldn't consider them to be final.
I guess in your case when you get an id to your event view and then inflate the layout view, the inflate procedure involve changing the 'int' id value of the event view so whenever you query the old id it returns null since the event view inside the inflated layout view now has a new 'int' id value.
I don't know why it works in main activity since you didn't share full code where you get the id from.
so I guess the only solution is that you should find a way to get a fresh copy of the id after you inflate the view you want to work on in the method.
Update
the problem is with this block of code
View mainActivity = inflater.inflate(R.layout.activity_main, null);
everytime you inflate a new layout view thinking that you have the one used by main activity back there but instead you're creating an entirely new one with new views and new Id's.
that would be why you could get the view in main activity but you can't get it from a newly inflated view.
Update
if you need to remove this item using the id and have a static array stored in the view custom class, call a getter on the static array and remove the item from it instead of trying to remove the view itself.
a better implementation of the whole situation is to store these events in a database using room instead of the static array, that way you could delete/add/edit any event anytime with just one line of code, if you're willing to do this you can start by reading the developers documentation of room.

How to Create a customized Directory using java

Problem:
I wanted to create a directory such that when I click on a button for one time the directory must be created with the name "Node_1". when I click on the same button once again the directory must be created with the name "Node_2".
Please do not bother about the button. I need the code where the count must be incremented as stated above.
The below sample code will create a directory with the name "Node_1" When I click once.
But when I click button Once again, it will create a directory with the same name "Node_1" again. But I wanted to create with the name "Node_2".
String src = "C:\\Users\\DELL\\Documents\\NetBeansProjects\\src\\Nodes\\Node_1\\n1_sample.txt";
Hope, this will help:
int clickCounter = 0;
void onClick() {
++clickCounter;
.
.
String src = "...\\Node_" + clickCounter + "\\...txt"
}
Note: Learn to ask question in a better way. Share what you want to achieve, what you've tried already, and what problem you are facing, and also keep it simple.

how to reference a view in android without need for inflating

I keep getting an error that says cannot resolve method findViewById . I understand that this is probably because findViewById method works with a specific view or its descendants . I would like to check a radio button in another view whilst I am in another view. How do I then reference that view without having to inflate . This is the line of code that is giving me the "cannot resolve method findViewById" error . This radio button is actually in another view.
RadioButton r1 = (RadioButton) findViewById(R.id.rb_data_all);
r1.checked(true);
You said:-
"cannot resolve method findViewById "
That means it is undefined , and I assume you want the one from Activity Class so
try this.
1) Extend your activity class to android.support.v7.app.AppCompatActivity
2) Override onCreate(Bundle instance) at least and it should work.

Cant setId for a view programatically with AndroidStudio

I want to add view programatically to my parent view, my view is a RadioButton. I also want to set an Id for the view that I add in RadioGroup. But when I do this it gives me an error in: mRadioButton.setId(321);
Reports two types of problems:
Supplying the wrong type of resource identifier. For example, when calling Resources.getString(int id), you should be passing R.string.something, not R.drawable.something.
Passing the wrong constant to a method which expects one of a specific set of constants. For example, when calling View#setLayoutDirection, the parameter must be android.view.View.LAYOUT_DIRECTION_LTR or android.view.View.LAYOUT_DIRECTION_RTL.
I dont know why it gives me this error.
I found that one solution would be to create MyRadioButton class which extends RadioButton and there I could add a variable int MYID; and then add getters and setters for this view.
But this is a workaround, does anyone know the solution of this problem ?
Thanks!
EDIT:
Another workaround is to use setTag()
(I have used it for a horizontal view with ImageView's added dynamically and it helps me to detect which one was clicked)
If you are only supporting API 17 and higher,
you can call View.generateViewId
ImageButton mImageButton = new ImageButton(this);
mImageButton.setId(View.generateViewId());
Otherwise for apis lower than 17,
open your project's res/values/ folder
create an xml file called ids.xml
with the following content:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="imageButtonId1" type="id" />
</resources>
then in your code,
ImageButton mImageButton = new ImageButton(this);
mImageButton.setId(R.id.imageButtonId1);

Android - define groups in R.id

Is there any possibility to group the R.id?
android:id="#+id/button1"
R.id.button1
I want something like this:
android:id="#+id/main/button1"
R.id.main.button1
But that does not work.
The only way I know to group like id's like that is to set all the tags the same. Then you get reference the id's with the same tag.
Button myButton = (Button)findViewById(R.id.button1);
Button mySecondButton = (Button)findViewById(R.id.button2);
myButton.setTag("Tag1");
mySecondButton.setTag("Tag1");
This way you can still programatically reference your group.
In the R.java file, the id itself is a group, and there is no way to superclass it with something else.
As a matter of fact you can. This isn't documented, and IntelliJ does not play along nicely (Eclipse does), but you can do something like this...
layout.xml
android:id="#+id_group1/button1"
Activity.java
Button myButton = (Button)findViewById(R.id_group1.button1);

Categories

Resources