Android Transitions (API 19) - How to setText() on TextView before transition? - android

I am animating a TextView using android's API19 transitions. I defined a scene that i wish to transition to:
scene = Scene.getSceneForLayout(rootLayout, R.layout.my_scene, this);
I defined my transition:
myTransition = new ChangeBounds();
myTransition.setDuration(1000);
myTransition.setInterpolator(new BounceInterpolator());
And I begin transition:
TransitionManager.go(scene, myTransition);
Everything works as long as I have the android:text hardcoded. Here is what my_scene.xml looks like:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="#+id/textview1"
android:layout_width="100dp"
android:layout_height="100dp"
android:text="text1"/>
</merge>
An identical TextView with the same id is in activity_main.xml, but in a different position.
When I try to set the text dynamically using setText() it will not change the text. I am not very experienced with this transition API so any help is appreciated.

Define the scene enter action and then call the go() method in TransitionManager. Here is the code snippet
scene = Scene.getSceneForLayout(rootLayout, R.layout.my_scene, this); scene.setEnterAction(new Runnable() {
#Override
public void run() {
TextView textView1 = (TextView)rootLayout.findViewById(R.id.textView1);
textView1.setText("Hello World");
}
}); TransitionManager.go(scene, myTransition);

What if you try to delay the transition via the TextView's event queue?
final Scene scene = Scene.getSceneForLayout(rootLayout, R.layout.my_scene, this);
final ChangeBounds myTransition = new ChangeBounds();
myTransition.setDuration(1000);
myTransition.setInterpolator(new BounceInterpolator());
TextView tv;
tv.setText("Some text");
tv.post(new Runnable() {
#Override
public void run() {
TransitionManager.go(scene, myTransition);
}
});

You may try having an initial scene by initializing a Scene variable scene one and using enter() to set the initial scene.
Then, you can transition from scene1 to scene2, your target scene. Above that, I've also noticed some lag during the change of text from scene1 to scene2. In order to counteract that, I utilized the TransitionListener class to detect when the scene was finished transitioning. Then, I altered the text using setText() after the transition.

Related

Hiding and showing multiple views using the same animation

I want to apply an animation for multiple views at the same time, how can I apply said animation to several types of views (buttons, imageviews, and other views)?
If what you want is to apply an animation on several views at the same time, simply call the startAnimation method on those views one after the other. They will be simultaneous
//Get your views
View view1 = findViewById(R.id.view1);
View view2 = findViewById(R.id.view2);
View view3 = findViewById(R.id.view3);
//Get your animation
Animation youranimation = AnimationUtils.loadAnimation(this, R.anim.animationid);
//Start animations
view1.startAnimation(youranimation);
view2.startAnimation(youranimation);
view3.startAnimation(youranimation);
Or if you have a lot of views:
Animation youranimation = AnimationUtils.loadAnimation(this, R.anim.animationid);
int[] viewIds = new int[]{R.id.view1,R.id.view2,R.id.view3,R.id.view4};
for(int id : viewIds) findViewById(id).startAnimation(youranimation);
That is, assuming you want to animate several views at the same time, if what your're doing is one after the other we would dive into animation listeners and that's another story
You may use object animators.
There is an easy example in that link which you can also use.
You may also use this tutorial.
Use ValueAnimator instead, and set views property in onAnimationUpdate.
mShowAnimator = ValueAnimator.ofFloat(0f, 1f);
mShowAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
for (View v : mTargetViews) {
v.setAlpha((Float)animation.getAnimatedValue());
}
}
});
You can create one large AnimatorSet() that includes several ObjectAnimators. This allows you to play all animations at the same time with no delay. See my answer here.

Remove image after loading screen with animation, Android

I'm trying to show a splash screen between activities. For this I'm using a handler that loads an ImageView then sets the visibility to GONE after a certain amount of time.
I wanted to make it a bit more fancy and animate it with a loadAnimation. The problem I'm running into is once the handler ends the animation stops but does not remove the loading image from the screen. Instead it is just placed as a background for the whole activity.
I would like to know how to remove the splash image after the handler stops.
Below is my code:
private static final long SPLASHTIME = 3000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main)
ImageView splash = (ImageView)findViewById(R.id.splashscreen);
final Animation a = AnimationUtils.loadAnimation(getBaseContext(),R.anim.progress_anim);
a.setDuration(1000);
splash.startAnimation(a);
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
a.cancel();
splash.setVisibility(View.GONE);
}
}, SPLASHTIME);
}
XML for splash image:
<ImageView
android:id="#+id/splashscreen"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="#drawable/loading_circle"
android:layout_gravity="center"
/>
Just declare splash globally and not in oncreate().
i think you need to add visibility :gone in XML:ImageView
and make imageview INVISIBLE
You need to add
a.setFillAfter(true);
to the end of your code inside your Runnable.

