bind 2 buttons with equal functionality on different activities - java

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.

Related

findViewById() returns null on included layout?

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) {
}
});

can I have two different onclick methods for one button

I wanted to know if its possible to have two onclick methods for one buttton..Im trying to have a button that can open a new activity and send a id token to the server for firebase purposes, if possible how do i go about it on android studio
I think you are getting the underlying concept wrong.
Buttons react to clicks.
The "ActionListener" that gets triggered on that click ... can do whatever it wants. There is nothing (conceptually) that prevents you in your code to just trigger various things. Of course, you have to understand what you are doing (things like: not blocking the UI thread for too long; or how to kick of things in background threads, and so on).
No. There is only one onClick method for a Button. But you can still perform two different purposes by one button.
I am using a button to hide and show a linear layout. The code is given below :
final int[] count = {2};
//here startTopics is the button....
startTopics.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(count[0] %2==0)
{
topicLin.setVisibility(View.VISIBLE);
count[0]++;
}
else
{
topicLin.setVisibility(View.GONE);
//here topicLin is the linear layout
count[0]++;
}
}
});
It is one button and so you should apply only one onClick listener which performs the buttons job.
In your onClick-method you can just call another (private) method if you want to do multiple things without sacrificing code management.
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendTokenToServer();
// Include your code to open the activity here or outsource it again into another private method
}
});
And your method to send the token to the server:
private void sendTokenToServer() {
// Your code here.
}

Opening datepicker dialog on click of a programmatically created editext?

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.

Is there a way to summarize multiple OnClickListener into one function in AndroidStudio?

I got multiple OnClickListener for 8 ImageViews with the same logic behind. OnClick Variable-Details will be shown. I tried to summarize them in a method and tried to add them in the OnCreate method with a Loop. But it did not work. Now I have 8 listeners and also 8 addListener at onCreateMethod.
Is there a more elegant way?
private void addListenerCal1Arrow() {
ivCalArrow1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!cal1Clicked) {
cal1Clicked = true;
ivCalArrow1.setImageResource(R.drawable.arrow_symbol_up);
tvDescription1.setVisibility(View.VISIBLE);
} else {
cal1Clicked = false;
ivCalArrow1.setImageResource(R.drawable.arrow_symbol_down);
tvDescription1.setVisibility(View.GONE);
}
}
});
}
more explanation:
I got an experiment Fragment, where i can add 8 Variables max. Each variable has several textviews and also an ImageView, which holds further information about the variable. when the ImageView is Clicked it shall show the information. I got an container class holding all the widgets of a variable, like the textviews and the imageview and also the description which shall be displayed when its clicked
There are 2 level to summrize this code
1- use 1 onClick() for all ImageViews: this involves
1.a implementing OnClickListener and not using anonymous inner class
make your activity or fragment implements OnClickListener and override onClick()
public class MyActivity extends Activity implements OnClickListener {
//class implementation
#override
public void onClick(View view){
}
}
use this as OnClickLister for method setOnClickListener():
ivCalArrow1.setOnClickListener(this);//this here refers to MyActivity
ivCalArrow2.setOnClickListener(this);//this here refers to MyActivity
//and so on ...
b. recognize the click source (which ImageView) generated the action)
you will need to compare view id with the 8 ImageViews id and execute proper code based on that:
#override
public void onClick(View view){
if(view.getId() == ivCalArrow1.getId()){
//do what needed on ivCalArrow1
}else if(view.getId() == ivCalArrow2.getId()){
//do what needed on ivCalArrow2
}
//and so on ... for 3 4 5 6 7 8
}
2- make onClick() general to handle the click properly: this involves using arrays instead of single variables named with 1 2 3, like cal1Clicked cal2Clicked ... or tvDescription1, tvDescription2 ...
this can be done in several ways, it could be complex to understand or maintain, so try to make it clear
you might need a Map where ImageView.getId as key and some value based on what you need
for example,
boolean variables calXClicked may be you can use a HashMap, that the key is an identifier for calX and the value is boolean for the clicked status
from my understanding the identifier for cal1Clicked is the imageView itself ivCalArrow1 so:
declare this class-scope
HashMap<int, boolean> calClickedStatus = new HashMap();
an at onCreate() add this:
//assuming all boolean values are false on first create of activity
calClickedStatus.put(ivCalArrow1.getId,false);
calClickedStatus.put(ivCalArrow2.getId,false);
calClickedStatus.put(ivCalArrow3.getId,false); // and so on
now at onClick() you will use view.getId as key to lookup other data needed
no need to find what is the source of the click, because you will look it up using the key (view.getId)
#override
public void onClick(View view){
if (!calClickedStatus.get(view.getId())) {
calClickedStatus.put(view.getId(), true);
//the view here is actually the clicked ImageView, so just cast it and use it, replace this
//ivCalArrow1.setImageResource(R.drawable.arrow_symbol_up);
//with this
((ImageView)view).setImageResource(R.drawable.arrow_symbol_up);
//now for this, you may want to use an array of TextView to hold tvDescription1, tvDescription2 ...
//and make a map to link each tvDescriptionX to the index of licked image
tvDescription1.setVisibility(View.VISIBLE);
} else {
//do same changes here too
calClickedStatus.put(view.getId(), false);
ivCalArrow1.setImageResource(R.drawable.arrow_symbol_down);
tvDescription1.setVisibility(View.GONE);
}
}
as i mentioned earlier this could be complex and might be hard to explain
and it could be done in may ways, so this is just to guide you on the concept and the rest is up to you
You can define in your layout for each View the following:
android:onClick="myClickFct"
android:clickable="true"
and also in the class which loads the layout the method:
public void myClickFct(View view){
...
}

Android OnClickListener complexity

I need to know, what is better in terms of complexity. Either to identity a separate onClick method from xml for each button like this:
android:onClick:"clickHandler"
and the java code:
public void clickHandler(View v){
Button b = (Button) v;
//do something for that button
};
, or identify one method for all of the buttons, and separate them with if conditions.
Public void clickHandler(View v){
Button b = (Button) v;
if(b.getText().equals("a")){
}
elseif(b.getText().equals("b")){
}
//And so on.
}
I am not that good in calculating complexity and so on, but this question just irritates and I can't answer it. But what I understand, the first method increases the code lines a lot!
I generally like the latter. Except I tend to do something that looks more like this:
public void onClick(View v){
switch(v.getId()){
case R.id.button_a:
//do button a logic here
break;
case R.id.button_b:
//do button b logic here
break;
}
}
Consider making your Activity implement View.OnClickListener than in your OnCreate() simple attach with findViewById(R.id.button_a).setOnClickListener(this);
I would use a version of the second option. Create one handler, and then use a switch statement to determine which view received the event. It is code efficient and is not messy at all. Also, you don't need to list that attribute in xml... I personally think it is much easier to findViewById() in your activity and implement onClickListener. Then you can use each button's id in your switch statement.

Categories

Resources