새로운 RecyclerView에서 확장 가능한 목록 항목을 사용할 수 있습니까? ExpandableListView처럼?
새로운 RecyclerView에서 확장 가능한 목록 항목을 사용할 수 있습니까? ExpandableListView처럼?
답변:
이것은 주식 LayoutManagers로 간단하게 할 수 있으며, 모두 어댑터를 관리하는 방법에 따라 다릅니다.
섹션을 확장하려면 헤더 뒤에 새 항목을 어댑터에 추가하기 만하면됩니다. 이 작업을 수행 할 때 notifyItemRangeInserted를 호출해야합니다. 섹션을 축소하려면 관련 항목을 제거하고 notifyItemRangeRemoved ()를 호출하면됩니다. 적절하게 통보 된 데이터 변경에 대해 리사이클 러 뷰는 뷰를 애니메이션합니다. 항목을 추가 할 때 새 항목으로 채워질 영역이 만들어지고 새 항목이 희미 해집니다. 제거는 그 반대입니다. 어댑터 외에해야 할 일은 뷰의 스타일을 지정하여 사용자에게 논리적 구조를 전달하는 것입니다.
업데이트 : Ryan Brooks는 이제 이를 수행하는 방법에 대한 기사 를 작성했습니다 .
에서 샘플 코드 구현 받기 여기를
ViewHolder의 onClick 내에 ValueAnimator 설정
@Override
public void onClick(final View view) {
if (mOriginalHeight == 0) {
mOriginalHeight = view.getHeight();
}
ValueAnimator valueAnimator;
if (!mIsViewExpanded) {
mIsViewExpanded = true;
valueAnimator = ValueAnimator.ofInt(mOriginalHeight, mOriginalHeight + (int) (mOriginalHeight * 1.5));
} else {
mIsViewExpanded = false;
valueAnimator = ValueAnimator.ofInt(mOriginalHeight + (int) (mOriginalHeight * 1.5), mOriginalHeight);
}
valueAnimator.setDuration(300);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
view.getLayoutParams().height = value.intValue();
view.requestLayout();
}
});
valueAnimator.start();
}
다음은 최종 코드입니다.
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView mFriendName;
private int mOriginalHeight = 0;
private boolean mIsViewExpanded = false;
public ViewHolder(RelativeLayout v) {
super(v);
mFriendName = (TextView) v.findViewById(R.id.friendName);
v.setOnClickListener(this);
}
@Override
public void onClick(final View view) {
if (mOriginalHeight == 0) {
mOriginalHeight = view.getHeight();
}
ValueAnimator valueAnimator;
if (!mIsViewExpanded) {
mIsViewExpanded = true;
valueAnimator = ValueAnimator.ofInt(mOriginalHeight, mOriginalHeight + (int) (mOriginalHeight * 1.5));
} else {
mIsViewExpanded = false;
valueAnimator = ValueAnimator.ofInt(mOriginalHeight + (int) (mOriginalHeight * 1.5), mOriginalHeight);
}
valueAnimator.setDuration(300);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
view.getLayoutParams().height = value.intValue();
view.requestLayout();
}
});
valueAnimator.start();
}
}
ExpandableListView
경우 확장 된 콘텐츠는 어댑터에서 가져온 항목이 포함 된 목록 자체이므로 "처럼 " 작동하지 않습니다 . 이것은 그룹 내에서 자식으로 허용되는 항목이 하나 뿐인 퇴화 솔루션입니다.
https://github.com/gabrielemariotti/cardslib
이 라이브러리에는 recyclerview가있는 확장 가능한 목록이 구현되어 있습니다 ( "CardViewNative"-> "List, Grid 및 RecyclerView"-> "Expandable cards"아래의 데모 앱 참조). 또한 카드 / 목록의 다른 멋진 조합이 많이 있습니다.
누군가는 위에서 언급 한 솔루션을 확장 가능한 콘텐츠로 목록보기와 함께 사용할 수 없다고 불평했습니다. 그러나 간단한 해결책 이 있습니다. 목록보기를 만들고이 목록보기를 행으로 수동으로 채 웁니다 .
게으른 사람들을위한 솔루션 : 코드를 많이 변경하고 싶지 않은 경우 간단한 솔루션이 있습니다. 어댑터를 수동으로 사용하여 뷰를 생성 하고LinearLayout
.
예는 다음과 같습니다.
if (mIsExpanded)
{
// llExpandable... is the expandable nested LinearLayout
llExpandable.removeAllViews();
final ArrayAdapter<?> adapter = ... // create your adapter as if you would use it for a ListView
for (int i = 0; i < adapter.getCount(); i++)
{
View item = adapter.getView(i, null, null);
// if you want the item to be selectable as if it would be in a default ListView, then you can add following code as well:
item.setBackgroundResource(Functions.getThemeReference(context, android.R.attr.selectableItemBackground));
item.setTag(i);
item.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// item would be retrieved with:
// adapter.getItem((Integer)v.getTag())
}
});
llExpandable.addView(item);
}
ExpandUtils.expand(llExpandable, null, 500);
}
else
{
ExpandUtils.collapse(llExpandable, null, 500);
}
도우미 함수 : getThemeReference
public static int getThemeReference(Context context, int attribute)
{
TypedValue typeValue = new TypedValue();
context.getTheme().resolveAttribute(attribute, typeValue, false);
if (typeValue.type == TypedValue.TYPE_REFERENCE)
{
int ref = typeValue.data;
return ref;
}
else
{
return -1;
}
}
도우미 클래스 : ExpandUtils
Kavin Varnan postet은 이미 레이아웃을 애니메이션하는 방법을 ...하지만 내 수업을 사용하고 싶다면 자유롭게 사용 하십시오 . https://gist.github.com/MichaelFlisar/738dfa03a1579cc7338a
recyclerview
사용하고이 중첩 된 뷰 를 확장 / 숨기기하고recyclerview
부드러운 확장 / 축소 애니메이션 CheckBox와 같은 ExpandableLayout을 사용할 수 있으므로 ListView 및 RecyclerView에서 CheckBox로 사용할 수 있습니다.
이것은 @TonicArtos 에서 항목을 추가 및 제거하고 작업하는 동안 애니메이션화하기 위해 언급 한 샘플 코드입니다 . 이것은 RecyclerView 애니메이션 및 GitHub 샘플 에서 가져옵니다.
1) onCreateViewHolder () 내부에 리스너를 추가 하여 onClick 등록
2) 어댑터 내부에 사용자 지정 OnClickListener 만들기
private View.OnClickListener mItemListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
TextView tv = (TextView) v.findViewById(R.id.tvItems);
String selected = tv.getText().toString();
boolean checked = itemsList.get(recyclerView.getChildAdapterPosition(v)).isChecked();
switch (selected){
case "Item1":
if(checked){
deleteItem(v);
itemsList.get(recyclerView.getChildAdapterPosition(v)).setChecked(false);
}else {
addItem(v);
itemsList.get(recyclerView.getChildAdapterPosition(v)).setChecked(true);
}
break;
case "Item2":
if(checked){
deleteItem(v);
itemsList.get(recyclerView.getChildAdapterPosition(v)).setChecked(false);
}else {
addItem(v);
itemsList.get(recyclerView.getChildAdapterPosition(v)).setChecked(true);
}
break;
default:
//In my case I have checkList in subItems,
//checkItem(v);
break;
}
}
};
3) addItem () 및 deleteItem () 추가
private void addItem(View view){
int position = recyclerView.getChildLayoutPosition(view);
if (position != RecyclerView.NO_POSITION){
navDrawItems.add(position+1,new mObject());
navDrawItems.add(position+2,new mObject());
notifyItemRangeInserted(position+1,2);
}
}
private void deleteItem(View view) {
int position = recyclerView.getChildLayoutPosition(view);
if (position != RecyclerView.NO_POSITION) {
navDrawItems.remove(position+2);
navDrawItems.remove(position+1);
notifyItemRangeRemoved(position+1,2);
}
}
4) RecyclerViewAdapter가 Recycler View와 동일한 활동에 있지 않은 경우 recyclerView의 인스턴스를 어댑터에 전달하는 동안
5) itemList는 항목의 상태 (Open / Close), 이름, 항목의 유형 (subItems / mainItem)을 유지하고 값에 따라 테마를 설정하는 데 도움이되는 mObject 유형의 ArrayList입니다.
public class mObject{
private String label;
private int type;
private boolean checked;
}