我跟着Nick Butcher's Material Improvements I/O 2016 talk,大约6点,他开始谈论动画列表项目。我完全按照他的方式实现了这个功能,并且绑定更改了正确的动画效果,但颜色变化没有动画,尽管他明确表示他们会这样做:
这就是代码的样子:
这是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()
}
}
这是我用于项目的布局。 ConstraintLayout
对于当前的布局设置来说有点过分,但我减少了布局以创建一个最小的示例。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/item_background"
android:stateListAnimator="@animator/item_elevation"
android:padding="8dp">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
tools:text="Title 1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="@+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="Subtitle 1"
app:layout_constraintTop_toBottomOf="@id/title"
app:layout_constraintStart_toStartOf="parent"
/>
</android.support.constraint.ConstraintLayout>
这是我用于项目布局的背景:
<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>
答案 0 :(得分:4)
确保您的数据集具有稳定的ID并调用Recycler.Adapter#setHasStableIds(true)
。看到
setHasStableIds()
您还需要覆盖适配器中的getItemId()
以返回稳定的ID。另请参阅notifyDataSetChanged以获得有关稳定ID的简短讨论。
当使用此方法时,RecyclerView将尝试为报告它们具有稳定ID的适配器合成可见的结构更改事件。这有助于动画和视觉对象持久性的目的,但单个项目视图仍然需要反弹并重新传输。
以下是稳定ID设置为false的演示:
并将稳定的ID设置为true。我对颜色变化的过渡时间很长,所以很明显。
<强> RecyclerViewAdapter.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";
}