Button.findViewById vs Button = findViewById - java

Hey guys I am new in programming. Trying out something in Android Studio (Kotlin)
I have looked for this but didn't find an answer. Button
Mostly I use Button.findViewById<Button>(R.id.Button) but sometimes it gives me error and I have to write it like Button = findViewById(R.id.Button) as Button
Can someone tell me where (or what) is the difference?

with kotlin : you don't must use findViewById. you can use direct id ex: btnSave.text="abc"
If code show error, you select [btnSave] and click [Alt + Enter] to import lib.

findViewById search a View that has the Id you give inside the view you call this method with.
So when you do Button.findViewById(R.id.btn) it should never work because Button is a class and not an instance of view.
When you do myButton.findViewById(R.id.btn) it looks inside myButton, that is an instance of view, if there is a view having btn has id. If there is it return it, otherwise it returns null.
When you do findViewById(R.id.btn) You call this method directly from inside a custom view code. Often it's inside an Activity. Then it looks in the layout of this activity if there is a View having btn has ID.If there is it return it, otherwise it returns null.

Related

Why implement the onClickListener instead of just setting the onClick attribute to a defined method in the Activity class?

I understand professionals use the former to tailor the onClick method to their exact specification, but cant I just use the onClick attribute and specify the same desired actions within a method.
i.e. [In xml file:] onClick="doSomething" & then
[in MainActivity.java:]
public void doSomething(View view){
//define and start intent
//Show a toast, etc
}
Why not just use the latter option? Thanks
Why not just use the latter option?
Go right ahead.
On bigger projects, it is unlikely that the activity will be managing the button directly:
You might be using fragments, in which case the fragment is more likely to manage the button than is the activity
You might be using MVP, MVVM, MVI, etc. GUI architectures, in which case some other "presenter" object is more likely to manage the button than is the activity
You might be using the data binding framework, in which case you might still be using android:onClick in a layout resource, but directing the event to something other than the activity (e.g., a fragment, a presenter)
And so on
Yes you can do so,both are doing the same thing but using the onClickListener is a better choice ,you can set the listener when you want that button to be active thus your Button and Activity are in cooordinaton.
If you use onClick in your xml file ,it will always call that method doesn't matter what is happening in your activity.

Java - Android - view.getContext() meaning

Hello i have just started learning android application development and i am watching a lot of tutorials but none of them really describe step by step so my question is :
i have created a simple app which contains on TextView one EditText and one Button
i have added android:onClick="onButtonClick" to my Button so it will trigger the onButtonClick method , now , i would like it to print out the userinput from EditText so what i did is :
public void onButtonClick(View v){
Toast.makeText(v.getContext(), email.getText().toString(), Toast.LENGTH_SHORT).show();
}
but why the method has to contain the View v ? where is it passed from ? and what does it contain ? it contains the button which i clicked ? and what does the v.getContext() do? why my app does the same when replacing the v.getContext() with this ?
That are many questions at once, but I try to answer them one by one.
but why the method has to contain the View v ? where is it passed from ? and what does it contain ?
Consider the documentation of View.OnClickListener:
View: The view that was clicked.
So you are correct in your assumption that it is the View that has been clicked.
and what does the v.getContext() do?
The first parameter of the Toast#makeText method is a Context. Basically the Context is a container of global information in an Android application. The Toast needs it to retrieve information to show itself.
why my app does the same when replacing the v.getContext() with this ?
I assume your method resides in an Activity. An Activity is a subclass of Context and can be used as a parameter.
If you click a button then View is passed. ViewGroup is a group of View example LinearLayout, Relative Layout, FrameLayout,etc. View is a part of ViewGroup. According to Official Documentation, A View occupies a rectangular area on the screen and is responsible for drawing and event handling. View is the base class for widgets, which are used to create interactive UI components (buttons, text fields, etc.). The ViewGroup subclass is the base class for layouts, which are invisible containers that hold other Views (or other ViewGroups) and define their layout properties.
I hope you understand well about what is View and ViewGroup!!

When you use findViewById, what is the object that invokes this method?

