타사 라이브러리를 사용할 필요가 없습니다. 약간의 비틀기 에서 설명하는 방법에 구글 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
특성에 대해 Heisenberg가 말한대로 정확하게 정의됩니다.
업데이트 : 위의 데모는 확장 된 항목 중 하나가 확장 된 경우 이전에 확장 된 항목을 축소합니다. 이 동작을 수정하고 확장 된 항목을 다른 항목이 확장 된 경우에도 그대로 유지하려면 다음 코드가 필요합니다.
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는 유연성이 있어야합니다.