How to animate an adding of a view in Android?

I would like to know if there is a simple way to add a view (a button) to a RelativeLayout, with some kind of scale animation.
I extended a class from Button and did something like this:
public class MyButton extends Button {
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
ScaleAnimation anim = new ScaleAnimation(0,1,0,1);
anim.setDuration(1000);
anim.setFillAfter(true);
this.startAnimation(anim);
}
Then tried to add this button to a view and it didn't work. Please help!
In your activity, use instead:
parentview.addView(myButton);
Then animate the button with this:
Animation animation = AnimationUtils.loadAnimation(getBaseContext(), R.anim.slide_right_in);
animation.setStartOffset(0);
myButton.startAnimation(animation);
This is an example of slide_right_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="100%p" android:toXDelta="0" android:duration="800"/>
</set>
In addition,
This is a activity play animation function I wrote:
public Animation PlayAnim( int viewid, Context Con, int animationid, int StartOffset )
{
View v = findViewById(viewid);
if( v != null )
{
Animation animation = AnimationUtils.loadAnimation(Con, animationid );
animation.setStartOffset(StartOffset);
v.startAnimation(animation);
return animation;
}
return null;
}
You can call this like this:
PlayAnim(R.id.bottombar, (Context) this, R.anim.slide_right_in, 0);
Where:
1st parameter is the id of the view you want to apply the animation on.
2nd paramenter isThe context retrieved inside your activity.
3rd parameter is the desired animation that you put inside your anim resource folder or from android predefined animations.
4rd paremeter is the animation startoffset.
I tested your animated button implementation and it works correctly. There must be some other problem. Probably the way you add the button to the layout.
To add your button to the relative layout use code like this.
RelativeLayout rl = (RelativeLayout)findViewById(R.id.rl);
MyButton b1 = new MyButton(Main.this);
b1.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
rl.addView(b1);
Or you can inflate the button from layout. To do this create layout mybtn.xml containing your button implementation:
<?xml version="1.0" encoding="utf-8"?>
<PACKAGE_OF_MYBUTTON_HERE.MyButton
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
To add it to your layout call:
RelativeLayout rl = (RelativeLayout)findViewById(R.id.rl);
Button b = (Button)getLayoutInflater().inflate(R.layout.mybtn, rl, false);
rl.addView(b);
There might be a problem with proper positioning of your view when you add it to the relative layout. Just add code like this before calling rl.addView(b1) (the code snippet adds new button below someOtherView).
LayoutParams lp = new LayoutParams(b.getLayoutParams());
lp.addRule(RelativeLayout.BELOW, someOtherView.getId());
b.setLayoutParams(lp);
You can try adding this to your code just before adding view.I guess this code would work for any view changes. In my case was switching 2 views with animation.
TransitionManager.beginDelayedTransition(layoutlocation);//layoutlocation is parent layout(In my case relative layout) of the view which you gonna add.
Hope it works.Took 2 days for me to make this work.
It's not always necessary to use animation class to get actual animation. We can provide a delay when adding views to layout using handler as shown.
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
Animation fadeanimation = new AlphaAnimation(0,1);
fadeanimation.setDuration(position*60+100);
child.setAnimation(fadeanimation);
linearLayout.addView(child);
}
}, position*60);

Adding items into listview dynamically [duplicate]