I am programming for android devices on Android Studio.
To my understanding, when I declare and assign a Button like this in my MainActivity.java:
mTrueButton = (Button) findViewById(R.id.true_button);
The compiler automatically substitutes this:
mTrueButton = (Button) com.testapp.mytestapp.MainActivity.findViewById(R.id.true_button);
But if I actually type in the second statement, I get a warning about non-static methods cannot be referenced from a static context.
What am I not understanding?
Please look at its signature: public View findViewById (int id)
As it's not static, you should call it from an instantiated class and this is the reason of the message you're getting.
To answer your question, the method is part of Activity. In the end, you can call it on an instance of Activity.
In your case you're inside an Activity instance, so you can refer to this instance with the keyword this.
I think retrieve it with View.findViewById() or Activity.findViewById().
View
Activity
In your MainActivity you have not imported R.java file
SO its taking full reference
Import R.java(your project's not android.R) of your package will solve your problem.
The method called is getWindow().findViewById(id);. To call this method in an activity, you first have to set it's view with setContentView(view). Or you can inflate a view yourself, and call the method findViewById() on the view you inflated.

Dynamically Creating/Removing Buttons in Android

Firstly, my apologies if this answer is already on here, as I've been searching for a few weeks and haven't found anything yet.
I am working on an Android app which needs to allow the user to create and remove buttons. I know how to normally create buttons statically through adding the button the XML file and creating it's functionality in the JAVA file.
Instead, I have a static button which I'll refer to as "Create Button". When the user presses on the Create Button, they should be given the option to add a new button to the current activity, allowing them to change the title of said button etc. When they close the app and open it back up; the button they added should still be there. Similarly, they should be given an option to remove buttons.
Can someone point me in the right direction? Most of the sources that I've come across only explain how to statically create buttons, like I first mentioned.
Thanks for the help!
EDIT: I was able to figure some stuff out based off of the feedback I've been given.
So far I have the following code in the onOptionsItemSelected( ) method:
if (id == R.id.add_button)
{
Button myButton = new Button(this);
myButton.setText("Push Me");
//myButton.setVisibility(View.VISIBLE);
return true;
}
I am still a little confused about how this can get added to the layout. Mainly, I am confused about the findViewById call:
RelativeLayout layout = (RelativeLayout)findViewById(R.id.?);
Which id should I be using? In the app's main XML file, there is no ID for the layout itself. It's just a "RelativeLayout".
EDIT2:
Actually, I solved the problem. Thanks for the advice! I just needed to give my layout an ID in the XML file. I knew that I could give buttons etc an ID, but never knew that I was able to do so for the actual layout itself!
Creating a button -
Button myButton = new Button(this);
Adding text to it -
myButton.setText("Push Me");
To make the button visible, you need to add it to a view like this. You can also add it to a statically created view -
LinearLayout ll = (LinearLayout)findViewById(R.id.buttonlayout);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
ll.addView(myButton, lp);
Removing button -
ll.removeView(myButton);
For additional customizations, check documentation.
If you are creating multiple buttons, then I recommend setting id. This example makes it clear.
For making buttons visible after closing the app, you need to store the data on memory. The simplest way to do this is to maintain a record of the buttons and their specifications and storing them before closing the app. After opening the app, you can read the stored data and create the buttons accordingly.
For more details, check Data Storing.
ViewGroup mViewGroup = (ViewGroup) findViewById(R.id.main_layout_id);
mViewGroup.addView(yourButton, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));

Android: Why can I not setText in the same line as findViewById

I am not sure if this is an Android issue or a AndroidStudio issue. Why is this valid:
TextView currentItem
currentItem = (TextView)findViewById(R.id.myText);
currentItem.setText("text");
But this is not (cannot resolve method setText(Java.Lang.String))
(TextView)findViewById(R.id.myText).setText("text");
Not a big deal, but I have some code that requires a lot of text updates. It would be much cleaner if I could get this in one line.
findViewById returns a generic 'View', hence you have to cast it to TextView before you can set the text. In your piece of code you are trying to invoke setText on the 'View' object rather than the 'TextView' object.
Try this :
((TextView)findViewById(R.id.myText)).setText("text");
Try this please :
((TextView)findViewById(R.id.myText)).setText("text");
findViewById returns a View, so you don't have setText from TextView yet. You have to cast first to TextView by putting parenthesis around findViewById and then call setText like this:
((TextView)findViewById(R.id.myText)).setText("text");
Also, this is a Java thing, not Android nor Android Studio thing.

Categories