I have an included layout in my activity's XML layout like so:
<include
layout="#layout/info_button"
android:id="#+id/config_from_template_info_btn"/>
I'm trying to set an OnClickListener for the button inside of that included layout by doing this:
findViewById(R.id.config_from_template_info_btn)
.findViewById(R.id.info_btn)
.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
//Do things
}
});
However, this crashes on runtime with:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
The info_btn.xml layout simply contains Button widget like so:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:id="#+id/info_btn"
...
/>
</merge>
What am I doing wrong here?
The <merge.../> tag is removing the outer layout, which is the one with that ID. That's the purpose of merge: to collapse unnecessary layouts for better performance. Yours is one common case. You need a top-level XML container to hold the included views, but you don't actually need view layout functionality.
Either just use one find on info_btn, or don't use merge. The only reason you'd need to do the double find is if you were including multiple layouts that each had views with an ID of info_btn.
If you have an included layout in your activity, you can access to the Button like if the button was inside the activity.
You only need to do:
findViewById(R.id.info_btn)
.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Do things
}
});
You just need to do this:
findViewById(R.id.info_btn)
.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v)
{
//Do things
}
});
Included layouts are added to your view already. You can do this way also.
findViewById(R.id.info_btn)
.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
Related
I'm having trouble taking in text from a few text boxes with one button. I can't seem to get OnClick() to work. I have setContentView(R.layout.activity_load_xactivity); as a test I know it doesn't have anything to do with input.
Button button = (Button)findViewById(R.id.create);
button.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
setContentView(R.layout.activity_load_xactivity);
}
});
Is in my protected void onCreate(Bundle savedInstanceState). Doesn't work. No errors, just doesn't do anything.
Button button = (Button)findViewById(R.id.create);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
setContentView(R.layout.activity_home2);
}
});
On It's own Doesn't resolve setOnClickListener. I have import android.view.View.OnClickListener set. I've tried entering different code where it says setContentView(R.layout.activity_home2);
Try adding an ID to the Layout holding the Views, Buttons (RelativeLayout, ContrasintLayout ect...) in XML. Then in java make a new Layout, and use layout.addContentView(XML) in your button:
Layout a = findViewById(R.id.layout_name);//Use whatever layout TYPE is used in XML
Button button = (Button)findViewById(R.id.create);
button.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
a.addContentView(R.layout.activity_load_xactivity);
}
});
Also, In you XML, you should give an ID to your layout then define it in java.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_name">
<!--You can use any Layout Type -->
...
</RelativeLayout>
EDIT:
I know this has nothing to with your question, but if you want to switch activity's use this instead:
Intent b = new Intent(this, JavaActivtyName.class);
startActivity(b);
I need to define a layout for multiple activities in android and from the UI part, it is successful. But to code those elements to perform on each click listeners, I need to define it in all the java pages I use.
Can we globally define this in a java page and include it in the required pages?
menuButton = findViewById(R.id.menuButton);
menuButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(getApplicationContext(), MenuActivity.class);
startActivity(i);
finish();
overridePendingTransition(0, 0);
}
});
Yes and No.
You can create a BaseActivity which has the common logic that has to be executed for each button click.
But you need to implement the listener for the button on specific activity, since life cycle of each activity is independent of other activity.
To make the code readable better (avoiding implementing listener/setOnclickListener), you can use ButterKinfe, and create a method for OnClick() annotation, and call the method in BaseActivity.
What you essentially want to do is call the findViewById(), which can only be called if you have a reference to a Context variable. You should use your Activity Context, hence you pass this to the static function, which can then access all methods accessible via Context .
public class ExampleActivity2 extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MenuUtils.setListener(this);
}
}
Define the static class like this:
public static class MenuUtils{
public static void setListener(Context context){
menuButton = context.findViewById(R.id.menuButton);
menuButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// do stuff
}
});
}
}
What you should be careful about is that any Activity you pass to this function should have a menuButton in it's layout, otherwise you run the risk of getting a NullPointerException, which is when findViewById() cannot find menuButton.
I've found numerous tutorials on how to accomplish this when you can grab the textview from the xml but nothing on how to implement such a function when you have multiple edit texts created programmatically that all need the same functionality.
After you create the EditText, you would add a click listener the same way you would to any other view. You may also need to disable the focusable attribute to prevent clicks from activating the keyboard:
editText.setFocusable(false);
editText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Open dialog here
}
});
If you have all EditText's, simply create one OnClickListener, call setOnClickListener on every EditText and pass the OnClickListener Object.
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
//open dialog here;
}
};
editText1.setOnClickListener(listener);
editText2.setOnClickListener(listener);
You should maybe store the EditText's in an array, so that you can just loop through all of them.
I have a 2 diffetent activity with button. These buttons have a equal functionality and equal ids. What is the best way to create listener of these buttons? The very long "switch" or setting "OnClick" state? On the second way I may forget to change something.
The first way:
XML:
<Button
android:id="#+id/btn_main_continue"
android:text="#string/btn_main_continue" />
JAVA:
View button = findViewById(R.id.btn_main_about);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
...
}
}
});
The second way:
XML:
<Button
android:id="#+id/btn_main_continue"
android:text="#string/btn_main_continue"
android:onClick="onClickButtonAbout" />
JAVA:
public void onClickButtonAbout(View view) {
...
}
I would suggest making your activity implement an OnClickListener, then override the onClick method in there with your switch case statements inside.
This way, you just need to put eg. button.setOnClickListener(this) in your activity.
It is kind of clean and avoids overstepping.
On another note, try to keep the ids of the XML layouts unique.
I want to have access to objects in views from views other than the main content view in the app. How can I go about doing this?
I am trying to add an onclicklistener, but it fails every time because the program can't seem to find the button.
02-12 15:26:29.034: E/AndroidRuntime(11788): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.evolutionsystems.kiroco/com.evolutionsystems.kiroco.OverviewActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
Or am I going about this the wrong way? Should I include all the buttons in the main view and have them set to hidden and then change them dynamically as the user interacts with the program?
EDIT - This is the type of code that throws the error.
final Button receiver = (Button) findViewById(R.id.receiver);
receiver.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
aboutKirocoClicked(v);
}
});
The receiver button is part of a different view to the content view so the program can't find it and it returns null.
When you call findViewById( int ) you are asking for a view within the context of the object you called.
So if this is an activity then the object must be part of the xml resource from setContent.
You can also find resources from other inflated layouts ( menu, fragement ), but you must call the findViewById on that object inorder to find the view.
Not to complicate your life, but once you are more comfortable with Android you may want to check out a dependency injection framework like Roboguice or Dagger.
In your Activity, where you would like your button to appear, you add the following code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//In activity_main.xml, you have a button.
setContentView(R.layout.activity_main);
//You get this button with the referencing ID
Button myBtn = (Button) findViewById(R.id.my_btn_id);
//Now, you can set your onClickListner
myBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Handle your button click
}
});
}