首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >活动出口上的RecyclerView动画

活动出口上的RecyclerView动画
EN

Stack Overflow用户
提问于 2018-12-11 08:02:42
回答 2查看 695关注 0票数 5

我正在制作一个应用程序,其中包括回收视图。回收视图的项目显示(幻灯片)与动画从底部开始的活动。单击一个项时,它导航到另一个活动。我希望项目消失(滑出)与动画之前,退出当前的活动。在我的例子中,我希望项目放下(滑出),然后开始新的活动。在退出活动之前,有没有办法把物品滑出去?

编辑:,如下所示:

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-11-14 11:08:15

LayoutAnimationController:

使用LayoutAnimationController中的构建,您可以使用自定义的从上到下的动画幻灯片实现滑出效果,并命令LayoutAnimationController.ORDER_REVERSE从右下角子项视图开始动画。

1.)在res/anim/slide_from_top_to_bottom.xml中声明幻灯片动画:

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="250">

    <translate
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:fromYDelta="0"
        android:toYDelta="100%p"/>

    <alpha
        android:fromAlpha="1"
        android:toAlpha="0"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"/>

</set>

2.使用下面的助手启动上述动画,方法是使用LayoutAnimationController方法将RecyclerView设置为setLayoutAnimation()

代码语言:javascript
运行
复制
private void slideOutRecyclerViewLayoutAnimation(final RecyclerView recyclerView)
{
    Animation animation = AnimationUtils.loadAnimation(this, R.anim.slide_from_top_to_bottom);
    animation.setFillAfter(true); //true if the animation should apply its transformation after it ends
    LayoutAnimationController lac = new LayoutAnimationController(animation);
    lac.setOrder(LayoutAnimationController.ORDER_REVERSE);
    lac.setDelay(0.15f);

    recyclerView.setLayoutAnimation(lac);
    recyclerView.getAdapter().notifyDataSetChanged();
    recyclerView.scheduleLayoutAnimation();

    //go to the next Activity after 1sec
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            //go to the next Activity
        }
    }, 1000);
}

定制ItemAnimator:

如果您想要在动画延迟中有更多的自定义,使用不同的滑出顺序(类似于您的gif ),您可以使用自定义SimpleItemAnimator并使用在删除RecyclerView中的项时调用的public boolean animateRemove(RecyclerView.ViewHolder holder)。当您只删除像notifyItemRemoved()这样的一个项目时,或者当您删除一系列像notifyItemRangeRemoved()这样的项目时,它就调用了。

1.创建CustomAnimator,如下所示:

代码语言:javascript
运行
复制
public class CustomAnimator extends SimpleItemAnimator {

    private final int columns;
    private final int rows;

    public CustomAnimator(int columns, int itemsCount){
        this.columns = columns;
        this.rows = (int) Math.ceil((double) itemsCount / (double)columns);
    }

    @Override
    public boolean animateRemove(RecyclerView.ViewHolder holder) {

        //to get the item view position set in RecyclerView.Adapter#onBindViewHolder the position to the item view like: itemView.setTag(position);
        int position = (int)holder.itemView.getTag();

        int x = position % columns;
        int y = position / columns;

        int yDiff = rows - y;
        long delay = 0;
        switch (x)
        {
            //column 0
            case 0:
                delay = yDiff * 60L;
                break;
            //column 1
            case 1:
                delay = yDiff * 50L;
                break;
            //column 2
            case 2:
                delay = yDiff * 40L;
                break;
            //column 3
            case 3:
                delay = yDiff * 30L;
                break;
        }

        int height = holder.itemView.getContext().getResources().getDisplayMetrics().heightPixels;
        holder.itemView.setTranslationY(0);
        holder.itemView.setAlpha(1);
        holder.itemView.animate()
                .translationY(height)
                .alpha(0)
                .setInterpolator(new LinearInterpolator())
                .setDuration(500)
                .setStartDelay(delay)
                .setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        super.onAnimationEnd(animation);
                        dispatchRemoveFinished(holder);
                    }
                })
                .start();
        return false;
    }

    @Override
    public boolean animateAdd(RecyclerView.ViewHolder holder) {
        return false;
    }

    @Override
    public boolean animateMove(RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {
        return false;
    }

    @Override
    public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromLeft, int fromTop, int toLeft, int toTop) {
        return false;
    }

    @Override
    public void runPendingAnimations() {

    }

    @Override
    public void endAnimation(@NonNull RecyclerView.ViewHolder item) {

    }

    @Override
    public void endAnimations() {

    }

    @Override
    public boolean isRunning() {
        return false;
    }
}