In iOS, there is a very easy and powerful facility to animate the addition and removal of UITableView rows, here's a clip from a youtube video showing the default animation. Note how the surrounding rows collapse onto the deleted row. This animation helps users keep track of what changed in a list and where in the list they were looking at when the data changed.
Since I've been developing on Android I've found no equivalent facility to animate individual rows in a TableView. Calling notifyDataSetChanged() on my Adapter causes the ListView to immediately update its content with new information. I'd like to show a simple animation of a new row pushing in or sliding out when the data changes, but I can't find any documented way to do this. It looks like LayoutAnimationController might hold a key to getting this to work, but when I set a LayoutAnimationController on my ListView (similar to ApiDemo's LayoutAnimation2) and remove elements from my adapter after the list has displayed, the elements disappear immediately instead of getting animated out.
I've also tried things like the following to animate an individual item when it is removed:
#Override
protected void onListItemClick(ListView l, View v, final int position, long id) {
Animation animation = new ScaleAnimation(1, 1, 1, 0);
animation.setDuration(100);
getListView().getChildAt(position).startAnimation(animation);
l.postDelayed(new Runnable() {
public void run() {
mStringList.remove(position);
mAdapter.notifyDataSetChanged();
}
}, 100);
}
However, the rows surrounding the animated row don't move position until they jump to their new positions when notifyDataSetChanged() is called. It appears ListView doesn't update its layout once its elements have been placed.
While writing my own implementation/fork of ListView has crossed my mind, this seems like something that shouldn't be so difficult.
Thanks!
Animation anim = AnimationUtils.loadAnimation(
GoTransitApp.this, android.R.anim.slide_out_right
);
anim.setDuration(500);
listView.getChildAt(index).startAnimation(anim );
new Handler().postDelayed(new Runnable() {
public void run() {
FavouritesManager.getInstance().remove(
FavouritesManager.getInstance().getTripManagerAtIndex(index)
);
populateList();
adapter.notifyDataSetChanged();
}
}, anim.getDuration());
for top-to-down animation use :
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromYDelta="20%p" android:toYDelta="-20"
android:duration="#android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="#android:integer/config_mediumAnimTime" />
</set>
The RecyclerView takes care of adding, removing, and re-ordering animations!
This simple AndroidStudio project features a RecyclerView. take a look at the commits:
commit of the classic Hello World Android app
commit, adding a RecyclerView to the project (content not dynamic)
commit, adding functionality to modify content of RecyclerView at runtime (but no animations)
and finally...commit adding animations to the RecyclerView
Take a look at the Google solution. Here is a deletion method only.
ListViewRemovalAnimation project code and Video demonstration
It needs Android 4.1+ (API 16). But we have 2014 outside.
Since ListViews are highly optimized i think this is not possible to accieve. Have you tried to create your "ListView" by code (ie by inflating your rows from xml and appending them to a LinearLayout) and animate them?
Have you considered animating a sweep to the right? You could do something like drawing a progressively larger white bar across the top of the list item, then removing it from the list. The other cells would still jerk into place, but it'd better than nothing.
call
listView.scheduleLayoutAnimation();
before changing the list
I hacked together another way to do it without having to manipulate list view. Unfortunately, regular Android Animations seem to manipulate the contents of the row, but are ineffectual at actually shrinking the view. So, first consider this handler:
private Handler handler = new Handler() {
#Override
public void handleMessage(Message message) {
Bundle bundle = message.getData();
View view = listView.getChildAt(bundle.getInt("viewPosition") -
listView.getFirstVisiblePosition());
int heightToSet;
if(!bundle.containsKey("viewHeight")) {
Rect rect = new Rect();
view.getDrawingRect(rect);
heightToSet = rect.height() - 1;
} else {
heightToSet = bundle.getInt("viewHeight");
}
setViewHeight(view, heightToSet);
if(heightToSet == 1)
return;
Message nextMessage = obtainMessage();
bundle.putInt("viewHeight", (heightToSet - 5 > 0) ? heightToSet - 5 : 1);
nextMessage.setData(bundle);
sendMessage(nextMessage);
}
Add this collection to your List adapter:
private Collection<Integer> disabledViews = new ArrayList<Integer>();
and add
public boolean isEnabled(int position) {
return !disabledViews.contains(position);
}
Next, wherever it is that you want to hide a row, add this:
Message message = handler.obtainMessage();
Bundle bundle = new Bundle();
bundle.putInt("viewPosition", listView.getPositionForView(view));
message.setData(bundle);
handler.sendMessage(message);
disabledViews.add(listView.getPositionForView(view));
That's it! You can change the speed of the animation by altering the number of pixels that it shrinks the height at once. Not real sophisticated, but it works!
After inserting new row to ListView, I just scroll the ListView to new position.
ListView.smoothScrollToPosition(position);
I haven't tried it but it looks like animateLayoutChanges should do what you're looking for. I see it in the ImageSwitcher class, I assume it's in the ViewSwitcher class as well?
Since Android is open source, you don't actually need to reimplement ListView's optimizations. You can grab ListView's code and try to find a way to hack in the animation, you can also open a feature request in android bug tracker (and if you decided to implement it, don't forget to contribute a patch).
FYI, the ListView source code is here.
Here's the source code to let you delete rows and reorder them.
A demo APK file is also available. Deleting rows is done more along the lines of Google's Gmail app that reveals a bottom view after swiping a top view. The bottom view can have an Undo button or whatever you want.
As i had explained my approach in my site i shared the link.Anyways the idea is create bitmaps
by getdrawingcache .have two bitmap and animate the lower bitmap to create the moving effect
Please see the following code:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View rowView, int positon, long id)
{
listView.setDrawingCacheEnabled(true);
//listView.buildDrawingCache(true);
bitmap = listView.getDrawingCache();
myBitmap1 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), rowView.getBottom());
myBitmap2 = Bitmap.createBitmap(bitmap, 0, rowView.getBottom(), bitmap.getWidth(), bitmap.getHeight() - myBitmap1.getHeight());
listView.setDrawingCacheEnabled(false);
imgView1.setBackgroundDrawable(new BitmapDrawable(getResources(), myBitmap1));
imgView2.setBackgroundDrawable(new BitmapDrawable(getResources(), myBitmap2));
imgView1.setVisibility(View.VISIBLE);
imgView2.setVisibility(View.VISIBLE);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(0, rowView.getBottom(), 0, 0);
imgView2.setLayoutParams(lp);
TranslateAnimation transanim = new TranslateAnimation(0, 0, 0, -rowView.getHeight());
transanim.setDuration(400);
transanim.setAnimationListener(new Animation.AnimationListener()
{
public void onAnimationStart(Animation animation)
{
}
public void onAnimationRepeat(Animation animation)
{
}
public void onAnimationEnd(Animation animation)
{
imgView1.setVisibility(View.GONE);
imgView2.setVisibility(View.GONE);
}
});
array.remove(positon);
adapter.notifyDataSetChanged();
imgView2.startAnimation(transanim);
}
});
For understanding with images see this
Thanks.
I have done something similar to this. One approach is to interpolate over the animation time the height of the view over time inside the rows onMeasure while issuing requestLayout() for the listView. Yes it may be be better to do inside the listView code directly but it was a quick solution (that looked good!)
Just sharing another approach:
First set the list view's android:animateLayoutChanges to true:
<ListView
android:id="#+id/items_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"/>
Then I use a handler to add items and update the listview with delay:
Handler mHandler = new Handler();
//delay in milliseconds
private int mInitialDelay = 1000;
private final int DELAY_OFFSET = 1000;
public void addItem(final Integer item) {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
new Thread(new Runnable() {
#Override
public void run() {
mDataSet.add(item);
runOnUiThread(new Runnable() {
#Override
public void run() {
mAdapter.notifyDataSetChanged();
}
});
}
}).start();
}
}, mInitialDelay);
mInitialDelay += DELAY_OFFSET;
}

