I have a button that I want its text appear for 1 second then disappear for 1 second, loop for 6 seconds, here is what I tried:
for(int i = 0 ; i < 6 ; i++) {
button.setTextSize(18);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
button.setTextSize(0);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
first is it appear that the button's text size became 36 instead of 18,
second is it is does not act as I expected, never show the text,
note: the text size from start is 0.
How can I achieve this?
okey as you suggested you want to just blink your TextView, here what you can do.
create on folder under res called "anim", now create one xml file under that say
blink.xml and copy this code in it.
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="1000"
android:repeatMode="reverse"
android:repeatCount="infinite" />
</set>
Now in your Java class just apply this animation to your TextView
Animation anim = AnimationUtils.loadAnimation(getActivity(),
R.anim.blink);
yourtextview.startAnimation(anim);
Done.
Instead of blocking thread using Thread.sleep(1000) you can use handler post delayed and after 1 second and make it visible and post another one to make it disappear .
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
/* Make it visible here. */
button.setVisibility(View.VISIBLE);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
/* Make it disappear here. */
button.setVisibility(View.GONE);
}
}, 1000);
}
}, 1000);
This simple code can help you blink your textview:
final String text = yourTextView.getText().toString();
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (yourTextView.getText().length() == 0) {
yourTextView.setText(text);
} else {
yourTextView.setText("");
}
}
});
}
};
Timer timer = new Timer();
timer.scheduleAtFixedRate(timerTask,1000,1000);
Related
I have Button which function is to animate one of my ImageView for a second and delete specific table, recreate and insert the default value. Everything's working fine but one of my requirements is to show the animation aleast 1 second even recreating table is done. how can i achieve this?
NOTE: I animate my ImageView with Rotate effect so it will looks like refreshing.
refreshDatabase function
public void refreshDatabase(View v){
Button btnRefresh = (Button)findViewById(R.id.btnRef);
ImageView refreshing = (ImageView) findViewById(R.id.rfs);
btnRefresh.setClickable(false);
btnRefresh.setEnabled(false);
Animation animation = AnimationUtils.loadAnimation(this, R.anim.rotate);
//I want to start animation here
refreshing.startAnimation(animation);
....recreat table here
//Stop animation after 1 second
refreshing.clearAnimation();
}
rotate.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false" >
<rotate
android:duration="300"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:repeatMode="restart"
android:toDegrees="360" />
</set>
I try to add this,
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//recreate table here
refreshing.clearAnimation();
}
}, 1000);
but i got an error Handler is abstract; cannot be instantiated.
Anybody can help me? Thank You!!!
You can use Handler which will wait for a second and then execute clearAnimation method:
public void refreshDatabase(View v){
Button btnRefresh = (Button)findViewById(R.id.btnRef);
ImageView refreshing = (ImageView) findViewById(R.id.rfs);
btnRefresh.setClickable(false);
btnRefresh.setEnabled(false);
Animation animation = AnimationUtils.loadAnimation(this, R.anim.rotate);
//I want to start animation here
refreshing.startAnimation(animation);
....recreat table here
//Stop animation after 1 second
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
refreshing.clearAnimation();
}
}, 1000);
}
Use a Handler (http://developer.android.com/reference/android/os/Handler.html) to post delay a message or a Runnable in which you call clearAnimation()
You can set the duration of the animation like the following example in your rotate.xml file
<rotate android:interpolator="#android:anim/accelerate_interpolator"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="1000" //set this property (1000 is 1second)
android:startOffset="1500"/>
Or you can do it programatically too by using setDuration() .
ImageView iv_follow_insta = findViewById(R.id.iv_follow_insta);
Animation zoomInanimation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.dialog_zoomin);
Animation zoomOutanimation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.dialog_zoomout);
zoomOutanimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation arg0) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationRepeat(Animation arg0) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation arg0) {
iv_follow_insta.startAnimation(zoomInanimation);
}
});
zoomInanimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation arg0) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationRepeat(Animation arg0) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation arg0) {
iv_follow_insta.startAnimation(zoomOutanimation);
}
});
iv_follow_insta.startAnimation(zoomInanimation);
iv_follow_insta.startAnimation(zoomOutanimation);
new Handler().postDelayed(() -> {
zoomInanimation.setAnimationListener(null);
zoomOutanimation.setAnimationListener(null);
iv_follow_insta.clearAnimation();
}, 10000);
try this
In the code below I have 3 images stored in an imageArray. I'm animating images using a handler, but it's looping continuously, and I want it to only to run the animation once.
What I want to do is to see if it gets to the 3rd image, then stop the animation.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grade_four__place_value);
final ImageView image1 = (ImageView) findViewById(R.id.im1);
final int[] imageArray = {(R.drawable.pl1),
(R.drawable.pl2),
(R.drawable.pl3)};
final Button btn2 = (Button) findViewById(R.id.button2);
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
int i = 0;
public void run() {
image1.setImageResource(imageArray[i]);
i++;
if (i > imageArray.length - 1) {
i = 0;
}
handler.postDelayed(this, 300); // for interval...
}
};
handler.postDelayed(runnable, 500); // for initial delay..
btn2.setVisibility(View.INVISIBLE);
}
});
Have you considered using a Drawable Animation as opposed to a Handler?
You'd basically create an animation set in xml as follows:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/pl1" android:duration="300" />
<item android:drawable="#drawable/pl2" android:duration="300" />
<item android:drawable="#drawable/pl3" android:duration="300" />
</animation-list>
Let's call this file animation_drawable.xml and put it in the drawable folder. Afterwards, just use the following code to start the animation:
final AnimationDrawable drawable = (AnimationDrawable) getResources().getDrawable(R.drawable.animation_drawable);
image1.setImageDrawable(drawable);
drawable.start();
image1.postDelayed(new Runnable() {
#Override
public void run() {
image1.clearAnimation();
// Handle your animation ending here
}
}, drawable.getDuration());
That's it! I know it's a hack solution, but I thing Drawable animation makes the code clearer and more compact, but listening to the end of the animation requires a bit of workaround.
Schedule the Runnable only if the end of the image array is not reached:
public void run() {
image1.setImageResource(imageArray[i]);
i++;
if (i < imageArray.length) {
handler.postDelayed(this, 300); // for interval...
}
}
Try changing
i++;
if (i > imageArray.length - 1) {
i = 0;
}
handler.postDelayed(this, 300);
to
if (i < imageArray.length - 1) {
handler.postDelayed(this, 300);
}
i++;
Your Runnable code posts itself into handler with delay after each pass. Just instead setting i=0; when your i variable is bigger or equal array size - return from run() method. It will not reach handler.postDelayed(this, 300), so next frame will be not displayed.
Sample:
final int[] imageArray = {R.drawable.ic, R.drawable.ic, R.drawable.ic};
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
private int i = 0;
#Override
public void run() {
i++;
if(i > imageArray.length - 1) {
Log.e("ASD", "Done");
return;
}
Log.e("ASD", "Preparing next iteration");
handler.postDelayed(this, 300);
}
};
handler.postDelayed(runnable, 500);
Anyway, it's not best way to provide frame animation.
The animation starts when I clicked the ball.
It just moves down then to top then to the middle again.
However, the second onClick in the ball only works if I click in the middle, meaning the ball physically moves but the function's still in the middle.
How do I set its position according to the animation?
(The second click will cancel the animation)
onClick :
public void ballChange(View v)
{
isClicked = false;
if (ballstarted == false)
{
L1_animation = AnimationUtils.loadAnimation(this, R.anim.mercury_anim);
L1_Ball2.startAnimation(L1_animation);
ct = new CountDownTimer(4000, 1000)
{
#Override
public void onTick(long millisUntilFinished)
{
}
#Override
public void onFinish()
{
if (isClicked == false)
{
lifeline-=1;
if (lifeline == 0)
{
Toast.makeText(getApplicationContext(), "Gameover dude",
Toast.LENGTH_LONG).show();
heart.setText(""+lifeline);
GameOverDialog wp = new GameOverDialog(getApplicationContext());
wp.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
wp.show();
wp.setCancelable(false);
Mercury_L1.L1_Ball.clearAnimation();
Mercury_L1.L1_countDownTimer.cancel();
Mercury_L1.timerHasStarted = false;
Mercury_L1.isCancelled = true;
}
else
{
Toast.makeText(getApplicationContext(), String.valueOf(lifeline), Toast.LENGTH_SHORT).show();
heart.setText(""+lifeline);
minuslife.setVisibility(View.VISIBLE);
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
#Override
public void run()
{
minuslife.setVisibility(View.GONE);
}
}, 500);
Mercury_L1.this.v.vibrate(500);
}
}
}
}.start();
ballstarted = true;
Toast.makeText(getApplicationContext(), String.valueOf(ballstarted), Toast.LENGTH_SHORT).show();
}
else
{
L1_Ball2.clearAnimation();
ballstarted = false;
}
}
You are doing a view animation which only updates the place the ball is drawn and not its actual location. You should use a property animation like objectanimator. Below is some sample code for how to do that with XML.
public void doObjectAnimatorXML(){
AnimatorSet object = (AnimatorSet) AnimatorInflater.loadAnimator(getActivity(),R.animator.property_animator);
object.addListener(new AnimatorListenerAdapter(){
#Override
public void onAnimationEnd(Animator animation) {
simpleLock= false;
}
});
object.setInterpolator(new LinearInterpolator());
object.setTarget(mLittleChef); //mLittleChef is the view
object.start();
}
And the XML
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially" >
<objectAnimator
android:propertyName="x"
android:duration="1000"
android:valueTo="138"
android:valueType="floatType"/>
<objectAnimator
android:propertyName="x"
android:duration="1000"
android:valueTo="276"
android:valueType="floatType"/>
</set>
I have function that starts thread for blinking view if accepted true, but how do I stop it if false received?
private void blinkText(boolean b){
final Handler handler = new Handler();
if(b)
{
new Thread(new Runnable() {
#Override
public void run() {
int timeToBlink = 1000; //in ms
try{
Thread.sleep(timeToBlink);
}catch (Exception e) {
}
handler.post(new Runnable() {
#Override
public void run() {
TextView txt = (TextView) findViewById(R.id.tv);
if(txt.getVisibility() == View.VISIBLE){
txt.setVisibility(View.INVISIBLE);
}else{
txt.setVisibility(View.VISIBLE);
}
blinkText(true);
}
});
}}).start();
}
else
{
// stop blinking
}
}
You can define a blinking animation in xml and add it to your textview after initialising it:
res/anim/blink.xml
<?xml version="1.0" encoding="utf-8"?>
<alpha
android:fromAlpha="0"
android:toAlpha="1"
android:duration="200"
android:repeatMode="reverse"
android:repeatCount="infinite"
xmlns:android="http://schemas.android.com/apk/res/android">
</alpha>
Add animation to view:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_button);
TextView textView = (TextView) this.findViewById(R.id.textview);
Animation blink = AnimationUtils.loadAnimation(this, R.anim.blink);
textView.setAnimation(blink);
}
To start:
textView.getAnimation().start()
To stop:
textView.getAnimation().cancel()
textView.getAnimation().reset()
you need to create a boolean field as class member ( boolean mStopBlink = false; ) and track of whether the TextView is currently blink:
txt.setVisibility(View.VISIBLE);
if(!mStopBlink){
txt.setVisibility(View.INVISIBLE);
I have three scroll views that overlap. For some reason, when I set the other two to View.Gone and the one scroll view I wanted to View.Visible, then start an animation, it doesn't get triggered. These scroll views are within a fragment -- I know some features don't work fully within a fragment. Animation seems pretty basic though.
Here is my button listener's method;
sv2.setVisibility(View.GONE);
sv3.setVisibility(View.GONE);
sv1.setVisibility(View.VISIBLE);
Animation fadeInAnimation = AnimationUtils.loadAnimation(getActivity(), R.anim.fade_in_scollview);
//set your animation
sv1.startAnimation(fadeInAnimation);
also tried to set invisible, load animation, then make it visible;
sv1.setVisibility(View.INVISIBLE);
Animation fadeInAnimation = AnimationUtils.loadAnimation(getActivity(), R.anim.fade_in_scollview);
//set your animation
sv1.startAnimation(fadeInAnimation);
sv1.setVisibility(View.VISIBLE);
And here is my animation xml;
<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:interpolator="#android:anim/accelerate_interpolator"
android:duration="500"
android:repeatCount="infinite"/>
</set>
For use animation in Fragment try below code
This is my layout file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/iv_banner"
android:layout_width="fill_parent"
android:layout_height="250dp"
android:layout_gravity="center_horizontal" />
</LinearLayout>
This is my fragment java class
public class Fragment_Home extends Fragment {
public int currentimageindex = 0;
Handler mHandler = new Handler();
Runnable mUpdateResults;
//Array of drawable images
private int[] IMAGE_IDS = {
R.drawable.home_slider_stemer, R.drawable.home_slider_plane
};
//image view
private ImageView iv_banner;
private View rootView;
public Fragment_Home() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
rootView = inflater.inflate(R.layout.fragment_home, container, false);
LoadUIElements();
return rootView;
}
private void LoadUIElements() {
iv_banner = (ImageView) rootView.findViewById(R.id.iv_banner);
int delay = 1000; // delay for 1 sec.
int period = 2000; // repeat every 4 sec.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// TODO Auto-generated method stub
mHandler.post(mUpdateResults);
}
}, delay, period);
mUpdateResults = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
AnimateandSlideShow();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}
/**
* Helper method to start the animation on the splash screen
*/
protected void AnimateandSlideShow() {
// TODO Auto-generated method stub
try {
iv_banner.setImageResource(IMAGE_IDS[currentimageindex
% IMAGE_IDS.length]);
currentimageindex++;
Animation rotateimage = AnimationUtils.loadAnimation(getActivity()
.getBaseContext().getApplicationContext(), R.anim.fade_in);
iv_banner.startAnimation(rotateimage);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Don't forget to put images in your Drawable folder in res.
I got around the problem by setting an animation listener and managing all the visibility stuff inside there.
sv1.setVisibility(View.INVISIBLE);
//grab animation from anim folder in res/
Animation fadeInAnimation = AnimationUtils.loadAnimation(getActivity(), R.anim.push_up_anim);
fadeInAnimation.setAnimationListener(new AnimationListener() {
//set other scroll views to invisible once done
public void onAnimationEnd(Animation animation) {
sv2.setVisibility(View.INVISIBLE);
sv3.setVisibility(View.INVISIBLE);
}
public void onAnimationRepeat(Animation animation) {
}
//once our animation starts, we set our view to visible
public void onAnimationStart(Animation animation) {
sv1.setVisibility(View.VISIBLE);
}
});
scrollViewAnimationActive = true;
//start our animations for views that need to be removed.
//We know one of these views were showing by checking if it was "visible".
if (sv2.getVisibility() == View.VISIBLE)
sv2.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.pushed_out_anim));
else if (sv3.getVisibility() == View.VISIBLE) {
sv3.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.pushed_out_anim));
}else if (wikiParentLL.getChildCount() > 1) {
wikiParentLL.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.pushed_out_anim));
}
//finally, start our "animation"
sv1.startAnimation(fadeInAnimation);
Hope this helps.
I had exactly problem, I solved it by using onWindoFocusChangeListener and Handler.
mview.getViewTreeObserver().addOnWindowFocusChangeListener(new ViewTreeObserver.OnWindowFocusChangeListener() {
#Override
public void onWindowFocusChanged(final boolean hasFocus) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
startSeedAnimation();
}
}, 600);
}
});
Where you can get the view object in onViewCreated or simply call view? / getView() from everywhere.