2.在RecyclerView.Adapter in onBindViewHolder中,将每个项目的位置设置为以后从CustomAnimator中检索的标记,如下所示:

代码语言:javascript
运行
复制
itemView.setTag(position);

3.)在RecyclerView初始化期间,将ItemAnimator设置如下:

代码语言:javascript
运行
复制
//set GridLayoutManager with 4 columns
recyclerView.setLayoutManager(new GridLayoutManager(this, 4));
//prepare some dummy items
List<Item> itemsList = new ArrayList<>();
for(int i =0; i<26; i++) {
    itemsList.add(new Item());
}
//initialize Adapter
itemsAdapter = new MyAdapter(itemsList);
//set recyclerView Adapter
recyclerView.setAdapter(itemsAdapter);
//set recyclerView CustomAnimator
recyclerView.setItemAnimator(new CustomAnimator(4, itemsAdapter.getItems().size()));

4.)最后,当您单击某个项目时,请调用下面的助手启动动画:

代码语言:javascript
运行
复制
private void removeAllItems(){

    int itemsCount = itemsAdapter.getItems().size();
    itemsAdapter.getItems().clear();
    recyclerView.getAdapter().notifyItemRangeRemoved(0, itemsCount);

    //go to the next Activity after 1sec
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            //go to the next Activity after 1sec
        }
    }, 1000);
}

结果:

票数 1
EN

Stack Overflow用户

发布于 2018-12-12 06:41:15

你需要幻灯片动画。

我已经在我的Android应用程序中使用过它。我会用爆炸动画来解释这个问题。

假设您有两个活动A(GridList活动)和B(DetailActivity活动)。

A->B

您可以通过以下简单步骤实现这一点

1.启用内容转换

将此代码添加到style.xml

代码语言:javascript
运行
复制
<item name="android:windowContentTransitions">true</item>

2.设置默认的进入和退出动画

在活动A中编写此方法,它将为您处理动画。

代码语言:javascript
运行
复制
public void setAnimation()
{
    if(Build.VERSION.SDK_INT>20) {
        Explode explode = new Explode();
        explode.setDuration(1000);
        explode.setInterpolator(new DecelerateInterpolator());
        getWindow().setExitTransition(explode);
        getWindow().setEnterTransition(explode);
    }
}

3.以意图启动活动

将此添加到活动A中以启动活动B。注意动画只在SDK>20之上工作。因此,如果min较低,则还必须检查sdk。只需使用这个代码片段,您就可以继续了。

代码语言:javascript
运行
复制
 public void startActivity(){

    Intent i = new Intent(BlankActivity.this, AllImageActivity.class);
    i.putStringArrayListExtra(MOVIE_LIST, movie.getImages());

      if(Build.VERSION.SDK_INT>20)
       {
           ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(BlankActivity.this);
           startActivity(i,options.toBundle());
       }
       else {
           startActivity(i);
       }
 }

非常重要

您应该将setAnimation()放在setContentView(R.layout.yourLayout)之前,否则动画将无法工作。所以活动A应该是这样的

代码语言:javascript
运行
复制
Activity A extends .... {

   @Override
   protected void onCreate(Bundle savedInstaceState)
   {
       super.onCreate(savedInstaceState);

       setAnimation();

       setContentView(R.layout.image_landing_layout);

       startActivity();  // Use as you wish 
       .......
   }

   public void setAnimation(){

       ..........
   }

我不会在任何IDE上写这个,所以不要介意任何语法错误。但这会把你推向正确的轨道。

你可以看看我的存储库。但你可能很难在那里找到它。希望这能有所帮助。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53719748

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档