Move an ImageButton after onClick event

I have an imageButton inside a RelativeLayaut.
My imageButton is 300x350px and positioned outside the screen (on top) -300px onClick the button go down 300px and go back to the initial position when click again. The effect is like a popup window.
I could obtain this working code.
XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#drawable/pag1" android:id="#+id/relativeLayout1"
android:drawingCacheQuality="high" android:layout_width="1024px"
android:layout_height="600px">
<ImageButton android:id="#+id/imageButton8"
android:layout_width="300px"
android:layout_height="350px"
android:layout_marginLeft="720px"
android:background="#drawable/popup"
android:layout_marginTop="-300px">
</ImageButton>
</RelativeLayout>
CODE
import android.widget.RelativeLayout.LayoutParams;
...
//activity declarations
protected static final int WIDTH = 300;
protected static final int HEIGHT = 350;
int count=0;
...
///click
final ImageButton pop=(ImageButton) findViewById (R.id.imageButton8);
pop.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
count++;
if (count==1){
LayoutParams lp = new LayoutParams(WIDTH,HEIGHT);
lp.setMargins(720, -20, 4, 0);
pop.setLayoutParams(lp);
}
else{
LayoutParams lp = new LayoutParams(WIDTH,HEIGHT);
lp.setMargins(720, -300, 4, 0);
pop.setLayoutParams(lp);
count=0;
}
}
});
NOW I wont to add a smooth transition to the final position. I think in a FOR cycle using a sleep function. Your HELP is welcome
I think you should start with deciding which platform you are targeting as there is a new animation framework in Honeycomb. Have a look at this article.
If however you are targeting pre-3.0 versions then the simplest way is to define your animation in anim.xml and load it in your activity by using android.view.animation.AnimationUtils. Then once you've set your new layout params on the view, simply call public void startAnimation (Animation animation) on the view and it will animate it for you. Two lines in Java and a few more in XML.
Take a look at Animation Resources too.

Categories

Resources