サードパーティのライブラリを使用する必要はまったくありません。少し微調整で立証方法でGoogleのI / O 2016このトピックにとハイゼンベルク、トリックを行います。
notifyDataSetChanged()
完全なを再描画するRecyclerView
のでnotifyDataItemChanged()
、位置とをViewHolder
自由に使用notifyDataItemChanged()
でき、特定のViewHolder
位置でのみ特定のを再描画するため、これはより良いオプションです(最良ではありません)。
しかし、問題は、ViewHolder
クリックしたときの早期の消滅とその出現が排除されないことです。notifyDataItemChanged()
使用さです。
次のコードではありませんに頼るnotifyDataSetChanged()
かnotifyDataItemChanged()
、各ViewHolderがありRecyclerViewに使用されたときAPI 23と魅力のような作品でテストされCardView
、それのルート要素として:
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final boolean visibility = holder.details.getVisibility()==View.VISIBLE;
if (!visibility)
{
holder.itemView.setActivated(true);
holder.details.setVisibility(View.VISIBLE);
if (prev_expanded!=-1 && prev_expanded!=position)
{
recycler.findViewHolderForLayoutPosition(prev_expanded).itemView.setActivated(false);
recycler.findViewHolderForLayoutPosition(prev_expanded).itemView.findViewById(R.id.cpl_details).setVisibility(View.GONE);
}
prev_expanded = position;
}
else
{
holder.itemView.setActivated(false);
holder.details.setVisibility(View.GONE);
}
TransitionManager.beginDelayedTransition(recycler);
}
});
prev_position
-1に初期化されたグローバル整数です。
details
展開すると表示され、折りたたむとクローク表示される完全なビューです。
言ったように、のルート要素ViewHolder
はCardView
with foreground
とstateListAnimator
このトピックにハイゼンベルグで言ったように属性が正確に定義されました。
更新:上記のデモンストレーションは、以前に展開されたアイテムの1つが展開されている場合、折りたたまれます。この動作を変更し、別のアイテムが展開されている場合でも展開されたアイテムをそのままにするには、次のコードが必要です。
if (row.details.getVisibility()!=View.VISIBLE)
{
row.details.setVisibility(View.VISIBLE);
row.root.setActivated(true);
row.details.animate().alpha(1).setStartDelay(500);
}
else
{
row.root.setActivated(false);
row.details.setVisibility(View.GONE);
row.details.setAlpha(0);
}
TransitionManager.beginDelayedTransition(recycler);
更新:リストの最後のアイテムを展開すると、展開された部分が画面の下に移動するため、完全に表示されない場合があります。画面内の完全なアイテムを取得するには、次のコードを使用します。
LinearLayoutManager manager = (LinearLayoutManager) recycler.getLayoutManager();
int distance;
View first = recycler.getChildAt(0);
int height = first.getHeight();
int current = recycler.getChildAdapterPosition(first);
int p = Math.abs(position - current);
if (p > 5) distance = (p - (p - 5)) * height;
else distance = p * height;
manager.scrollToPositionWithOffset(position, distance);
重要:上記のデモを機能させるには、RecyclerViewとそのLayoutManagerのインスタンスをコード内に保持する必要があります(柔軟性のために後者)。