Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to swapping ListView items with animation?

I want to implement swapping ListView item with animations like in XE Currency Application

XE animation

from the list when user tap on GBP-British Pound that row will go up side and fit upon INR - Indian Rupee with animations and row INR - Indian Rupee will replace on place of GBP-British Pound

I have tried one animation in listview (used header in listview) then it is working perfect, but the issue is that the header is also scrolled up and down with listview and I want the header view (or any view) fixed at top and below it list can be scrolled

I have tried one fix view at top in Relative Layout and keep listview below the top view at that time animation is worked but inside only listview not outside of listview

how can we implement that in android ?

like image 980
Jayesh Avatar asked Oct 20 '22 00:10

Jayesh


2 Answers

Why reinvent the wheel? There's out a couple of well-documented and well-structured libraries for dealing with ListView. For example ListViewAnimations is the best one, IMO.

Features

  • Appearance animations for items in ListViews, GridViews, other AbsListViews
    • Built in animations include Alpha, SwingRightIn, SwingLeftIn, SwingBottomIn, SwingRightIn and ScaleIn.
    • Other animations can easily be added
    • StickyListHeaders is supported, other implementations can easily be added.
  • Swipe-to-Dismiss, Swipe-To-Dismiss with contextual undo
  • Drag-and-Drop reordering This is what you need
  • Animate addition of items
  • Smoothly expand your items to reveal more content

enter image description here

like image 71
frogatto Avatar answered Nov 01 '22 15:11

frogatto


I had pretty similar problem a while ago. I needed to have a page, where I can re-arrange entries (musical song tracks). So here's my implementation:

  • DynamicListView (too long to post it here)

My AllTracksFragment, that allows to re-order tracks

public class AllTracksFragment extends SupportFragmentBase {

    DynamicListView allTracksListView;

    private ArrayList<Track> allTracksList = new ArrayList<>();
    TracksListViewAdapter allTracksAdapter;

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_all_tracks, container, false);
        setHasOptionsMenu(true);

        allTracksListView = (DynamicListView)rootView .findViewById(R.id.allTracksListView);

        Track track1 = new Track();  // Track is simple model class
        track1.trackName = "Winter\'s Coming (Acoustic) 1";
        track1.trackId = "47580057";

        Track track2 = new Track();
        track2.trackName = "Winter\'s Coming (Acoustic) 2";
        track2.trackId = "47580057";

        Track track3 = new Track();
        track3.trackName = "Winter\'s Coming (Acoustic) 3";
        track3.trackId = "47580057";

        allTracksList.add(track1);
        allTracksList.add(track2);
        allTracksList.add(track3);

        allTracksAdapter = new TracksListViewAdapter(allTracksList, eventBus);
        allTracksListView.setTracksList(allTracksList); //SEE DynamicListView class
        allTracksListView.setAdapter(allTracksAdapter);
        allTracksListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

        return rootView;
    }
}

And the AllTracksFragment layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.myapp.views.DynamicListView
        android:id="@+id/allTracksListView"
        android:layout_marginTop="12dp"
        android:scrollbars="none"
        android:divider="@null"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</RelativeLayout>

TracksListViewAdapter (if needed):

public final class TracksListViewAdapter extends BaseListViewArrayAdapter<PlayTrackView, Track> {  // extended version of simple BaseAdapter

    final int INVALID_ID = -1;

    public TracksListViewAdapter(final List<Track> tracks) {
        super(tracks == null ? new ArrayList<Track>(0) : tracks);
        if (tracks != null) {
            for (int i = 0; i < tracks.size(); ++i) {
                mIdMap.put(tracks.get(i), i);
            }
        }
    }

    public PlayTrackView createNewView(final Context context, final int position) {
        return new PlayTrackView(context);  // PlayTrackView - is an extension of FrameLayout
    }

    HashMap<Track, Integer> mIdMap = new HashMap<>();

    @Override
    public long getItemId(int position) {
        if (position < 0 || position >= mIdMap.size()) {
            return INVALID_ID;
        }

        Track item = (Track) getItem(position);
        return mIdMap.get(item);
    }

    @Override
    public boolean hasStableIds()
    {
        return android.os.Build.VERSION.SDK_INT < 20;
    }
}

PlayTrackView.java

public class PlayTrackView extends FrameLayout implements IItemDisplayer<Track> {

    public PlayTrackView(Context context) {
        super(context);
        LayoutInflater.from(context).inflate(R.layout.play_track_view, this);
    }

    public PlayTrackView(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.play_track_view, this);
    }

    public PlayTrackView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        LayoutInflater.from(context).inflate(R.layout.play_track_view, this);
    }

    @Override
    public void displayItem(Track track) {

    }
}

Track.java

public class Track {
    public String trackId;
    public String trackName;
}

IItemDisplayer interface

public interface IItemDisplayer<TItem> {
    public void displayItem(TItem item);
}

BaseListViewAdapter

BaseListViewArrayAdapter

like image 34
Konstantin Loginov Avatar answered Nov 01 '22 16:11

Konstantin Loginov