Android TransitionManager没有';不要设置颜色变化的动画

Android TransitionManager没有';不要设置颜色变化的动画,android,android-layout,android-recyclerview,material-design,android-animation,Android,Android Layout,Android Recyclerview,Material Design,Android Animation,我跟着他,大约6:00,他开始谈论为列表项设置动画。我完全按照他所做的方式实现了该功能,并且绑定的更改正确地设置了动画,但是颜色更改不会设置动画,尽管他明确表示会: 这是代码的样子: 这是RecyclerView.Adapter类的相关部分: override fun onBindViewHolder(holder: ViewHolder, position: Int) { val item: Pair<String, String> = items[position]

我跟着他,大约6:00,他开始谈论为列表项设置动画。我完全按照他所做的方式实现了该功能,并且绑定的更改正确地设置了动画,但是颜色更改不会设置动画,尽管他明确表示会:

这是代码的样子:

这是
RecyclerView.Adapter
类的相关部分:

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val item: Pair<String, String> = items[position]

    holder.title.text = item.first
    holder.subtitle.text = item.second

    val isExpanded = position == expandedPosition
    holder.subtitle.visibility = if (isExpanded) View.VISIBLE else View.GONE
    holder.itemView.isActivated = isExpanded
    holder.itemView.setOnClickListener {
        expandedPosition = if (isExpanded) -1 else position
        TransitionManager.beginDelayedTransition(recyclerView)
        notifyDataSetChanged()
    }
}
这是我用于项目布局的背景:

<selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:enterFadeDuration="@android:integer/config_mediumAnimTime"
    android:exitFadeDuration="@android:integer/config_mediumAnimTime">

    <item android:state_activated="true"
        android:drawable="@color/colorAccent" />

    <item android:drawable="@color/colorPrimaryDark" />

</selector>

确保您的数据集有稳定的ID,并调用
Recycler.Adapter\setHassTableID(true)
。看见

您还需要在适配器中重写以返回稳定id。有关稳定id的简短讨论,请参阅

RecyclerView将尝试为适配器合成可见的结构更改事件,这些适配器在使用此方法时报告它们具有稳定的ID。这有助于动画和视觉对象持久化,但仍需要恢复和重新生成单个项目视图

下面是一个将稳定ID设置为false的演示:

并将稳定ID设置为true。我已经使过渡时间很长的颜色变化,所以它会很明显

RecycleServiceAdapter.java

这是演示中使用的适配器
TransitionManager.beginDelayedTransition(mRecyclerView)
已被删除,以便让
RecyclerView
更好地处理动画

