I have a custom view extending from View with lots of text drawn at different angles and I want a particular string to decrease its alpha value to a certain level once, after first start. Any suggestion or snippet would be appreciated :)
postInvalidateDelayed(...) doesn't seem to work for this task.
One possibility might be to create two views, inside of a FrameLayout that overlap each other. One view would contain all the static strings, the other the string you want to animate. Then it would be a simple matter of adding an alpha animation to the animated view.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<package.MyNonAnimatedView
android:id="#+id/nonAnimatedView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<package.MyAnimatedView
android:id="#+id/animatedView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout>
And for an animation you would attach to the animated view:
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_interpolator"
android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="100" />
From within your activity's onCreate(Bundle) method, you can call AnimationUtils.loadAnimation(Context, int) to load the animation from the xml resource and attach it to the animated view (provided you give it an id).
You can add a Handler to your activity that can send messages at a specified interval. When your activity receives a callback from the handler, it can notify the view to update the parts that you want to change.
An example:
public class myActivity extends Activity implements Handler.Callback {
int mDelay = 100; // Update interval (milliseconds).
Handler mHandler = new Handler(this);
private Runnable mEvent = new Runnable() {
#Override
public void run() {
mHandler.postDelayed(mEvent, mDelay);
Message message = mHandler.obtainMessage();
// Add arguments to message, if required.
mHandler.sendMessage(message);
}
};
#Override
public boolean handleMessage(Message message) {
// Your view update code.
}
private void start() {
mHandler.postDelayed(mEvent, mDelay);
}
private void stop() {
mHandler.removeCallbacks(mEvent);
}
}
Calling start() starts the handler, stop() stops it. Determining when to stop the handler will probably be in the handleMessage(Message) code.
There was a mistake in the correct measurement of vertical text bounds to be faded. Here is my onDraw method
Paint myPaint = new Paint();
myPaint.setColor(Color.parseColor("#" + colorAlpha + "3AA6D0"));// initially colorAlpha is ff
Rect r = new Rect();
char[] a = "Hello World".toCharArray();
datePaint.getTextBounds(a, 0, a.length, r);// get the bound of the text, I was not calculating this correctly
canvas.drawText("Hello World", 0, 0, myPaint);// draw the text
int colorValue = Integer.parseInt(colorAlpha, 16);
colorValue -= 20;// decrease alpha value for next call to onDraw method by postInvalidateDelayed
if (colorValue > 40) {
colorAlpha = Integer.toHexString(colorValue);
// this will create the effect of fade out animation
// because each call to onDraw method is at the difference of 50 millisecond delay
// and in each call we are decreasing alpha value by 20.
postInvalidateDelayed(50, r.left, r.top, r.right, r.bottom);
}
Related
In code - after first part of animation pivot of view is changing and...view position too!(it is strange behavior)
Here's code(stipulation - one ValueAnimator):
ValueAnimator animator = ValueAnimator.ofFloat(0,180);
float firstAnimLineX = ((47.5f * Resources.getSystem().getDisplayMetrics().density));
float firstAnimLineY = ((2.5f * Resources.getSystem().getDisplayMetrics().density));
float secondAnimLineX = ((47.5f * Resources.getSystem().getDisplayMetrics().density));
float secondAnimLineY = ((47.5f * Resources.getSystem().getDisplayMetrics().density));
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
view.setPivotX((Float) animator.getAnimatedValue()>180/2?firstAnimLineX : secondAnimLineX);
view.setPivotY((Float) animator.getAnimatedValue()>180/2?firstAnimLineY : secondAnimLineY);
view.setRotation((Float) animator.getAnimatedValue());
}
});
XML file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="50dp"
android:layout_height="50dp"
android:id="#+id/frameLayout">
<ImageView
android:layout_width="50dp"
android:layout_height="5dp"
android:layout_gravity="center_horizontal"
android:id="#+id/line"
/>
</FrameLayout>
</RelativeLayout>
And here is what i want to do(left part; right part - it's what realy happens)(yellow point - pivot):
I watched source code of setPivotX but it doesn't says me anything.
Maybe i should call someone of invalidate-methods of view?
I recreated this code and ran it on my Android phone. It gives the exact animation you are looking for.
I created an Image to match your 'match-stick' image.
I made it 400 px wide by 40 high for an example.
I gave it the id: 'bar'
ImageView bar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bar = findViewById(R.id.bar);
bar.getLayoutParams().width = 400; // I set the dimensions here.
bar.getLayoutParams().height = 40; // I set the dimensions here.
bar.setX(0); bar.setY(0); // Then I positioned it in upper left corner.
bar.setPivotX(380); // I set the pivot a little inside the image so that it looks kinda like it is pivoting on a nail.
bar.setPivotY(20);
bar.animate().rotation(-90).setDuration(2000); // Here it animates from your first image above, to your second image in 2 seconds.
// Here I used a postDelay to allow the first animation to finish its' 2 seconds 'before' calling the second animation. No need for an animate() - listener now.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
bar.setY(360); // This re-positions the original image to the
// location where the animation ended.
bar.setRotation(90); // Because the original image was horizontal, this turns it vertical.
// Now we finish the animation to your 3rd image above.
bar.animate().rotation(0).setDuration(2000);
}
},2100);
}
I am animating a view firstView and secondView is below it.On firstView i have used object animator's property 'y' to move along in y direction but when i animate i want the secondView also move along with it because view it is below the firstView.How can i do that?
I have tried view.requestLayout() and view.invalidate() but it does not help.
Here is my layout -:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/firstView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
/>
<View
android:id="#+id/secondView"
android:layout_below="#+id/firstView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
Animations are only visually moving the view. Logically, the view is still where it was when the animation started, so the secondView will never move up because firsView technically never moved.
There are two ways to handle this depending on how you want the views to act after the animation is complete. If there are no clickable views (buttons, images, etc) within the animated view, you can apply your translation animation to firstView, and a scale animation to the second view. This will give you the effect you are looking for.
However, if there are clickable views inside, the clickable areas will not be affected by the animation and give some weird user experience with detached click areas. To handle this, you will want to create your own animation loop (on a different thread), and update the margin of firstView on each iteration. This will cause the physical location of both views to change along with their contents. If this is what you need, I can go into more detail of how to achieve this with a smooth animation.
Approach #2 in more detail
To use the second approach, you will need to create your own animation thread off of the main thread. We do not want to block the main UI thread for the duration of the animation. I'm going to assume you are wanting to move the entire view off of the screen in this example.
final View firstView = findViewById(R.id.firstView);
new Thread() {
public void run() {
long startTime = System.currentTimeMillis();
int duration = 500; // Make this whatever you want, in ms
int finalY = -firstView.getHeight();
double progress = 0;
while (progress < 1) {
progress = Math.min((System.currentTimeMillis() - startTime) / (double)duration, 1);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)firstView.getLayoutParams();
params.topMargin = (int)(progress * (double)finalY);
firstView.setLayoutParams(params);
firstView.postInvalidate();
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
}.start();
I have the following layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<FrameLayout android:id="#+id/viewgroup_left"
android:layout_height="match_parent"
android:layout_weight="2"
android:layout_width="0dp">
... children ...
</FrameLayout>
<LinearLayout android:id="#+id/viewgroup_right"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_width="0dp"
android:orientation="vertical">
... children ...
</LinearLayout>
</LinearLayout>
I end up with something like this:
+------------------------+------------+
| | |
| | |
| Left | Right |
| | |
| | |
+------------------------+------------+
When a certain toggle is toggled, I want to animate Left so that its width expands to fill the entire screen. At the same time, I would like to animate the width of Right so that it shrinks to zero. Later, when the toggle is toggled again, I need to restore things to the above state.
I've tried writing my own Animation that calls View.getWidth() but when I animate back to that value (by setting View.getLayoutParams().width) it is wider than when it began. I suspect I'm just doing it wrong. I have also read all the documentation on the Honeycomb animation stuff, but I don't want to translate or scale... I want to animate the layout width property. I can't find an example of this.
What is the correct way to do this?
Since noone helped you yet and my first answer was such a mess I'll try to give you the right answer this time ;-)
Actually I like the idea and I think this is a great visual effect which might be useful for a bunch of people. I would implement an overflow of the right view (I think the shrink looks strange since the text is expanding to the bottom).
But anyway, here's the code which works perfectly fine (you can even toggle while it's animating).
Quick explanation:
You call toggle with a boolean for your direction and this will start a handler animation call loop. This will increase or decrease the weights of both views based on the direction and the past time (for a smooth calculation and animation). The animation call loop will invoke itself as long it hasn't reached the start or end position.
The layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="10"
android:id="#+id/slide_layout">
<TextView
android:layout_weight="7"
android:padding="10dip"
android:id="#+id/left"
android:layout_width="0dip"
android:layout_height="fill_parent"></TextView>
<TextView
android:layout_weight="3"
android:padding="10dip"
android:id="#+id/right"
android:layout_width="0dip"
android:layout_height="fill_parent"></TextView>
</LinearLayout>
The activity:
public class TestActivity extends Activity {
private static final int ANIMATION_DURATION = 1000;
private View mSlidingLayout;
private View mLeftView;
private View mRightView;
private boolean mAnimating = false;
private boolean mLeftExpand = true;
private float mLeftStartWeight;
private float mLayoutWeightSum;
private Handler mAnimationHandler = new Handler();
private long mAnimationTime;
private Runnable mAnimationStep = new Runnable() {
#Override
public void run() {
long currentTime = System.currentTimeMillis();
float animationStep = (currentTime - mAnimationTime) * 1f / ANIMATION_DURATION;
float weightOffset = animationStep * (mLayoutWeightSum - mLeftStartWeight);
LinearLayout.LayoutParams leftParams = (LinearLayout.LayoutParams)
mLeftView.getLayoutParams();
LinearLayout.LayoutParams rightParams = (LinearLayout.LayoutParams)
mRightView.getLayoutParams();
leftParams.weight += mLeftExpand ? weightOffset : -weightOffset;
rightParams.weight += mLeftExpand ? -weightOffset : weightOffset;
if (leftParams.weight >= mLayoutWeightSum) {
mAnimating = false;
leftParams.weight = mLayoutWeightSum;
rightParams.weight = 0;
} else if (leftParams.weight <= mLeftStartWeight) {
mAnimating = false;
leftParams.weight = mLeftStartWeight;
rightParams.weight = mLayoutWeightSum - mLeftStartWeight;
}
mSlidingLayout.requestLayout();
mAnimationTime = currentTime;
if (mAnimating) {
mAnimationHandler.postDelayed(mAnimationStep, 30);
}
}
};
private void toggleExpand(boolean expand) {
mLeftExpand = expand;
if (!mAnimating) {
mAnimating = true;
mAnimationTime = System.currentTimeMillis();
mAnimationHandler.postDelayed(mAnimationStep, 30);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.slide_test);
mLeftView = findViewById(R.id.left);
mRightView = findViewById(R.id.right);
mSlidingLayout = findViewById(R.id.slide_layout);
mLeftStartWeight = ((LinearLayout.LayoutParams)
mLeftView.getLayoutParams()).weight;
mLayoutWeightSum = ((LinearLayout) mSlidingLayout).getWeightSum();
}
}
Just adding my 2 cents here to Knickedi's excellent answer - just in case someone needs it:
If you animate using weights you will end up with issues with clipping/non-clipping on contained views and viewgroups. This is especially true if you use viewgroups with weight as fragment containers. To overcome it, you might as well need to animate margins of the problematic child views and viewgroups / fragment containers.
And, to do all these things together, its always better to go for ObjectAnimator and AnimatorSet (if you can use them), along with some utility classes like MarginProxy
A different way to the solution posted by #knickedi is to use ObjectAnimator instead of Runnable. The idea is to use ObjectAnimator to adjust the weight of both left and right views. The views, however, need to be customised so that the weight can be exposed as a property for the ObjectAnimator to animate.
So first, define a customised view (using a LinearLayout as an example):
public class CustomLinearLayout extends LinearLayout {
public CustomLinearLayout(Context context) {
super(context);
}
public CustomLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setMyWeight(float value) {
LinearLayout.LayoutParams p = (LinearLayout.LayoutParams)getLayoutParams();
p.weight = value;
requestLayout();
}
}
Then, update the layout XML to use this custom linear layout.
Then, when you need to toggle the animation, use ObjectAnimator:
ObjectAnimator rightView = ObjectAnimator.ofFloat(viewgroup_right, "MyWeight", 0.5f, 1.0f);
ObjectAnimator leftView = ObjectAnimator.ofFloat(viewgroup_left, "MyWeight", 0.5f, 0.0f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(1000); // 1 second of animation
animatorSet.playTogether(rightView, leftView);
animatorSet.start();
The above code assumes both views are linear layout and are half in weight to start with. The animation will expand the right view to full weight (so the left one is hidden). Note that ObjectAnimator is animated using the "MyWeight" property of the customised linear layout. The AnimatorSet is used to tie both left and right ObjectAnimators together, so the animation looks smooth.
This approach reduces the need to write runnable code and the weight calculation inside it, but it needs a customised class to be defined.
I'm developing a small game where I have images that changes and a control panel (some buttons) which the user suppose to press them according to the shown image. The GameView class extends SurfaceView so when the activity starts it just create the game and set the content view (a layout with SurfaceView and some buttons in relative layout). The game call loadGameObjects during setSurfaceSize callback as follow:
public void setSurfaceSize(int width, int height)
{
synchronized (holder)
{
canvasWidth = width;
canvasHeight = height;
GameView.this.postInvalidate();
loadGameObjects(getResources());
}
}
In loadGameObjects method i keep a reference to a game pojo object which is not a view (but holds references to images) as follow:
public void loadGameObjects(Resources resouces)
{
List<GameObject> gameObjects = new LinkedList<GameObject>();
int middleX = getWidth()/2;
int middleY = getHeight()/2;
//Create the backgroung game object
BitmapDrawable background = (BitmapDrawable)resouces.getDrawable(R.drawable.g_monitor);
Bitmap bitmap = Bitmap.createScaledBitmap(background.getBitmap(), getWidth(),
getHeight(), true);
background = new BitmapDrawable(bitmap);
gameObjects.add(new GameObject(this, getContext(), background, new Point(0,0)));
//Create the game object with all its images.
Map<RunningGoblinResourceEnum, BitmapDrawable> goblinImgs = new HashMap<RunningGoblinResourceEnum, BitmapDrawable>();
goblinImgs.put(RunningGoblinResourceEnum.greenGoblinUp, (BitmapDrawable)resouces.getDrawable(R.drawable.goblin_up_green));
//This map get more entries like this...
//ourGoblin is a member var that later will be null in onClick
ourGoblin = new RunningGoblinObject(this, getContext(), goblinImgs,
new Point(middleX, middleY));
gameObjects.add(ourGoblin);
setGameObjects(gameObjects);
}
During doDraw the game objects "draw" method is called to draw themself on the canvas.
My problem is that when I click the button the reference to ourGoblin game object is null although it was valid during loadGameObjects method.
Can someone please tell me what I'm missing?
I had something simillar.
In loadGameObjects method you create ourGoblin instance using the new operator. However, if this is a view in a layout which was used with setContentView the system does not relate your view to the view in the layout and thus from the system point of view the view in the layout is still null until findViewById will be called with this view id. Try to call findViewById on that id and see if ourGoblin is still null, if not then take in mind that you still have two instances of that object, one created using the new operator and one by the system.
Sure,
You can see that it is a very simple and straight forward onClick implementation:
public void onClick(View v)
{
Log.d(getClass().getName() + "onClick", "ourGoblin = " + ourGoblin);
if(ourGoblin == null)
return;
Log.d(getClass().getName() + "onClick", "ourGoblin = " + ourGoblin.getCurrentImageEnum().toString());
int id = v.getId();
switch(id)
{
case R.id.greenUp:
if(RunningGoblinResourceEnum.greenGoblinUp.equals(ourGoblin.getCurrentImageEnum()))
{
//Do something to statistics
}
break;
}
}
and also my layout xml file is as follow:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gameFrame"
android:layout_width="match_parent" android:layout_height="match_parent">
<com.test.game.GameView android:id="#+id/gameView"
android:layout_width="match_parent" android:layout_height="match_parent" />
<RelativeLayout android:id="#+id/controlPanel"
android:layout_width="match_parent" android:layout_height="match_parent">
<Button android:id="#+id/greenUp" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_centerInParent="true"
android:text="up"/>
</RelativeLayout>
</FrameLayout>
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;
}