Blinking Text in android view - android

How do I display Blinking Text in android.
Thank you all.

Actually there is an Easter egg blink tag for this in ICS! :) I don't actually recommend using it - was REALLY amused to find it in the source, though!
<blink xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="I'm blinking"
/>
</blink>

Create a view animation for it. You can do an alpha fade from 100% to 0% in 0 seconds and back again on a cycle. That way, Android handles it inteligently and you don't have to mess arround with threading and waste CPU.
More on animations here:
http://developer.android.com/reference/android/view/animation/package-summary.html
Tutorial:
http://developerlife.com/tutorials/?p=343

Using Threads in your code always wastes CPU time and decreases performance of the application. You should not use threads all the time. Use if wherever neccessary.
Use XML Animations for this purpose :
R.anim.blink
<?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="600"
android:repeatMode="reverse"
android:repeatCount="infinite"/>
</set>
Blink Activity: use it like this :-
public class BlinkActivity extends Activity implements AnimationListener {
TextView txtMessage;
Button btnStart;
// Animation
Animation animBlink;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_blink);
txtMessage = (TextView) findViewById(R.id.txtMessage);
btnStart = (Button) findViewById(R.id.btnStart);
// load the animation
animBlink = AnimationUtils.loadAnimation(getApplicationContext(),
R.anim.blink);
// set animation listener
animBlink.setAnimationListener(this);
// button click event
btnStart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
txtMessage.setVisibility(View.VISIBLE);
// start the animation
txtMessage.startAnimation(animBlink);
}
});
}
#Override
public void onAnimationEnd(Animation animation) {
// Take any action after completing the animation
// check for blink animation
if (animation == animBlink) {
}
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}
}
Let me know if you have any queries..

It can be done by adding a ViewFlipper that alternates two TextViews and Fadein and Fadeout animation can be applied when they switch.
Layout File:
<ViewFlipper android:id="#+id/flipper" android:layout_width="fill_parent" android:layout_height="wrap_content" android:flipInterval="1000" >
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="TEXT THAT WILL BLINK"/>
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="" />
</ViewFlipper>
Activity Code:
private ViewFlipper mFlipper;
mFlipper = ((ViewFlipper)findViewById(R.id.flipper));
mFlipper.startFlipping();
mFlipper.setInAnimation(AnimationUtils.loadAnimation(getApplicationContext(), android.R.anim.fade_in));
mFlipper.setOutAnimation(AnimationUtils.loadAnimation(getApplicationContext(), android.R.anim.fade_out));

public static void blinkText(TextView textView) {
Animation animation = new AlphaAnimation(1, 0); // Change alpha from fully visible to invisible
animation.setDuration(300); // duration - half a second
animation.setInterpolator(new LinearInterpolator()); // do not alter animation rate
animation.setRepeatCount(-1); // Repeat animation infinitely
animation.setRepeatMode(Animation.REVERSE); // Reverse animation at the end so the button will fade back in
textView.startAnimation(animation);
}
I can't remember where I found this but it is by far the best I've seen

If you want to make text blink on canvas in bitmap image so you can use this code
we have to create two methods
So first, let's declare a blink duration and a holder for our last update time:
private static final int BLINK_DURATION = 350; // 350 ms
private long lastUpdateTime = 0; private long blinkStart=0;
now create method
public void render(Canvas canvas) {
Paint paint = new Paint();
paint.setTextSize(40);
paint.setColor(Color.RED);
canvas.drawBitmap(back, width / 2 - back.getWidth() / 2, height / 2
- back.getHeight() / 2, null);
if (blink)
canvas.drawText(blinkText, width / 2, height / 2, paint);
}
Now create update method to blink
public void update() {
if (System.currentTimeMillis() - lastUpdateTime >= BLINK_DURATION
&& !blink) {
blink = true;
blinkStart = System.currentTimeMillis();
}
if (System.currentTimeMillis() - blinkStart >= 150 && blink) {
blink = false;
lastUpdateTime = System.currentTimeMillis();
}
}
Now it work fine

private bool _blink;
private string _initialtext;
private async void Blink()
{
_initialtext = _txtView.Text;
_txtView.Text = Resources.GetString(Resource.String.Speak_now);
while (VoiceRecognizerActive)
{
await Task.Delay(200);
_blink = !_blink;
Activity.RunOnUiThread(() =>
{
if (_blink)
_txtView.Visibility = ViewStates.Invisible;
else
_txtView.Visibility = ViewStates.Visible;
});
}
_txtView.Text = _initialtext;
_txtView.Visibility = ViewStates.Visible;
}
//this is for Xamarin android

Related

How can I make animation like whatsapp call screen?