class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    RecyclerViewAdapter() {
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
        return new ItemViewHolder(view);
    }

    private int mExpandedPosition = RecyclerView.NO_POSITION;

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        final ItemViewHolder vh = (ItemViewHolder) holder;
        final TextView subTitle = vh.mSubTitle;

        vh.mTitle.setText(titleForPosition(position));
        subTitle.setText(subTitleForPosition(position));

        final boolean isExpanded = position == mExpandedPosition;

        subTitle.setVisibility((isExpanded) ? View.VISIBLE : View.GONE);
        holder.itemView.setActivated(isExpanded);
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mExpandedPosition = isExpanded ? RecyclerView.NO_POSITION : vh.getAdapterPosition();
                notifyDataSetChanged();
            }
        });
    }

    private String titleForPosition(int position) {
        return "Title " + position;
    }

    private String subTitleForPosition(int position) {
        return "Subtitle " + position;
    }

    @Override
    public int getItemCount() {
        return 5;
    }

    @Override
    public long getItemId(int position) {
        return titleForPosition(position).hashCode();
    }

    static class ItemViewHolder extends RecyclerView.ViewHolder {
        private final TextView mTitle;
        private final TextView mSubTitle;

        ItemViewHolder(View itemView) {
            super(itemView);
            mTitle = itemView.findViewById(R.id.title);
            mSubTitle = itemView.findViewById(R.id.subtitle);
        }
    }

    @SuppressWarnings("unused")
    private final static String TAG = "RecyclerViewAdapter";
}
类RecycleServiceAdapter扩展了RecycleView.Adapter{ RecycleServiceAdapter(){ } @非空 @凌驾 public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup父级,int-viewType){ 视图; view=LayoutInflater.from(parent.getContext()).flate(R.layout.item_布局,parent,false); 返回新的ItemViewHolder(视图); } private int-mExpandedPosition=RecyclerView.NO_POSITION; @凌驾 public void onBindViewHolder(@NonNull RecyclerView.ViewHolder,int位置){ 最终项目视图持有人vh=(项目视图持有人)持有人; 最终文本视图字幕=vh.mSubTitle; vh.mTitle.setText(标题位置(position)); subTitle.setText(subTitleForPosition(position)); 最终布尔值isExpanded=position==MeExpandedPosition; subTitle.setVisibility((isExpanded)?View.VISIBLE:View.GONE); holder.itemView.setActivated(isExpanded); holder.itemView.setOnClickListener(新视图.OnClickListener(){ @凌驾 公共void onClick(视图v){ mExpandedPosition=isExpanded?RecyclerView.NO_位置:vh.getAdapterPosition(); notifyDataSetChanged(); } }); } 私有字符串标题位置(int位置){ 返回“标题”+位置; } 私有字符串位置(int位置){ 返回“Subtitle”+位置; } @凌驾 public int getItemCount(){ 返回5; } @凌驾 公共长getItemId(int位置){ 返回titleForPosition(position).hashCode(); } 静态类ItemViewHolder扩展了RecyclerView.ViewHolder{ 私有最终文本视图mTitle; 私有最终文本视图mSubTitle; ItemViewHolder(查看itemView){ 超级(项目视图); mTitle=itemView.findviewbyd(R.id.title); mSubTitle=itemView.findviewbyd(R.id.subtitle); } } @抑制警告(“未使用”) 私有最终静态字符串TAG=“RecycleServiceAdapter”; }
Gif不起作用:-/@azizbekian听到这个消息我很抱歉,可能它不起作用,因为您正在移动设备上查看…背景绘图功能使用
ConstraintLayout
工作,而无需调用
TransitionManager
。我想知道您使用的是哪个视图组。您可以发布布局吗?不幸的是,在调整视图大小时,设置
setHasStableIds
会导致明显的重叠。看起来当前选定的项目将从列表中消失,然后从列表的开始或结束处设置动画。我将在问题中发布我的布局…@AleksandarStefanovićRemove
TransitionManager.beginDelayedTransition(mRecyclerView)
并让
RecyclerView
完成它的任务。颜色转换问题已解决?删除
beginDelayedTransition
修复了奇怪的调整大小动画,但颜色更改仍然不会产生动画。@AleksandarStefanović您的稳定ID设置好了吗?您返回的目的是什么?是的,
setHasStableIds
已启用。至于
getItemId()
,我使用的是数据数组中项目数据的哈希值,即
items[position].name.hashCode().toLong()
class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    RecyclerViewAdapter() {
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
        return new ItemViewHolder(view);
    }

    private int mExpandedPosition = RecyclerView.NO_POSITION;

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        final ItemViewHolder vh = (ItemViewHolder) holder;
        final TextView subTitle = vh.mSubTitle;

        vh.mTitle.setText(titleForPosition(position));
        subTitle.setText(subTitleForPosition(position));

        final boolean isExpanded = position == mExpandedPosition;

        subTitle.setVisibility((isExpanded) ? View.VISIBLE : View.GONE);
        holder.itemView.setActivated(isExpanded);
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mExpandedPosition = isExpanded ? RecyclerView.NO_POSITION : vh.getAdapterPosition();
                notifyDataSetChanged();
            }
        });
    }

    private String titleForPosition(int position) {
        return "Title " + position;
    }

    private String subTitleForPosition(int position) {
        return "Subtitle " + position;
    }

    @Override
    public int getItemCount() {
        return 5;
    }

    @Override
    public long getItemId(int position) {
        return titleForPosition(position).hashCode();
    }

    static class ItemViewHolder extends RecyclerView.ViewHolder {
        private final TextView mTitle;
        private final TextView mSubTitle;

        ItemViewHolder(View itemView) {
            super(itemView);
            mTitle = itemView.findViewById(R.id.title);
            mSubTitle = itemView.findViewById(R.id.subtitle);
        }
    }

    @SuppressWarnings("unused")
    private final static String TAG = "RecyclerViewAdapter";
}