IT story

Android ListView 행의 추가 또는 제거에 애니메이션을 적용하는 방법

hot-time 2020. 4. 30. 07:33
반응형

Android ListView 행의 추가 또는 제거에 애니메이션을 적용하는 방법


iOS에는 UITableView 행의 추가 및 제거에 애니메이션을 적용 할 수있는 매우 쉽고 강력한 기능이 있습니다. 여기 에는 기본 애니메이션을 보여주는 YouTube 비디오의 클립이 있습니다 . 주변 행이 삭제 된 행으로 축소되는 방법에 유의하십시오. 이 애니메이션은 사용자가 목록에서 변경된 사항과 데이터가 변경된 시점을보고 있던 목록을 추적하는 데 도움이됩니다.

Android에서 개발 한 이후 TableView 에서 개별 행에 애니메이션을 적용하는 동등한 기능을 찾지 못했습니다 . notifyDataSetChanged()내 어댑터를 호출 하면 ListView가 해당 내용을 새로운 정보로 즉시 업데이트합니다. 데이터가 변경 될 때 새 행을 밀어 넣거나 빼는 간단한 애니메이션을 보여주고 싶지만 문서화 된 방법을 찾을 수 없습니다. LayoutAnimationController 가 이것을 작동시키는 열쇠를 가지고있는 것처럼 보이지만 ListView에서 LayoutAnimationController를 설정하고 ( ApiDemo의 LayoutAnimation2 와 유사 ) 목록이 표시된 후 어댑터에서 요소를 제거하면 요소가 애니메이션되지 않고 즉시 사라집니다. .

또한 개별 항목이 제거 될 때 애니메이션을 적용하기 위해 다음과 같은 것을 시도했습니다.

@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);
}

그러나 애니메이션 행을 둘러싼 행 notifyDataSetChanged()은 호출 될 때 새 위치로 이동할 때까지 위치를 이동하지 않습니다 . 요소가 배치되면 ListView가 레이아웃을 업데이트하지 않는 것 같습니다.

ListView의 자체 구현 / 포크를 작성하는 것이 내 마음을 넘어 섰지 만, 그렇게 어렵지 않아야하는 것 같습니다.

감사!


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());

하향식 애니메이션 사용 :

<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>

RecyclerView추가, 제거 및 재 주문 애니메이션을 담당!

작동하는 RecyclerView

간단한 AndroidStudio 프로젝트 에는 기능이 RecyclerView있습니다. 커밋을 살펴보십시오 .

  1. 고전적인 Hello World Android 앱 커밋
  2. 커밋, 프로젝트에 RecyclerView 추가 (콘텐츠가 동적이 아님)
  3. commit, adding functionality to modify content of RecyclerView at runtime (but no animations)
  4. 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:

먼저 목록보기의 android : animateLayoutChangestrue로 설정하십시오 .

<ListView
        android:id="@+id/items_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:animateLayoutChanges="true"/>

그런 다음 핸들러사용하여 항목을 추가하고 지연 목록 목록을 업데이트합니다.

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;
}

참고 URL : https://stackoverflow.com/questions/3928193/how-to-animate-addition-or-removal-of-android-listview-rows

반응형