I am trying to write an animation like in WhatsApp Call screen. But I don't know what is the true way to achieve this.
To achieve this animation I am starting trying with fadein and fadeout animation. These are my set methods for fade in and out animations.
private Animation setAnimFadeOut(int startOff,int duration){
Animation animFadeOut;
animFadeOut = new AlphaAnimation(1, 0);
animFadeOut.setInterpolator(new AccelerateInterpolator());
animFadeOut.setStartOffset(startOff);
animFadeOut.setDuration(duration);
return animFadeOut;
}
private Animation setAnimFadeIn(int startOff,int duration){
Animation animFadeIn;
animFadeIn = new AlphaAnimation(0, 1);
animFadeIn.setInterpolator(new AccelerateInterpolator());
animFadeIn.setStartOffset(startOff);
animFadeIn.setDuration(duration);
return animFadeIn;
}
and for every animations animationlisteners onAnimationEnd method triggers animation for restart. fadeIn animation starts fadeOut animation and fadeOut starts fadeIn animation.
right1FadeOut.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationEnd(Animation animation) {
right1.startAnimation(right1FadeIn);
Log.i(TAG, "onAnimationEnd: 1 outEnd");
}
});
right1FadeIn.setAnimationListener(new Animation.AnimationListener() {
Override
public void onAnimationEnd(Animation animation) {
right1.startAnimation(right1FadeOut);
Log.i(TAG, "onAnimationEnd: 1 inEnd");
}
});
Initialization
int startOff = 0;
int diff = 100;
int duration = 600;
final Animation right1FadeOut = setAnimFadeOut(startOff,duration);
final Animation right1FadeIn = setAnimFadeIn(0,duration);
final Animation right2FadeOut = setAnimFadeOut(startOff+diff,duration+diff);
final Animation right2FadeIn = setAnimFadeIn(0,duration);
final Animation right3FadeOut = setAnimFadeOut(startOff+diff*2,duration+diff*2);
final Animation right3FadeIn = setAnimFadeIn(0,duration);
I am starting animation calling fadeout for every button and it did not work as I expected. How can I achieve animation like WhatsApp?
right1.startAnimation(right1FadeOut);
right2.startAnimation(right2FadeOut);
right3.startAnimation(right3FadeOut);
this is the result.
I would first use Animator objects instead of Animation, then i can use AnimatorSet to control all animators as a group. (aka: order)
For example:
activity XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/img1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0"
android:src="#drawable/ic_launcher_foreground" />
<ImageView
android:id="#+id/img2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0"
android:src="#drawable/ic_launcher_foreground" />
<ImageView
android:id="#+id/img3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0"
android:src="#drawable/ic_launcher_foreground" />
<ImageView
android:id="#+id/img4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0"
android:src="#drawable/ic_launcher_foreground" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
Activity Class:
Java:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View[] images = {findViewById(R.id.img1), findViewById(R.id.img2), findViewById(R.id.img3), findViewById(R.id.img4),}; //array of views that we want to animate
//we will have 2 animator foreach view, fade in & fade out
//prepare animators - creating array of animators & instantiating Object animators
ArrayList<ObjectAnimator> anims = new ArrayList<>(images.length * 2);
for (View v : images) anims.add(ObjectAnimator.ofFloat(v, View.ALPHA, 0f, 1f).setDuration(80)); //fade in animator
for (View v : images) anims.add(ObjectAnimator.ofFloat(v, View.ALPHA, 1f, 0f).setDuration(80)); //fade out animator
final AnimatorSet set = new AnimatorSet(); //create Animator set object
//if we want to repeat the animations then we set listener to start again in 'onAnimationEnd' method
set.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
set.start(); //repeat animator set indefinitely
}
});
set.setStartDelay(600); //set delay every time we start the chain of animations
for (int i = 0; i < anims.size() - 1; i++) set.play(anims.get(i)).before(anims.get(i + 1)); //put all animations in set by order (from first to last)
findViewById(R.id.txt).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) { //start the animations on click
set.start();
}
});
}
}
Kotlin:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val images = arrayOf(img1, img2, img3, img4) //array of views that we want to animate
//we will have 2 animator foreach view, fade in & fade out
//prepare animators - creating array of animators & instantiating Object animators
val anims = ArrayList<ObjectAnimator>(images.size * 2)
for (v in images) anims.add(ObjectAnimator.ofFloat(v, View.ALPHA, 0f, 1f).setDuration(80)) //fade in animator
for (v in images) anims.add(ObjectAnimator.ofFloat(v, View.ALPHA, 1f, 0f).setDuration(80)) //fade out animator
val set = AnimatorSet() //create Animator set object
//if we want to repeat the animations then we set listener to start again in 'onAnimationEnd' method
set.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) = set.start() //repeat animator set indefinitely
})
set.startDelay = 600 //set delay every time we start the chain of animations
for (i in 0 until anims.size - 1) set.play(anims[i]).before(anims[i + 1]) //put all animations in set by order (from first to last)
txt.setOnClickListener { set.start() } //start the animations on click
}
}
Try to start your subsequent animations in your AnimationListeners onAnimationStart method with an increasing delay.
arrow1FadeIn.setAnimationListener( new Animation.AnimationListener() {
#Override
public void onAnimationStart( Animation animation )
{
arrow2.startAnimation( arrow2FadeIn );
}
#Override
public void onAnimationEnd( Animation animation )
{
arrow1.startAnimation( arrow1FadeOut );
}
#Override
public void onAnimationRepeat( Animation animation )
{
}
} );
arrow1FadeOut.setAnimationListener( new Animation.AnimationListener()
{
#Override
public void onAnimationStart( Animation animation )
{
}
#Override
public void onAnimationEnd( Animation animation )
{
arrow1.startAnimation( arrow1FadeIn );
}
#Override
public void onAnimationRepeat( Animation animation )
{
}
} );
And your animations like
final Animation arrow1FadeIn = setAnimFadeIn( startOff, duration );
final Animation arrow1FadeOut = setAnimFadeOut( startOff, duration );
final Animation arrow2FadeIn = setAnimFadeIn( diff, duration );
final Animation arrow2FadeOut = setAnimFadeOut( startOff, duration );
final Animation arrow3FadeIn = setAnimFadeIn( diff*2, duration );
final Animation arrow3FadeOut = setAnimFadeOut( startOff, duration );
You may need to twiddle a bit when starting all over again but this way, they should be in sync. Just start the first fadeIn Animation with
arrow1.startAnimation( arrow1FadeIn );
I suggest you use Facebook Rebound library.
It support Spring animation like facebook has. It also has cool feature called SpringChain, which automatically play a sequence of animation using Spring physics from start to end. You can custom how you want to animate the View (scale, alpha, translate ...)

