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.
Related
I'm really not sure where to go with this question because I don't necessarily know how possible it is. I'm still somewhat new to Android Studio and coding overall, but I know enough to be dangerous (perhaps that's my problem - I may be thinking too grandiose for a beginner) but this is what I'm looking to do.
I have a single page app with several buttons. I'm creating an app that is essentially a score counter for an NFL game, and the section where my choices for scoring methods looks as follows:
The above section is a Horizontal LinearLayout with 2 Nested LinearLayouts for the 4 scoring buttons on each side. The vertical toggle buttons are already set to change the text on the bottom button from Fieldgoal to Safety and vice-versa depending on the True/False of the toggle for each side.
teamOneToggleButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
if (isChecked) {
teamTwoToggleButton.setChecked(false);
teamOneSafety.setText("SAFETY");
teamTwoSafety.setText("FIELDGOAL");
} else {
teamTwoToggleButton.setChecked(true);
teamTwoSafety.setText("SAFETY");
teamOneSafety.setText("FIELDGOAL");
} } });
I have that part figured out, but since a Safety scores as 2 points and a fieldgoal scores as 3 points, I need to be able to change the onClick behavior.
I was hoping that there was a Java function that would let me set a new onClick activity much like I can setText, setColor, setAlignment, set(whatever), but I can't find anything close.
I've also played around with trying to define a string based on a .getText() from the button itself, but my application crashes every time.
If anyone has any ideas my full code is here on my Github.
If I understand your question you want to change the OnClickListener.
Currently you define it in your XML:
android:onClick="touchdownClickTeamOne" //This is not recommended practice, now you know.
You should do this in your Java code instead:
Button teamOneTouchDown = findViewById(R.id.team_one_off_td);
teamOneTouchDown.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Do stuff
}
});
Now you know how to redefine any button's OnClickListener.
I'm not sure how to set it up in a way to programmatically do "this" if the button displays 'Safety' and do "that" if the button displays 'Fieldgoal'.
Currently you use this method:
public void fieldgoalClickTeamOne (View v) {
scoreTeamOne = scoreTeamOne + 3;
displayForTeamOne(scoreTeamOne);
}
We know the View v is a Button and that's Buttons are TextViews, so let's check the text:
public void fieldgoalClickTeamOne (View v) {
TextView textView = (TextView) v; // Could cast to Button, makes no difference here
if (textView.getText().toString().equals("SAFETY") {
// Do this
} else {
// Do that
}
}
PS I'm happy to see a beginner following coding conventions, your code is very easy to read. I have a few pointers.
First you should take a moment to learn the difference between if, else if, and else. Your AdapterView should only have on if statement and many else ifs.
Second you should take some time to learn about generic coding practices and/or reusability (this concept is a little tricky). Back to your AdapterViews, you only need one OnItemSelectedListener:
OnItemSelectedListener onItemSelectedListener = new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
final ImageView imageView;
if (adapterView.getId() == R.id.teamOneSpinner)
imageView = (ImageView) findViewById(R.id.team_one_spinner_team_logo);
else
imageView = (ImageView) findViewById(R.id.team_two_spinner_team_logo);
String s=((TextView)view).getText().toString();
if(s.equals("Arizona Cardinals"))
imageView.setImageResource(R.drawable.arizona_cardinals);
else if(s.equals("Atlanta Falcons"))
imageView.setImageResource(R.drawable.atlanta_falcons));
else if(s.equals("Baltimore Ravens"))
//etc, etc
Viola, one listener for multiple spinners. Set it like so:
teamOneSpinner.setOnItemSelectedListener(onItemSelectedListener);
teamTwoSpinner.setOnItemSelectedListener(onItemSelectedListener);
See how much writing I saved you! Many of your methods are repetitive, you can remove 80% of your code with these techniques.
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.
}
To put you in context, when the user clicks the floating action button the activity will check which fragment is active.
Then, depending on the fragment tag it will call a method in that specific instance.
I found a way to do it on this awesome forum but the only problem is that I don't understand what I'm doing here
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Fragment fragment = getFragmentManager().findFragmentById(R.id.fragment_container);
if (fragment.getTag() == "EXERCISES_LIST_FRAGMENT") {
//THIS IS THE PART I DONT UNDERSTAND
ArrayList t = ((ExercisesListFragment) fragment).GetArray();
//THIS IS THE PART I DONT UNDERSTAND
System.out.println(t.size());
}
}
});
It seems like casting a variable but I searched and did not see anything like this.
I want to know what is that part : ((SomeKindofClass) variable).SomeKindOfClassMethod();
I would like to read about that but I don't know how you name that
sorry for my English
Thanks
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){
...
}
I am making a basic calculator for Android by eclipse and Java. The task is there are two values, like input and result. So when the first number is pressed, it saves it, then a plus or minus sign is pressed ad then the second value which is result.
My idea was to create a method for every button something like this:
public void number1(View view){
value1 = value2;
value2 = 1;
displayValue();
}
But did not work and also I am repeating a few lines many times which isnt nice. So what about using switch, or any idea to have one single method and put it on all android:onClick"" for buttons.
So if you have any idea just explain it or write an example.
Thanks in advance.
So what about using switch,
Yes, you can use a switch statement inside of your method and switch on the id of the Button clicked. Something like
public void someMethod(View v)
{
switch (v.getId()) // get the id of the View clicked
{
case R.id.idOfButton1: // and compare it to your Button ids
// do stuff;
break;
case R.id.idOfButton2:
// do stuff;
break;
}
// put common code before or after switch statement
}
Here v is the Button clicked so you get its id and compare it.
any idea to have one single method and put it on all android:onClick"" for buttons.
In your xml for each Button add that line
<Button
...
android:onClick="someMethod"/>
The Button Docs explain how this works and the rules associated with doing it this way but fairly straightforward.
I would really advise you to use ButterKnife for this case as best practice. All you have to do is to use #OnClick annotation with requested ids.
#OnClick({ R.id.door1, R.id.door2, R.id.door3 })
public void pickDoor(DoorView door) {
if (door.hasPrizeBehind()) {
Toast.makeText(this, "You win!", LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Try again", LENGTH_SHORT).show();
}
}
And inject this views at onCreate of your Activity or Fragment.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
Views.inject(this);
}
See this site for additional examples.