I have many buttons in my MainActivity.xml and i wanted to add an animation to all of them such that when the MainActivity is launched all buttons get a TRANSLATIONX animation to bring them into view. I have succesfully created the Button array using button as a data type and added three buttons to it as a sample...
The problem however is iterating through the button array to add animation property to each...
Here is the trier code i used to reach where i am, Suggestions and Solutions are greatly appreciated...
class Prime : AppCompatActivity
{
//Creating button array
Button[] mybuttons;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.Prime);
//Button definitions
Button button1 = this.FindViewById<Button>(Resource.Id.button1);
Button button2 = this.FindViewById<Button>(Resource.Id.button2);
Button button3 = this.FindViewById<Button>(Resource.Id.button3);
//Adding the buttons to an array
mybuttons = new Button[3] { button1, button2, button3 };
//Defining a view animation
ObjectAnimator animator = ObjectAnimator.OfFloat(button3, "translationX", 130f);
animator.SetDuration(2000);
animator.Start();
//This is where i need the loop code to iterate through the button array and to each of them them the animation object property
I tried replacing the button3 parameter in the ObjectAnimator.OfFloat method with mybuttons but it didnt work. Thanks
The loop foreach works fine to access every button in the array and style it with respect to the Object Animator.
foreach(Button button in mybuttons){
ObjectAnimator animator = ObjectAnimator.OfFloat(button, "translationX", 130f);
animator.SetDuration(2000);
animator.Start();
}
The foreach loop is easy to understand and implement for Button arrays than its counter parts
Related
I'm trying to create a tic tac toe game for practice using simple buttons that change their text to x or o. Once a winner is found, all buttons should be reset to have the text "..." instead of x/o. It feels stupid to be doing this for each button but I can't figure out how to iterate over them. The buttons are named button1, button2, ..., and button9. Right now I'm using the same 3 lines of code for each button and just repeating that and that's not very DRY-friendly.
Tried to do a for loop and string concatenation (sort of like: findViewById(R.id."button"+i), but that obviously doesn't work hahah). I'm sure this is a stupid question but I've had this problem a couple of times now and I really wanna figure out how to so this better. [Image of the App][1]
if(winnerFound){
// print winner on screen and reset game
resetGame();
}
}
public void resetGame(){
// set all buttons clickable again and set text to "..."
// could be done in a for loop but idk how
Button button1 = (Button) findViewById(R.id.button1);
button1.setText("...");
button1.setEnabled(true);
Button button2 = (Button) findViewById(R.id.button2);
button2.setText("...");
button2.setEnabled(true);
Button button3 = (Button) findViewById(R.id.button3);
button3.setText("...");
button3.setEnabled(true);
Button button4 = (Button) findViewById(R.id.button4);
button4.setText("...");
button4.setEnabled(true);
// ... (9 buttons in total)'''
[1]: https://i.stack.imgur.com/1ocbZ.jpg
Simple solution based on your code:
Create a member variable holding the list of your buttons List<Button> and iterate them setting the text to empty.
class MyActivity: Activity {
private val buttonList: MuttableList<Button>
private val button1: Button
private val button2: Button
fun onCreate(...) {
button1 = findViewById(R.id.button_01)
button2 = findViewById(R.id.button_02)
buttonList.add(button1)
buttonList.add(button2)
....
}
}
More consideration about your code:
You shouldn't use findViewById every time you want to use a button referente. It should be ideally only used once in your onCreate method of your activity(onViewCreated if it's a fragment) and set to a member variable .
Example
class MyActivity: Activity {
private val button1: Button
fun onCreate(...) {
button1 = findViewById(R.id.button_01)
}
}
This is a code for blinking textview on a button click..
start.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
recordShow.setVisibility(View.VISIBLE);
Animation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(1000); //You can manage the time of the blink with this parameter
anim.setStartOffset(20);
anim.setRepeatMode(Animation.REVERSE);
anim.setRepeatCount(Animation.INFINITE);
recordShow.startAnimation(anim);
}
i have to stop blinking on another button click...what to do..??
Another approach could be:
1. Declare the Animation and TextView objects globally (outside any methods) in your Activity.
private Animation mAnim;
private TextView mRecordShow;
2. Setup a class that sets your animation properties and starts it. Let this class expect a TextView widget as its parameter.
protected void setBlinkingText(TextView textView) {
mAnim = new AlphaAnimation(0.0f, 1.0f);
mAnim.setDuration(1000); // Time of the blink
mAnim.setStartOffset(20);
mAnim.setRepeatMode(Animation.REVERSE);
mAnim.setRepeatCount(Animation.INFINITE);
textView.startAnimation(mAnim);
}
3. Setup another class that stops your animation on a given text view. Let this class expect a TextView widget as its parameter as well.
protected void removeBlinkingText(TextView textView) {
textView.clearAnimation();
}
4. Now you can use your classes wherever desired, passing it the appropriate text views.
e.g.
(a) In your onClick() method where you want to start the animation, replace all your animation code with:
setBlinkingText(mRecordShow);
(b) wherever you want to stop the animation on that text view, just call:
removeBlinkingText(mRecordShow);
The following assumes you want to stop the blink by clicking the same button. If you want to stop the click using a different button, you can split the if-else in the onClick() below into separate click handlers.
First, move anim outside onClick() and make it a field of the containing class. You need anim to be stored somewhere so you can cancel it later.
Animation anim = new AlphaAnimation(0.0f, 1.0f)
anim.setDuration(1000); //You can manage the time of the blink with this parameter
anim.setStartOffset(20);
anim.setRepeatMode(Animation.REVERSE);
anim.setRepeatCount(Animation.INFINITE);
Second, create a boolean field in the containing class to keep track of whether the TextView is currently blinking:
boolean mBlinking = false;
Then:
#Override
public void onClick(View v)
{
recordShow.setVisibility(View.VISIBLE);
if(!mBlinking){
recordShow.startAnimation(anim);
mBlinking = true;
} else{
recordShow.clearAnimation(anim); // cancel blink animation
recordShow.setAlpha(1.0f); // restore original alpha
mBlinking = false;
}
}
I usually code
Button button1 = (Button)findViewById(R.id.start1);
button1.setOnClickListener(mStart1Listener);
Button button2 = (Button)findViewById(R.id.start2);
button2.setOnClickListener(mStart2Listener);
But in android sample, I found these in ServiceStartArgumentsController.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.service_start_arguments_controller);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.start1);
button.setOnClickListener(mStart1Listener);
button = (Button)findViewById(R.id.start2);
button.setOnClickListener(mStart2Listener);
button = (Button)findViewById(R.id.start3);
button.setOnClickListener(mStart3Listener);
button = (Button)findViewById(R.id.startfail);
button.setOnClickListener(mStartFailListener);
button = (Button)findViewById(R.id.kill);
button.setOnClickListener(mKillListener);
}
What's the difference between them, and why one button can add multiple ClickListener
What's the difference between them, and why one button can add multiple ClickListener
A View can only have one OnClickListener. The second approach is just re-using the variable button, notice the third line:
Button button = (Button)findViewById(R.id.start1);
button.setOnClickListener(mStart1Listener);
button = (Button)findViewById(R.id.start2); // This one
It overrides the previous value of button with a new Button and the new Button will be assigned the next OnClickListener.
That's not one button. It changes before each setOnClickListener; The code just uses one variable for different buttons on that activity.
I create buttons dynamically based on the size of an array list that i get from another object. For each entry of the arraylist i need to create three buttons each one with different action.
Like this i need to create 3 times the sizes of arraylist number of buttons. If i had only one set of buttons I can write onClick()-method which takes the id of the button but here i have 3 buttons for each entry and need to write 3 different actions for those three buttons.
How could this be done?
Similar thing I have done when i needed a textview for each of my array item.it was like-
String[] arrayName={"abc","def","ghi"};
for(int i=0;i<arrayName.length;i++)
{
TextView tv=new TextView(context);
tv.setPadding(20, 5, 40, 5);
tv.setText(arrayName[i]);
tv.setTextSize(1, 12);
tv.setLayoutParams(new Gallery.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
tv.setTextColor(Color.parseColor("#2554C7"));
tv.setClickable(true);
tv.setId(i);
layout.addView(tv);
}
In same way,you can add button in similar way. and in click event of each of them,you can code for their actions separately.(I have not tried this).So in each iteration,you will have 3 buttons for each of the array item.
Edit - 1:
You can differentiate ids like:
mButton1.setId(Integer.parseInt(i+"1"));
mButton2.setId(Integer.parseInt(i+"2"));
mButton3.setId(Integer.parseInt(i+"3"));
Then you can set click listener on each of the button like mButton1.setOnClickListener... and so on.
Declare a list of buttons:
private List<Button> buttons = new ArrayList<Button>();
Then add each button to this list:
buttons.add(0, (Button) findViewById(id in ur layout));
Inside a for loop give click listener:
Button element = buttons.get(i);
element.setOnClickListener(dc);
where dc is ur object name for your inner class that implements OnClickListener.
To access each button you can give:
Button myBtn;
#Override
public void onClick(View v) {
myBtn = (Button) v;
// do operations related to the button
}
Create the Common Listener class for your button action event and set the used into the setOnClickListener() method
Now set the unique id for the buttons.
Now suppose your class look like this :
class MyAction implements onClickListener{
public void onClick(View view){
// get the id from this view and set into the if...else or in switch
int id = view.getId();
switch(id){
case 1:
case 2:
/// and so on...
}
//// do operation here ...
}
}
set this listener in button like this way.
Button b1 = new Button(context);
b1.setId(1);
b1.setOnClickListenr(new MyAction());
Button b2 = new Button(context);
b2.setId(2);
b2.setOnClickListener(new MyAction());
I have created a bunch of ImageButtons programmatically while in a for loop. They have worked fine as the data displayed in a HorizontalScrollView. Now I need each one to go dim or bright when clicked. First click will setAlpha(45); second click will setAlpha(255);.
I don't think I fully understand how the Views and onClickListener works yet. It seems the onClick function examples I find take a View. How would that function know which button is clicked? Perhaps there is an easier way to do what I want?
Here are the ImageButtons.
TableRow tr0 = new TableRow(this);
tr0.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
for(int but=0; but<ClueList.size(); but++){
ImageButton clueBut = new ImageButton(this);
clueBut.setBackgroundResource(0);
clueBut.setImageBitmap(ClueList.get(but).btmp);
//clueBut.setOnClickListener(this);
tr0.addView(clueBut);
}
Is there something I need to do to make the buttons identifiable? And how would that pass in through into the onClick function to be used?
-: Added Information :-
I am starting to wonder if the problem isn't with the buttons, but with the way I built the screen. More information added.
The Game activity is the main game, which uses the PuzzleView for the upper part of the screen holding the game grid. The lower part is where the ImageButtons are and I built them in place in the Game class.
public class Game extends Activity{
//various variables and stuff
private PuzzleView puzzleView; // The PuzzleView is from another .java file
// public class PuzzleView extends View
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
LinearLayout mainPanel = new LinearLayout(this);
mainPanel.setOrientation(LinearLayout.VERTICLE);
puzzleView = new PuzzleView(this);
mainPanel.addView(puzzleView);
HorizontalScrollView bottom = new HorizontalScrollView(this);
mainPanel.addView(bottom);
TableLayout clues = new TableLayout(this);
bottom.addView(clues);
TableRow tr0 = new TableRow(this);
for(int but=0; but<ClueList.size(); but++){
ImageButton clueBut = new ImageButton(this);
clueBut.setImageBitmap(ClueList.get(but).btmp);
tr0.addView(clueBut);
}
When I try to add the ClickListener(this) I get errors about this not being able to be a Game. I have similar problems in the onClick(View v) function referencing the View. Are these problems because I am building the buttons in the Game Activity instead of a View class?
Thanks
When you set up an OnClickListener and implement the onClick(View v) callback, it's the Dalvik VM the one that will call that method each time the View is clicked, and it will pass the View instance as a parameter. Thus, the code you write inside that method will be applied only to the View that received the click and not to any other View. Add something like this to your loop:
clueBut.setOnClickListener(new OnClickListener() {
public void onClick (View v) {
if (v.getAlpha() == 1f)
v.setAlpha(0.2f);
else
v.setAlpha(1f);
}
});
In the onClick event:
public void onClick(View currentView)
{
Button currentButton = (Button)CurrentView;
//Do whatever you need with that button here.
}
To identify each view uniquely use the property
View. setId(int)
In your case the code would look something like this
for(int but=0; but<ClueList.size(); but++){
ImageButton clueBut = new ImageButton(this);
clueBut.setBackgroundResource(0);
clueBut.setImageBitmap(ClueList.get(but).btmp);
clueBut.setId(but);
//clueBut.setOnClickListener(this);
tr0.addView(clueBut);
}
Inside the onclick listener match the id of the view using findViewByID()