image animation on screen

I am trying to make an app where in the first screen, an image (name of the app) flies into the background, and gets fixed into a certain location. I am new to android and would appreciate any help.
I have tried using setAnimationListener():
public class Pageone extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);
final ImageView imageView=(ImageView)findViewById(R.id.image);
Animation anim1 = new TranslateAnimation(0, 0, 1024, 824);
anim1.setDuration(3000);
anim1.setFillAfter(true);
anim1.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
Animation anim2 = new TranslateAnimation(0, 0, 824, 1024);
anim2.setDuration(3000);
anim2.setFillAfter(true);
imageView.clearAnimation();
imageView.startAnimation(anim2);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
imageView.startAnimation(anim1);
}
}
and the xml page as -
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.meeting.MainActivity$PlaceholderFragment"
android:background="#drawable/tapregister" >
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="#drawable/meet"
/>
</RelativeLayout>'
While running the app in android virtual device manager, I find the image fixed as seen in the layout section.
You don't need two animations to do what you want. You just need one animation that moves your ImageView from Bottom to the center of the screen.
So, drop your anim1.setAnimationListener() code. Change the Ydelta values to start in position Y+300 (for example) and end in position Y+0 (your layout original position). This will place your ImageView on the screen bottom, 300 px below your initial position and move it to the center, this is, to your layout initial position. Like this:
final ImageView imageView=(ImageView)findViewById(R.id.image);
Animation anim1 = new TranslateAnimation(0,0,300,0);
anim1.setDuration(3000);
anim1.setFillAfter(true);
imageView.startAnimation(anim1);

Switch between views with crossfade animation

