I am new and studying online . This is my first animation study at Android. The problem is that when I choose the answer my Card View animation is suppose to show immediately. But it didn't show as soon as I click . But I found out that after I click the button, I need to press Home button and resume it from the background apps to start the animation.The animation starts only after I do this process. Toast is showing without a problem. After I choose the answer I always need to do like that to show my animation. The app is about True or false.
Also the coding is exactly the same as my online tutorial. maybe my phone problem ?? I am using Samsung S 7 edge.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView QuestionTextView,QcountTextView;
private Button Tbutton,Fbutton;
private ImageButton prev,next;
private int count = 0;
private CardView cardView;
private Animation shake;
public Questions Qarray[] = new Questions[]{
new Questions(R.string.Q1, true),
new Questions(R.string.Q2, false),
new Questions(R.string.Q3, true),
new Questions(R.string.Q4, true),
new Questions(R.string.Q5, false),
new Questions(R.string.Q6, true),
new Questions(R.string.Q7, false)
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Tbutton = findViewById(R.id.tb);
Fbutton = findViewById(R.id.fb);
QuestionTextView = findViewById(R.id.questionshow);
QcountTextView = findViewById(R.id.Qcount);
next = findViewById(R.id.nb);
prev = findViewById(R.id.pb);
cardView = findViewById(R.id.cardView);
shake = AnimationUtils.loadAnimation(MainActivity.this,R.anim.shakeanimation);
Tbutton.setOnClickListener(this);
Fbutton.setOnClickListener(this);
next.setOnClickListener(this);
prev.setOnClickListener(this);
QuestionTextView.setText(Qarray[count].question);
}
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.tb:
giveanswer(true);
pagechange();
break;
case R.id.fb:
giveanswer(false);
pagechange();
break;
case R.id.pb:
if(count != 0) {
count = (count - 1);
pagechange();
}
break;
case R.id.nb:
count = (count + 1) % Qarray.length;
pagechange();
break;
}
}
private void pagechange() {
QuestionTextView.setText(Qarray[count].getQuestion());
QcountTextView.setText((count+1) + " out of " + Qarray.length);
}
private void giveanswer(boolean b) {
boolean correctanswer = Qarray[count].ans;
if(b == correctanswer){
fadeView();
Toast.makeText(this,R.string.yes,Toast.LENGTH_SHORT).show();
}
else{
ShakeAnimation();
Toast.makeText(this,R.string.no,Toast.LENGTH_SHORT).show();
}
}
private void fadeView(){
AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f,0.0f);
alphaAnimation.setDuration(350);
alphaAnimation.setRepeatCount(1);
alphaAnimation.setRepeatMode(Animation.REVERSE);
cardView.setAnimation(alphaAnimation);
alphaAnimation.setAnimationListener(new
Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
cardView.setCardBackgroundColor(Color.GREEN);
}
#Override
public void onAnimationEnd(Animation animation){
cardView.setCardBackgroundColor(Color.rgb(41,226,205));
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
}
private void ShakeAnimation(){
cardView.setAnimation(shake);
shake.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
cardView.setCardBackgroundColor(Color.RED);
}
#Override
public void onAnimationEnd(Animation animation) {
cardView.setCardBackgroundColor(Color.rgb(41,226,205));
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
}
}
I expect the animation show as soon as I choose the answer.
you need to call alphaAnimation.start(); or shake.start(); just having animation listeners is not gonna start your animation when you want it to start.
try adding these lines exactly where you want the animations to run.
For Example:
AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f,0.0f);
alphaAnimation.setDuration(350);
alphaAnimation.setRepeatCount(1);
alphaAnimation.setRepeatMode(Animation.REVERSE);
cardView.setAnimation(alphaAnimation);
alphaAnimation.start();
Also setAnimation should to be used with xml Animations if I'm not mistaking
Related
I'm trying to get an AlertDialog to appear if my counter is above 10.
I have tried using the TextView variable peopleCount in the if statement but it does not work too. I know using TextView will not work but I need to know if there is a workaround.
private TextView peopleCount;
private ImageView plusOne;
private ImageView minusOne;
private ImageView reset;
private int counter;
private View.OnClickListener clickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.ivPlusOne :
plusCounter();
break;
case R.id.ivMinusOne :
minusCounter();
break;
case R.id.ivReset :
initCounter();
break;
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_people);
peopleCount = (TextView)findViewById(R.id.tvPeopleCount);
plusOne = (ImageView)findViewById(R.id.ivPlusOne);
plusOne.setOnClickListener(clickListener);
minusOne = (ImageView)findViewById(R.id.ivMinusOne);
minusOne.setOnClickListener(clickListener);
reset = (ImageView)findViewById(R.id.ivReset);
reset.setOnClickListener(clickListener);
initCounter();
if( counter > 10) {
AlertDialog.Builder peopleAlert = new AlertDialog.Builder(PeopleActivity.this);
peopleAlert.setCancelable(false);
peopleAlert.setTitle("People Count High");
peopleAlert.setMessage("Please check and replenish inventory");
peopleAlert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogPeople, int which) {
dialogPeople.cancel();
}
});
peopleAlert.show();
}
private void initCounter(){
counter = 0;
peopleCount.setText(counter + "");
}
private void plusCounter(){
counter++;
peopleCount.setText(counter + "");
}
private void minusCounter(){
counter--;
peopleCount.setText(counter + "");
}
I expected the AlertDialog to appear when counter reached 11 but nothing happens.
OnCreate only runs once, You need to move the if statement to a function and call it from your plusCounter() and minusCounter() functions.
I am making an application on Android which generates one of the two available images on clicking a button and after a duration of 1 second, that image is supposed to fade away, giving the user a choice to click the button again.
The problem is that the animation works smoothly on the first button press (i.e. generates an image and then fades away), however on the second button press, the image just sits there and nothing happens. I can't figure out why.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageView firstimage = (ImageView)findViewById(R.id.imageView2);
final ImageView secondimage = (ImageView)findViewById(R.id.imageView1);
final Button clickMe = (Button)findViewById(R.id.button);
final TextView image_description = (TextView)findViewById(R.id.textView);
image_description.setText("");
final Animation fadeout = new AlphaAnimation(1,0);
fadeout.setStartOffset(1000);
fadeout.setDuration(1000);
secondimage.setAnimation(fadeout);
firstimage.setAnimation(fadeout);
image_description.setAnimation(fadeout);
secondimage.setVisibility(View.GONE);
firstimage.setVisibility(View.GONE);
image_description.setVisibility(View.GONE);
clickMe.setVisibility(View.VISIBLE);
fadeout.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) { }
#Override
public void onAnimationEnd(Animation animation) {
System.out.println("Animation block");
secondimage.setVisibility(View.GONE);
firstimage.setVisibility(View.GONE);
image_description.setVisibility(View.GONE);
clickMe.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) { }
});
clickMe.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
System.out.println("Click block");
Random r = new Random();
int i = r.nextInt(2);
clickMe.setVisibility(View.GONE);
if(i == 0) {
secondimage.setVisibility(View.VISIBLE);
image_description.setText("LOOK it's a CAT");
image_description.setVisibility(View.VISIBLE);
secondimage.setAnimation(fadeout);
image_description.setAnimation(fadeout);
} else {
firstimage.setVisibility(View.VISIBLE);
image_description.setText("LOOK it's a DOG");
image_description.setVisibility(View.VISIBLE);
firstimage.setAnimation(fadeout);
image_description.setAnimation(fadeout);
}
}
});
}
The Logs look something like this:
Click Block
Animation Block
Click Block
Click Block
Click Block
Click Block
Any idea why the code is not reaching the Animation block on 2nd click onwards?
Alright. I was able to solve my own query.
I replaced
secondimage.setAnimation(fadeout);
with
secondimage.startAnimation(fadeout);
On doing so, the code was able to reach the onAnimationEnd function.
The easiest thing to do is create/inflate a new instance of the Animation type object for each view that needs animation. As you have it now, it's trying to reuse the same object.
I have added childView with ObjectAnimator in RelativeLayout. Now when I remove all the child from RelativeLayout I still gets onAnimationEnd triggered.
How would I stop all the animation of childViews once I removed all the childs from RelativeLayout.
RelativeLayout container = (RelativeLayout) findViewById(R.id.container);
RelativeLayout.LayoutParams layoutParams = getCircleLayoutParam(R.dimen.game_circle_width, R.dimen.game_circle_ht);
container.addView(view, layoutParams);
ObjectAnimator scale = ObjectAnimator.ofPropertyValuesHolder(view,
PropertyValuesHolder.ofFloat("alpha", 0f),
PropertyValuesHolder.ofFloat("scaleY", 1f),
PropertyValuesHolder.ofFloat("y", 0, mWindowHeight));
scale.setDuration(SPEED_TIME);
scale.start();
scale.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
//Getting triggered even after calling container.removeAllViews()
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (scale != null){
scale.removeAllListeners();
scale.cancel();
scale.end();
}
container.removeAllViews();
container.invalidate();
}
});
On calling container.removeAllViews() and container.invalidate() on button click. I still gets onAnimationEnd() triggered.
Any response is highly appreciated.
When adding a View to the container, pass the Animator as tag:
view.setTag(scale);
The OnClickListener:
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i = 0; i < container.getChildCount(); i++)
{
View v = container.getChildAt(i);
Object o = v.getTag();
if (o != null && o instanceof ObjectAnimator)
{
((ObjectAnimator)o).cancel();
// or ...end(), see below
}
}
container.removeAllViews();
container.invalidate();
}
});
Use ValueAnimator.cancel() or ValueAnimator.end() depending on which result you want to achieve, see documentation
If the tag is already in use for some other purpose, one could keep a list with the ObjectAnimators and in the for loop run through that list.
Use removeAllListeners() or removeListener(Animator.AnimatorListener listener) before your calls.
I simply want to use this working animation code I have in a more efficient manner. The code below works exactly as I want it to but I don't want to copy and paste this everywhere in the thirty places across several activities in which I'll be using this specific fadeout animation. How can I set up a class to do this? The primary problem is setting the view to invisible in onAnimationEnd.
final TextView ph = (TextView) findViewById(R.id.textPlaceholder);
final Animation fadeOut = new AlphaAnimation(1.0f, 0.0f);
fadeOut.setStartOffset(1000);
fadeOut.setDuration(500);
fadeOut.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationEnd(Animation animation) {
ph.setVisibility(View.INVISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
});
ph.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ph.startAnimation(fadeOut);
}
});
Create a helper class:
Class ClickToFadeOutAnimation
private View view;
public static void attachTo(View view) {
new FadeOutAnimation(View view);
}
public FadeOutAnimation(View view) {
this.view = view;
view.setOnCLickListsner(new OnClickListener() {
animate();
)
}
public void animate() {
Animation fadeOut = ...
.. rest of your animation code
}
}
And to use it:
TextView ph = (TextView) findViewById(R.id.textPlaceholder);
ClickToFadeOutAnimation.attachTo(ph);
Extend the AlphaAnimation class where you set the duration, offset and AnimationListener in the constructor.
I am willing to create a news bar in android application and I used the animation to move TextView from left to right and fill it each round with a new text from array of strings. I faced a lot of problems and I used more than 5 ways but each one has a bad behaviour. the main problem is that when the animation ends it refreshes the textView and it appears like flashing which is not a user-friendly behaviour.
Here is a code snippet:
TextView my_text;
Animation slideRight;
Animation slideLeft;
String [] text = {"TwoOneOneOneOneOneOneOneOneOneTwo","OneTwoTwoTwoTwoTwoTwoTwoTwoTwoTwoOne",
"OneThreeThreeThreeThreeThreeThreeThreeOne","OneFourFourFourFourFourFourFourOne",
"OneFiveFiveFiveFiveFiveFiveFiveOne","OneSixSixSixSixSixSixSixOne",
"OneSevenSevenSevenSevenSevenSevenSeveOne","OneEightEightEightEightEightEightEightOne",
"OneNineNineNineNineNineNineNineOne"};
int arr_length;
int count = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
arr_length = text.length;
slideRight = AnimationUtils.loadAnimation(this, android.R.anim.slide_out_right);
slideRight.setDuration(2000);
slideRight.setRepeatCount(Animation.INFINITE);
slideRight.setAnimationListener(slideRightListener);
slideLeft = AnimationUtils.loadAnimation(this, android.R.anim.slide_in_left);
slideLeft.setDuration(2000);
slideLeft.setAnimationListener(slideLeftListener);
my_text = (TextView) findViewById(R.id.textView1);
my_text.setVisibility(TextView.VISIBLE);
my_text.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), my_text.getText(), Toast.LENGTH_SHORT).show();
}
});
slideLeft.setAnimationListener(slideLeftListener);
my_text.startAnimation(slideLeft);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
AnimationListener slideLeftListener = new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
my_text.setVisibility(TextView.VISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) {
my_text.setVisibility(TextView.VISIBLE);
}
#Override
public void onAnimationEnd(Animation animation) {
my_text.setVisibility(TextView.VISIBLE);
my_text.startAnimation(slideRight);
}
};
AnimationListener slideRightListener = new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
my_text.setVisibility(TextView.VISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) {
my_text.setVisibility(TextView.VISIBLE);
}
#Override
public void onAnimationEnd(Animation animation) {
my_text.setVisibility(TextView.VISIBLE);
if(count<arr_length)
{
my_text.setText(text[count]);
count+=1;
my_text.startAnimation(slideLeft);
}
else
{
count=0;
my_text.setText(text[count]);
my_text.startAnimation(slideLeft);
}
}
};
}
I think ViewFlipper is more suitable for you.
Try adding setFillAfter(true) as that might stop the "refresh" behavior at the end of the Animation.
As I commented on #Bill above I realized that the refresh issue related to Android version.
I have tested the same code above on devices with Android Ice-Cream-Sandwich and it didn't "refresh".
If there is any solution on non-ICS I will accept it.
I've got this link and I found it great to me and can be customized as my requirements.
It uses HorizonalSlideshow.