How Do I Change the onClick() Behavior of a Button? - java

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.

Related

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.
}

Calling a method from an unknow(yet) class type

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

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

revised background image comparison

i know the brainy people wont like my petty questions but im trying to learn
I,m trying to make a pairs game i have been using int so far on my apps but this game needs a different approach ive created the pairs game with ints but confusing code and a floor that pushing same button twice will delete the pair as below ive been trying with tags the code all looks clean as in no errors
public class MainActivity extends Activity {
//added Tag here for the if (pic2.getTag()==(beck));
Tag beck;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageButton pic1 = (ImageButton ) findViewById(R.id.imageButton1);
final ImageButton pic2 = (ImageButton ) findViewById(R.id.imageButton2);
pic1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
pic1.setBackgroundResource(R.drawable.becks);
pic1.setTag(R.drawable.becks);
if (pic2.getTag() == pic1.getTag()){
pic1.setVisibility(View.INVISIBLE);
pic2.setVisibility(View.INVISIBLE);}
}});
pic2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
pic2.setBackgroundResource(R.drawable.becks);
pic2.setTag(R.drawable.becks);
if (pic1.getTag() == pic2.getTag()){
pic1.setVisibility(View.INVISIBLE);
pic2.setVisibility(View.INVISIBLE);
}
}});
}}
ive tried since my original post to work out how to do ive shown code for 2 buttons all i want to do is compare and make invisible after the second button is clicked
if (pic1.getTag().equals(pic2.getTag())){
pic1.setVisibility(View.INVISIBLE);
pic2.setVisibility(View.INVISIBLE); }
the .equals crashes the app
pic1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
pic1.setBackgroundResource(R.drawable.becks);
pic1.setTag(beck);
if (pic2.getTag()==(beck));{
pic1.setVisibility(View.INVISIBLE);
pic2.setVisibility(View.INVISIBLE);}
}});
this works with or without semi but both buttons dissapear when either button clicked
if (pic1.getTag()==(pic2.getTag())){
pic1.setVisibility(View.INVISIBLE);
pic2.setVisibility(View.INVISIBLE); }
this changes the image but the buttons don,t disappear when second image clicked trying to not use ints if possible
this line works with comma to
if (pic1.getTag()==(pic2.getTag()))
if (pic1.getTag()==(pic2.getTag()));
with effect of both button disappear on 1 click of either button dread moving to the else if lol
Also can a Tag be removed if the pair of images compared if false eg
if no match remove the button tag and reset all remaining images to Default image as when i put all 24 buttons on i need a reset method
i,m finding the semi colon at end of if statement has different effects to not having can anyone point correct way when and when not to use semi colons
Use tags for saving your image-id:
pic1.setTag(R.drawable.becks);
pic2.setTag(R.drawable.becks);
You can then check and compare those by calling getTag() on the buttons that have been clicked:
public boolean isMatch(View x, View y) {
return x.getTag() == y.getTag();
}

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