I've wrote a small activity that is able to switch between two views. Now I am trying to add some animation (fade-in/fade-out effect). Can anybody explain me how to do that right?
My own attempt to do this works kinda buggy (if I will click buttons very fast, my application freezes). I use code listed below:
public class WelcomeActivity extends Activity {
private boolean isLogin = false;
private String KEY_IS_LOGIN = "KEY_IS_LOGIN";
private Animation anim_fadein;
private RelativeLayout welcome, login;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
welcome = (RelativeLayout)getLayoutInflater().inflate(R.layout.activity_welcome_menu, null);
login = (RelativeLayout)getLayoutInflater().inflate(R.layout.activity_welcome_login, null);
anim_fadein = AnimationUtils.loadAnimation(this, R.anim.anim_fadein);
if (savedInstanceState != null)
isLogin = savedInstanceState.getBoolean(KEY_IS_LOGIN, false);
if (isLogin)
setContentView(login);
else
setContentView(welcome);
}
#Override
public void onBackPressed() {
if (isLogin) {
setContentView(welcome);
welcome.startAnimation(anim_fadein);
isLogin = false;
} else {
super.onBackPressed();
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
outState.putBoolean(KEY_IS_LOGIN, isLogin);
super.onSaveInstanceState(outState);
}
public void onButton1Click(View v) {
setContentView(login);
login.startAnimation(anim_fadein);
}
public void onButtonLoginClick(View v) {
Intent i = new Intent(getApplicationContext(), MainActivity.class);
startActivity(i);
}
public void onButtonBackClick(View v) {
setContentView(welcome);
welcome.startAnimation(anim_fadein);
}
Animation XML file:
<?xml version="1.0" encoding="utf-8"?>
<alpha
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="800" />
Thanks in advance!
The way I have done this in the past is by using the ViewFlipper class and utilizing the built-in animation functions that the package provides.
Here is an example on how to do this; in my experience the transitions have been very smooth:
The XML File
<LinearLayout
//Ommitted...
<ViewFlipper
android:id="#+id/[your_id_here]"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout
<!--Your first layout XML here...-->
</RelativeLayout>
<RelativeLayout
<!--Your second layout XML here...-->
</RelativeLayout>
</ViewFlipper>
</LinearLayout>
Please note that you do not have to use relative layouts, I simply used them for the sake of clarity.
Implementing The Animations
Get a reference to the ViewFlipper in your activity:
ViewFlipper v = (ViewFlipper) findViewById(R.id.[your_id]);
Set the animations as necessary:
v.setInAnimation(AnimationUtils.loadAnimation([your_activity_name].this, R.anim.[your_in_animation here]));
v.setOutAnimation(AnimationUtils.loadAnimation([your_activity_name].this, R.anim.[your_out_animation here]));
Please note that you can find some really good prebuilt animations in the Android class files located in the following directory:
[android-sdks]/samples/android-[VERSION_NUMBER_HERE]/ApiDemos/res/anim
I highly recommend using these if you can - it will save you much time.
Now, if you wish to switch between the views, use the following commands:
v.showNext();
v.showPrevious();
You might have to change the animation files slightly to make sure the animations transition properly (i.e. make a fade right and left animation).
Hope this helps!
I think there are 2 main solution to this problem
The first one is using a ViewFlipper as suggested.
The other one is to go with the solution described here.
I prefer the second one cause it doesn't need additional View object in your view hiearchy and second you can have your 2 view all across the view tree. Not only in a single place defined by the position of the ViewFlipper.
The following Method implements cross-fade between two views:
public void CrossFade(View v1, View v2)
{
Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new DecelerateInterpolator()); //add this
fadeOut.setDuration(1000);
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator()); //add this
fadeIn.setDuration(1000);
fadeIn.setStartOffset(500);
fadeIn.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
v2.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationEnd(Animation animation) {
v2.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
fadeOut.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
v1.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationEnd(Animation animation) {
v1.setVisibility(View.GONE);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
v1.startAnimation(fadeOut);
v2.startAnimation(fadeIn);
}
In the code above, v1 will fade-out and v2 will fade-in, you can change duration and offset according to your needs

Animated Icon for ActionItem

I have been searching everywhere for a proper solution to my problem and I can't seem to find one yet. I have an ActionBar (ActionBarSherlock) with a menu that is inflated from an XML file and that menu contains one item and that one item is shown as an ActionItem.
menu:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/menu_refresh"
android:icon="#drawable/ic_menu_refresh"
android:showAsAction="ifRoom"
android:title="Refresh"/>
</menu>
activity:
[...]
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.mymenu, menu);
return true;
}
[...]
The ActionItem is displayed with an icon and no text however when a user clicks on the ActionItem, I want the icon to begin animating, more specifically, rotating in place. The icon in question is a refresh icon.
I realize that ActionBar has support for using custom views (Adding an Action View) however this custom view is expanded to cover the entire area of the ActionBar and actually blocks everything except the app icon, which in my case is not what I was looking for.
So my next attempt was to try to use AnimationDrawable and define my animation frame-by-frame, set the drawable as the icon for the menu item, and then in onOptionsItemSelected(MenuItem item) get the icon and begin animating using ((AnimationDrawable)item.getIcon()).start(). This however was unsuccessful. Does anyone know of any way to accomplish this effect?
You're on the right track. Here is how the GitHub Gaug.es app will be implementing it.
First they define an animation XML:
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="1000"
android:interpolator="#android:anim/linear_interpolator" />
Now define a layout for the action view:
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_action_refresh"
style="#style/Widget.Sherlock.ActionButton" />
All we need to do is enable this view whenever the item is clicked:
public void refresh() {
/* Attach a rotating ImageView to the refresh item as an ActionView */
LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ImageView iv = (ImageView) inflater.inflate(R.layout.refresh_action_view, null);
Animation rotation = AnimationUtils.loadAnimation(getActivity(), R.anim.clockwise_refresh);
rotation.setRepeatCount(Animation.INFINITE);
iv.startAnimation(rotation);
refreshItem.setActionView(iv);
//TODO trigger loading
}
When the loading is done, simply stop the animation and clear the view:
public void completeRefresh() {
refreshItem.getActionView().clearAnimation();
refreshItem.setActionView(null);
}
And you're done!
Some additional things to do:
Cache the action view layout inflation and animation inflation. They are slow so you only want to do them once.
Add null checks in completeRefresh()
Here's the pull request on the app: https://github.com/github/gauges-android/pull/13/files
I've worked a bit on solution using ActionBarSherlock, I've came up with this:
res/layout/indeterminate_progress_action.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="48dp"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingRight="12dp" >
<ProgressBar
style="#style/Widget.Sherlock.ProgressBar"
android:layout_width="44dp"
android:layout_height="32dp"
android:layout_gravity="left"
android:layout_marginLeft="12dp"
android:indeterminate="true"
android:indeterminateDrawable="#drawable/rotation_refresh"
android:paddingRight="12dp" />
</FrameLayout>
res/layout-v11/indeterminate_progress_action.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center" >
<ProgressBar
style="#style/Widget.Sherlock.ProgressBar"
android:layout_width="32dp"
android:layout_gravity="left"
android:layout_marginRight="12dp"
android:layout_marginLeft="12dp"
android:layout_height="32dp"
android:indeterminateDrawable="#drawable/rotation_refresh"
android:indeterminate="true" />
</FrameLayout>
res/drawable/rotation_refresh.xml
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:pivotX="50%"
android:pivotY="50%"
android:drawable="#drawable/ic_menu_navigation_refresh"
android:repeatCount="infinite" >
</rotate>
Code in activity (I have it in ActivityWithRefresh parent class)
// Helper methods
protected MenuItem refreshItem = null;
protected void setRefreshItem(MenuItem item) {
refreshItem = item;
}
protected void stopRefresh() {
if (refreshItem != null) {
refreshItem.setActionView(null);
}
}
protected void runRefresh() {
if (refreshItem != null) {
refreshItem.setActionView(R.layout.indeterminate_progress_action);
}
}
in activity creating menu items
private static final int MENU_REFRESH = 1;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(Menu.NONE, MENU_REFRESH, Menu.NONE, "Refresh data")
.setIcon(R.drawable.ic_menu_navigation_refresh)
.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS);
setRefreshItem(menu.findItem(MENU_REFRESH));
refreshData();
return super.onCreateOptionsMenu(menu);
}
private void refreshData(){
runRefresh();
// work with your data
// for animation to work properly, make AsyncTask to refresh your data
// or delegate work anyhow to another thread
// If you'll have work at UI thread, animation might not work at all
stopRefresh();
}
And the icon, this is drawable-xhdpi/ic_menu_navigation_refresh.png
This could be found in http://developer.android.com/design/downloads/index.html#action-bar-icon-pack
In addition to what Jake Wharton said, you should propably do the following to ensure that the animation stops smoothly and does not jump around as soon as the loading finished.
First, create a new boolean (for the whole class):
private boolean isCurrentlyLoading;
Find the method that starts your loading. Set your boolean to true when the activity starts loading.
isCurrentlyLoading = true;
Find the method that is started when your loading is finished. Instead of clearing the animation, set your boolean to false.
isCurrentlyLoading = false;
Set an AnimationListener on your animation:
animationRotate.setAnimationListener(new AnimationListener() {
Then, each time the animation was executed one time, that means when your icon made one rotation, check the loading state, and if not loading anymore, the animation will stop.
#Override
public void onAnimationRepeat(Animation animation) {
if(!isCurrentlyLoading) {
refreshItem.getActionView().clearAnimation();
refreshItem.setActionView(null);
}
}
This way, the animation can only be stopped if it already rotated till the end and will be repeated shortly AND it is not loading anymore.
This is at least what I did when I wanted to implement Jake's idea.
There is also an option to create the rotation in code. Full snip:
MenuItem item = getToolbar().getMenu().findItem(Menu.FIRST);
if (item == null) return;
// define the animation for rotation
Animation animation = new RotateAnimation(0.0f, 360.0f,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
animation.setDuration(1000);
//animRotate = AnimationUtils.loadAnimation(this, R.anim.rotation);
animation.setRepeatCount(Animation.INFINITE);
ImageView imageView = new ImageView(this);
imageView.setImageDrawable(UIHelper.getIcon(this, MMEXIconFont.Icon.mmx_refresh));
imageView.startAnimation(animation);
item.setActionView(imageView);
With support library we can animate icon without custom actionView.
private AnimationDrawableWrapper drawableWrapper;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
//inflate menu...
MenuItem menuItem = menu.findItem(R.id.your_icon);
Drawable icon = menuItem.getIcon();
drawableWrapper = new AnimationDrawableWrapper(getResources(), icon);
menuItem.setIcon(drawableWrapper);
return true;
}
public void startRotateIconAnimation() {
ValueAnimator animator = ObjectAnimator.ofInt(0, 360);
animator.addUpdateListener(animation -> {
int rotation = (int) animation.getAnimatedValue();
drawableWrapper.setRotation(rotation);
});
animator.start();
}
We can't animate drawable directly, so use DrawableWrapper(from android.support.v7 for API<21):
public class AnimationDrawableWrapper extends DrawableWrapper {
private float rotation;
private Rect bounds;
public AnimationDrawableWrapper(Resources resources, Drawable drawable) {
super(vectorToBitmapDrawableIfNeeded(resources, drawable));
bounds = new Rect();
}
#Override
public void draw(Canvas canvas) {
copyBounds(bounds);
canvas.save();
canvas.rotate(rotation, bounds.centerX(), bounds.centerY());
super.draw(canvas);
canvas.restore();
}
public void setRotation(float degrees) {
this.rotation = degrees % 360;
invalidateSelf();
}
/**
* Workaround for issues related to vector drawables rotation and scaling:
* https://code.google.com/p/android/issues/detail?id=192413
* https://code.google.com/p/android/issues/detail?id=208453
*/
private static Drawable vectorToBitmapDrawableIfNeeded(Resources resources, Drawable drawable) {
if (drawable instanceof VectorDrawable) {
Bitmap b = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
drawable.setBounds(0, 0, c.getWidth(), c.getHeight());
drawable.draw(c);
drawable = new BitmapDrawable(resources, b);
}
return drawable;
}
}
I took idea for DrawableWrapper from here: https://stackoverflow.com/a/39108111/5541688
its my very simple solution (for example, need some refactor)
works with standart MenuItem,
you can use it with any number of states, icons, animations, logic etc.
in Activity class:
private enum RefreshMode {update, actual, outdated}
standart listener:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_refresh: {
refreshData(null);
break;
}
}
}
into refreshData() do something like this:
setRefreshIcon(RefreshMode.update);
// update your data
setRefreshIcon(RefreshMode.actual);
method for define color or animation for icon:
void setRefreshIcon(RefreshMode refreshMode) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Animation rotation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.rotation);
FrameLayout iconView;
switch (refreshMode) {
case update: {
iconView = (FrameLayout) inflater.inflate(R.layout.refresh_action_view,null);
iconView.startAnimation(rotation);
toolbar.getMenu().findItem(R.id.menu_refresh).setActionView(iconView);
break;
}
case actual: {
toolbar.getMenu().findItem(R.id.menu_refresh).getActionView().clearAnimation();
iconView = (FrameLayout) inflater.inflate(R.layout.refresh_action_view_actual,null);
toolbar.getMenu().findItem(R.id.menu_refresh).setActionView(null);
toolbar.getMenu().findItem(R.id.menu_refresh).setIcon(R.drawable.ic_refresh_24dp_actual);
break;
}
case outdated:{
toolbar.getMenu().findItem(R.id.menu_refresh).setIcon(R.drawable.ic_refresh_24dp);
break;
}
default: {
}
}
}
there is 2 layouts with icon (R.layout.refresh_action_view (+ "_actual") ):
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="48dp"
android:layout_height="48dp"
android:gravity="center">
<ImageView
android:src="#drawable/ic_refresh_24dp_actual" // or ="#drawable/ic_refresh_24dp"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_margin="12dp"/>
</FrameLayout>
standart rotate animation in this case (R.anim.rotation) :
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="1000"
android:repeatCount="infinite"
/>
the best way is here:
public class HomeActivity extends AppCompatActivity {
public static ActionMenuItemView btsync;
public static RotateAnimation rotateAnimation;
#Override
protected void onCreate(Bundle savedInstanceState) {
rotateAnimation = new RotateAnimation(360, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration((long) 2*500);
rotateAnimation.setRepeatCount(Animation.INFINITE);
and then:
private void sync() {
btsync = this.findViewById(R.id.action_sync); //remember that u cant access this view at onCreate() or onStart() or onResume() or onPostResume() or onPostCreate() or onCreateOptionsMenu() or onPrepareOptionsMenu()
if (isSyncServiceRunning(HomeActivity.this)) {
showConfirmStopDialog();
} else {
if (btsync != null) {
btsync.startAnimation(rotateAnimation);
}
Context context = getApplicationContext();
context.startService(new Intent(context, SyncService.class));
}
}
Remember that u cant access "btsync = this.findViewById(R.id.action_sync);" at onCreate() or onStart() or onResume() or onPostResume() or onPostCreate() or onCreateOptionsMenu() or onPrepareOptionsMenu()
if u want get it just after activity start put it in a postdelayed:
public static void refreshSync(Activity context) {
Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
public void run() {
btsync = context.findViewById(R.id.action_sync);
if (btsync != null && isSyncServiceRunning(context)) {
btsync.startAnimation(rotateAnimation);
} else if (btsync != null) {
btsync.clearAnimation();
}
}
}, 1000);
}

Android fade in and fade out with ImageView

I'm having some troubles with a slideshow I'm building.
I've created 2 animations in xml for fade in and fade out:
fadein.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="2000"/>
</set>
fadeout.xml
<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:interpolator="#android:anim/accelerate_interpolator"
android:duration="2000"/>
</set>
What Im'trying to do, is to change images from an ImageView using the fade effect, so the currently displayed image will fade out, and another one will fade in.
Considering that I have an image already set, I can fadeout this Image without problem, with this:
Animation fadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.your_fade_in_anim);
imageView.startAnimation(fadeoutAnim);
But then, I set the next image to be displayed:
imageView.setImageBitmap(secondImage);
It just shows up in the imageView, and when i set the animation it hides the image, the fade it in... Is there any way to fix that, I mean, when I do imageView.setImageBitmap(secondImage); command, the image do not shows up immediately, and only when the fade in animation is executed?
I wanted to achieve the same goal as you, so I wrote the following method which does exactly that if you pass it an ImageView and a list of references to image drawables.
ImageView demoImage = (ImageView) findViewById(R.id.DemoImage);
int imagesToShow[] = { R.drawable.image1, R.drawable.image2,R.drawable.image3 };
animate(demoImage, imagesToShow, 0,false);
private void animate(final ImageView imageView, final int images[], final int imageIndex, final boolean forever) {
//imageView <-- The View which displays the images
//images[] <-- Holds R references to the images to display
//imageIndex <-- index of the first image to show in images[]
//forever <-- If equals true then after the last image it starts all over again with the first image resulting in an infinite loop. You have been warned.
int fadeInDuration = 500; // Configure time values here
int timeBetween = 3000;
int fadeOutDuration = 1000;
imageView.setVisibility(View.INVISIBLE); //Visible or invisible by default - this will apply when the animation ends
imageView.setImageResource(images[imageIndex]);
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator()); // add this
fadeIn.setDuration(fadeInDuration);
Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator()); // and this
fadeOut.setStartOffset(fadeInDuration + timeBetween);
fadeOut.setDuration(fadeOutDuration);
AnimationSet animation = new AnimationSet(false); // change to false
animation.addAnimation(fadeIn);
animation.addAnimation(fadeOut);
animation.setRepeatCount(1);
imageView.setAnimation(animation);
animation.setAnimationListener(new AnimationListener() {
public void onAnimationEnd(Animation animation) {
if (images.length - 1 > imageIndex) {
animate(imageView, images, imageIndex + 1,forever); //Calls itself until it gets to the end of the array
}
else {
if (forever){
animate(imageView, images, 0,forever); //Calls itself to start the animation all over again in a loop if forever = true
}
}
}
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
});
}
To implement this the way you have started, you'll need to add an AnimationListener so that you can detect the beginning and ending of an animation. When onAnimationEnd() for the fade out is called, you can set the visibility of your ImageView object to View.INVISIBLE, switch the images and start your fade in animation - you'll need another AnimationListener here too. When you receive onAnimationEnd() for your fade in animation, set the ImageView to be View.VISIBLE and that should give you the effect you're looking for.
I've implemented a similar effect before, but I used a ViewSwitcher with 2 ImageViews rather than a single ImageView. You can set the "in" and "out" animations for the ViewSwitcher with your fade in and fade out so it can manage the AnimationListener implementation. Then all you need to do is alternate between the 2 ImageViews.
Edit:
To be a bit more useful, here is a quick example of how to use the ViewSwitcher. I have included the full source at https://github.com/aldryd/imageswitcher.
activity_main.xml
<ViewSwitcher
android:id="#+id/switcher"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:inAnimation="#anim/fade_in"
android:outAnimation="#anim/fade_out" >
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:src="#drawable/sunset" />
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:src="#drawable/clouds" />
</ViewSwitcher>
MainActivity.java
// Let the ViewSwitcher do the animation listening for you
((ViewSwitcher) findViewById(R.id.switcher)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ViewSwitcher switcher = (ViewSwitcher) v;
if (switcher.getDisplayedChild() == 0) {
switcher.showNext();
} else {
switcher.showPrevious();
}
}
});
Have you thought of using TransitionDrawable instead of custom animations?
https://developer.android.com/reference/android/graphics/drawable/TransitionDrawable.html
One way to achieve what you are looking for is:
// create the transition layers
Drawable[] layers = new Drawable[2];
layers[0] = new BitmapDrawable(getResources(), firstBitmap);
layers[1] = new BitmapDrawable(getResources(), secondBitmap);
TransitionDrawable transitionDrawable = new TransitionDrawable(layers);
imageView.setImageDrawable(transitionDrawable);
transitionDrawable.startTransition(FADE_DURATION);
I used used fadeIn animation to replace new image for old one
ObjectAnimator.ofFloat(imageView, View.ALPHA, 0.2f, 1.0f).setDuration(1000).start();
you can do it by two simple point and change in your code
1.In your xml in anim folder of your project, Set the fade in and fade out duration time not equal
2.In you java class before the start of fade out animation, set second imageView visibility Gone then after fade out animation started set second imageView visibility which you want to fade in visible
fadeout.xml
<alpha
android:duration="4000"
android:fromAlpha="1.0"
android:interpolator="#android:anim/accelerate_interpolator"
android:toAlpha="0.0" />
fadein.xml
<alpha
android:duration="6000"
android:fromAlpha="0.0"
android:interpolator="#android:anim/accelerate_interpolator"
android:toAlpha="1.0" />
In you java class
Animation animFadeOut = AnimationUtils.loadAnimation(this, R.anim.fade_out);
ImageView iv = (ImageView) findViewById(R.id.imageView1);
ImageView iv2 = (ImageView) findViewById(R.id.imageView2);
iv.setVisibility(View.VISIBLE);
iv2.setVisibility(View.GONE);
animFadeOut.reset();
iv.clearAnimation();
iv.startAnimation(animFadeOut);
Animation animFadeIn = AnimationUtils.loadAnimation(this, R.anim.fade_in);
iv2.setVisibility(View.VISIBLE);
animFadeIn.reset();
iv2.clearAnimation();
iv2.startAnimation(animFadeIn);
For infinite Fade In and Out
AlphaAnimation fadeIn=new AlphaAnimation(0,1);
AlphaAnimation fadeOut=new AlphaAnimation(1,0);
final AnimationSet set = new AnimationSet(false);
set.addAnimation(fadeIn);
set.addAnimation(fadeOut);
fadeOut.setStartOffset(2000);
set.setDuration(2000);
imageView.startAnimation(set);
set.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) { }
#Override
public void onAnimationRepeat(Animation animation) { }
#Override
public void onAnimationEnd(Animation animation) {
imageView.startAnimation(set);
}
});
I'm using this kind of routine for programmatically chaining animations.
final Animation anim_out = AnimationUtils.loadAnimation(context, android.R.anim.fade_out);
final Animation anim_in = AnimationUtils.loadAnimation(context, android.R.anim.fade_in);
anim_out.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation)
{
////////////////////////////////////////
// HERE YOU CHANGE YOUR IMAGE CONTENT //
////////////////////////////////////////
//ui_image.setImage...
anim_in.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {}
});
ui_image.startAnimation(anim_in);
}
});
ui_image.startAnimation(anim_out);
The best and the easiest way, for me was this..
->Simply create a thread with Handler containing sleep().
private ImageView myImageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shape_count); myImageView= (ImageView)findViewById(R.id.shape1);
Animation myFadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.fadein);
myImageView.startAnimation(myFadeInAnimation);
new Thread(new Runnable() {
private Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
Log.w("hendler", "recived");
Animation myFadeOutAnimation = AnimationUtils.loadAnimation(getBaseContext(), R.anim.fadeout);
myImageView.startAnimation(myFadeOutAnimation);
myImageView.setVisibility(View.INVISIBLE);
}
};
#Override
public void run() {
try{
Thread.sleep(2000); // your fadein duration
}catch (Exception e){
}
handler.sendEmptyMessage(1);
}
}).start();
}
This is probably the best solution you'll get. Simple and Easy. I learned it on udemy.
Suppose you have two images having image id's id1 and id2 respectively and currently the image view is set as id1 and you want to change it to the other image everytime someone clicks in. So this is the basic code in MainActivity.java File
int clickNum=0;
public void click(View view){
clickNum++;
ImageView a=(ImageView)findViewById(R.id.id1);
ImageView b=(ImageView)findViewById(R.id.id2);
if(clickNum%2==1){
a.animate().alpha(0f).setDuration(2000); //alpha controls the transpiracy
}
else if(clickNum%2==0){
b.animate().alpha(0f).setDuration(2000); //alpha controls the transpiracy
}
}
I hope this will surely help

Categories

Resources