Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Animated ListView with TransitionManager
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="org.lucasr.transition.samples.MainActivity"/>
package org.lucasr.transition.samples;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.transition.TransitionManager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
import java.util.Random;
public class MainActivity extends ActionBarActivity {
private ListView listView;
private TransitionAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.list);
adapter = new SomeAdapter(this);
adapter.add("One");
adapter.add("Another");
listView.setAdapter(adapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
final int id = item.getItemId();
if (id == R.id.action_add) {
TransitionManager.beginDelayedTransition(listView);
adapter.add(1, "New item");
return true;
} else if (id == R.id.action_remove) {
TransitionManager.beginDelayedTransition(listView);
adapter.remove(1);
return true;
}
return super.onOptionsItemSelected(item);
}
}
package org.lucasr.transition.samples;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class SomeAdapter extends BaseAdapter {
private static class Item {
public final long id;
public final String value;
public Item(long id, String value) {
this.id = id;
this.value = value;
}
}
private final Context context;
private final List<Item> items = new ArrayList<Item>();
private int currentId = 0;
public SomeAdapter(Context context) {
super();
this.context = context;
}
@Override
public int getCount() {
return items.size();
}
@Override
public Object getItem(int position) {
return items.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.text_item, parent, false);
}
Item item = items.get(position);
((TextView) convertView).setText(item.value + " (" + item.id + ")");
return convertView;
}
@Override
public long getItemId(int position) {
return items.get(position).id;
}
@Override
public boolean hasStableIds() {
return true;
}
private Item createItem(String value) {
long id = ++currentId;
return new Item(id, value);
}
public void add(String value) {
items.add(createItem(value));
notifyDataSetChanged();
}
public void add(int index, String value) {
items.add(index, createItem(value));
notifyDataSetChanged();
}
public void remove(int index) {
items.remove(index);
notifyDataSetChanged();
}
}
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:gravity="center"
android:layout_margin="2dp"
android:paddingLeft="64dp"
android:paddingRight="64dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:background="#ffcc00"/>
@keyboardr

If the Adapter can get a reference to the ListView, is there anything stopping you from calling TransitionManager.beginDelayedTransition(listView) in notifyDataSetChanged()? I'd like to do this in a ListView populated by a CursorAdapter where the contents can change at any time.

@imminent

@keyboardr It's better to leave it in the ListView or Activity, and use PageAdapter.registerDataSetObserver(DataSetObserver) to register to be notified with notifyDataSetChanged() is triggered. Then you can do the TransitionManager.beginDelayedTransition(listView) there. You really don't want the adapter to deal with the ListView.

@imminent

@lucasr You have SomeAdapter as the class name, but elsewhere (including the constructor) you say TransitionAdapter (line 14 of SomeAdapter.java). Do you mean for them to always say TransitionAdapter instead of SomeAdapter?

@slidenerd

well a good approach but you wont be needing this anymore since the RecyclerView has come into the picture, it supports 2 types of animations 1) Animators that manage structural or data change and animate them and 2)Animations that you can apply on the ViewHolder root inside onBindViewHolder for animating how the recyclerview is loaded

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.