web-dev-qa-db-ja.com

RecyclerView:挿入アニメーション効果を作成する方法は?

ReyclerViewLinearLayoutManagerと_Adapter<ViewHolder>_で動作しています。挿入(スライドイン)アニメーションを使用してrecyclerviewに表示したいアイテムのリストがあります。これについてはどうすればよいですか?

アイテムのインデックスに基づいて、直線的に増加する遅延でアニメーションを表示したいと思います。

現在、「追加」と「削除」の2つのボタンを使用してから、recyclerviewでそれぞれの操作(notifyItemInserted()notifyItemRemoved())を実行すると、アニメーションがうまく表示されます。

プログラムでデータセットをループし、もう一度notifyItemInserted()を使用してアイテムを追加すると、アニメーションが表示されません。すべてのアイテムがほぼ同時に表示されるのがわかります。

線形遅延のある非同期タスクを使用してから、OnPostExecute()でアイテムを追加/削除しても、アニメーションが表示されません。また、複数の挿入スレッドがすべての削除スレッドの完了を待機している場合(削除スレッドを実行する場所がない場合)、デッドロックが発生する可能性があります。

私は何が間違っているのですか?

私はこれに関連するほとんどの質問をSOで確認し、recyclerviewのアニメーション部分を何日もかけて調べましたが、まだ運がありません。

9

以下は、Adapterにアニメーションを追加する方法です。これにより、プッシュエフェクトがアニメートされ、行が右から入ります。

まず、アニメーションをxmlで定義します(res/anim/Push_left_in.xml

<set xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <translate Android:fromXDelta="100%p" Android:toXDelta="0"
        Android:duration="300"/>
    <alpha Android:fromAlpha="0.0" Android:toAlpha="1.0"
        Android:duration="300" />
</set>

次に、アダプターにそのように設定します

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row;
    if (convertView == null) {
        LayoutInflater inflater = LayoutInflater.from(getContext());
        row = inflater.inflate(R.layout.music_list_item, null);
    } else {
        row = convertView;
    }

    ...

    //Load the animation from the xml file and set it to the row
    Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.Push_left_in);
    animation.setDuration(500);
    row.startAnimation(animation);

    return row;
}

このアニメーションは、新しい行を追加するたびに表示されますが、この場合は機能するはずです。

編集

これは、RecyclerViewを使用してアニメーションを追加する方法です。

@Override
public void onBindViewHolder(ViewHolder holder, int position)
{
    holder.text.setText(items.get(position));

    // Here you apply the animation when the view is bound
    setAnimation(holder.container, position);
}

/**
 * Here is the key method to apply the animation
 */
private void setAnimation(View viewToAnimate, int position)
{
    // If the bound view wasn't previously displayed on screen, it's animated
    if (position > lastPosition)
    {
        Animation animation = AnimationUtils.loadAnimation(context, Android.R.anim.Push_left_in);
        viewToAnimate.startAnimation(animation);
        lastPosition = position;
    }
}
9
Marcus

次の行をRecyclerViewxmlに追加します。

Android:animateLayoutChanges="true"

5
penduDev

これは私のために働きます:

animation.setStartOffset(position*100);
2
user2852741