RecyclerView에서 항목 사이에 구분선과 공백을 추가하는 방법은 무엇입니까?
다음은 divider 및 dividerHeight 매개 변수를 ListView
사용하여 이전에 클래스 에서 수행 할 수 있습니다.
<ListView
android:id="@+id/activity_home_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@android:color/transparent"
android:dividerHeight="8dp"/>
그러나 나는 RecyclerView
수업 에서 가능성을 보지 못합니다 .
<android.support.v7.widget.RecyclerView
android:id="@+id/activity_home_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"/>
이 경우 여백을 정의하거나 사용자 지정 구분선보기를 목록 항목의 레이아웃에 직접 추가해도? 아니면 목표를 달성하는 더 좋은 방법이 있습니까?
2016 년 10 월 업데이트
Android 지원 라이브러리 버전 25.0.0은 다음 클래스를 도입했습니다 .DividerItemDecoration
DividerItemDecoration은 .NET Framework의 항목 간 구분선으로 사용할 수있는 RecyclerView.ItemDecoration입니다
LinearLayoutManager
.HORIZONTAL
및VERTICAL
방향을 모두 지원합니다 .
용법 :
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
layoutManager.getOrientation());
recyclerView.addItemDecoration(dividerItemDecoration);
이전 답변
일부 답변은 이후 더 이상 사용되지 않는 방법을 사용하거나 완전한 솔루션을 제공하지 않습니다. 최신 요약을 시도했습니다.
달리 ListView
의 RecyclerView
클래스가 더 분할과 변수가 없습니다. 대신 확장 할 필요가 A, 의 내부 클래스 :ItemDecoration
RecyclerView
을
ItemDecoration
사용하면 응용 프로그램이 특수 도면 및 레이아웃을 추가 할 수 있습니다. 이 항목, 하이라이트, 그룹에서는 경계 등 사이의 구분선을 그리는 데 유용 할 수 있습니다.모든
ItemDecorations
(의 항목을보기 전에, 그들이 추가 된 순서대로 그려집니다onDraw()
() 및 항목 후 onDrawOver (에Canvas
,RecyclerView
,RecyclerView.State)
.
Vertical
간격 ItemDecoration
확장 ItemDecoration
하고 공간 height
을 매개 변수로 사용하는 user-지정 생성자를 추가 하고 getItemOffsets()
메서드를 재정의 합니다.
public class VerticalSpaceItemDecoration extends RecyclerView.ItemDecoration {
private final int verticalSpaceHeight;
public VerticalSpaceItemDecoration(int verticalSpaceHeight) {
this.verticalSpaceHeight = verticalSpaceHeight;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
outRect.bottom = verticalSpaceHeight;
}
}
마지막 항목 아래에 공백을 추가하지.면 다음 조건을 추가하십시오
if (parent.getChildAdapterPosition(view) != parent.getAdapter().getItemCount() - 1) {
outRect.bottom = verticalSpaceHeight;
}
참고 : 당신은 또한 수정할 수 outRect.top
, outRect.left
및 outRect.right
원하는 효과에, 대한 속성.
분할기 ItemDecoration
확장 ItemDecoration
및 재정의 onDraw()
방법 :
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
private Drawable divider;
/**
* Default divider will be used
*/
public DividerItemDecoration(Context context) {
final TypedArray styledAttributes = context.obtainStyledAttributes(ATTRS);
divider = styledAttributes.getDrawable(0);
styledAttributes.recycle();
}
/**
* Custom divider will be used
*/
public DividerItemDecoration(Context context, int resId) {
divider = ContextCompat.getDrawable(context, resId);
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + divider.getIntrinsicHeight();
divider.setBounds(left, top, right, bottom);
divider.draw(c);
}
}
}
기본 Android 구분선 속성을 사용하는 첫 번째 생성자 또는 고유 한 드로어 블을 사용하는 두 번째 생성자 (예 : drawable / divider.xml)를 호출 할 수 있습니다.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size android:height="1dp" />
<solid android:color="#ff992900" />
</shape>
참고 : 항목 위에 구분선을 그리려면 대신 메소드 onDrawOver()
를 재정의하십시오 .
용법
클래스를 사용 새하려면 예를 들어 프래그먼트의 메서드 에서 VerticalSpaceItemDecoration
또는 DividerSpaceItemDecoration
에 추가 RecyclerView
하십시오 onCreateView()
.
private static final int VERTICAL_ITEM_SPACE = 48;
private RecyclerView recyclerView;
private LinearLayoutManager linearLayoutManager;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_feed, container, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_home_recycler_view);
linearLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(linearLayoutManager);
//add ItemDecoration
recyclerView.addItemDecoration(new VerticalSpaceItemDecoration(VERTICAL_ITEM_SPACE));
//or
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity()));
//or
recyclerView.addItemDecoration(
new DividerItemDecoration(getActivity(), R.drawable.divider));
recyclerView.setAdapter(...);
return rootView;
}
아이템 장식 과정을 단순화하는 Lucas Rocha의 라이브러리 도 있습니다 . 그래도 시도하지 않을 수 있습니다.
그 기능 은 다음과 가능합니다.
- 다음을 포함 재고 항목 장식 컬렉션 :
- 항목 간격 가로 / 세로 구분선.
- 목록 항목
그냥 추가
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
DividerItemDecoration.VERTICAL));
또한 추가를 추가해야 할 수도 있습니다.
compile 'com.android.support:recyclerview-v7:27.1.0'
편집하다 :
약간의 사용자 정의를 위해 사용자 정의 드로어 블을 추가 할 수 있습니다.
DividerItemDecoration itemDecorator = new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL);
itemDecorator.setDrawable(ContextCompat.getDrawable(getContext(), R.drawable.divider));
예를 들어 사용자 정의 드로어 블을 자유롭게 사용할 수 있습니다.
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/colorPrimary"/>
<size android:height="0.5dp"/>
</shape>
Alex Fu의 Github에있는 특정 파일에주의를 주시겠습니까? https://gist.github.com/alexfu/0f464fc3742f134ccd1e
"지원 스크립트에서 직접 파일"DividerItemDecoration.java 예제 파일입니다. ( https://plus.google.com/103498612790395592106/posts/VVEB3m7NkSS )
내 프로젝트 에서이 파일을 여러 후 구분선을 멋지게 재활용 기보기에 항목 장식으로 추가 할 수 있습니다.
Recyclerview를 포함하는 내 조각에서 내 onCreateView가 어떻게 보이는지 다음과 가변됩니다.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_recycler_view, container, false);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.my_recycler_view);
mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
return rootView;
}
추가 스타일링을 할 수 있는지 확신하지만 시작점입니다. :)
ItemDecoration
모든 항목 사이의 동일한 공간에 대한 간단한 구현.
public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
private int space;
public SpacesItemDecoration(int space) {
this.space = space;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.left = space;
outRect.right = space;
outRect.bottom = space;
// Add top margin only for the first item to avoid double space between items
if(parent.getChildAdapterPosition(view) == 0) {
outRect.top = space;
}
}
}
간단한 방법은 RecyclerView에 대한 배경색을 설정 하고 항목에 대해 다른 배경색을 설정하는 것입니다. 여기에 예가 있습니다 ...
<android.support.v7.widget.RecyclerView
android:background="#ECEFF1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"/>
그리고 하단 여백 "x"dp 또는 px가 있는 TextView 항목 (어떤 것이 든 가능).
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="1dp"
android:background="#FFFFFF"/>
출력 ...
간단한 구분선을 사용
하면 각 항목에 구분선을 추가하는 데 도움이 될 것이라고 생각합니다 .
1- 드로어 블 디렉토리 line_divider.xml에 추가합니다.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="1dp"
android:height="1dp" />
<solid android:color="#999999" />
</shape>
2- SimpleDividerItemDecoration 클래스 만들기가
예제를 사용 하여이 클래스를 정의했습니다.
https://gist.github.com/polbins/e37206fbc444207c0e92
package com.example.myapp;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import com.example.myapp.R;
public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration{
private Drawable mDivider;
public SimpleDividerItemDecoration(Resources resources) {
mDivider = resources.getDrawable(R.drawable.line_divider);
}
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
}
3- RecyclerView를 사용하는 활동 또는 프래그먼트에서 onCreateView 내부에 다음을 추가하십시오.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
RecyclerView myRecyclerView = (RecyclerView) layout.findViewById(R.id.my_recycler_view);
myRecyclerView.addItemDecoration(new SimpleDividerItemDecoration(getResources()));
....
}
4- 항목 사이
에 간격을 추가 할 추가 항목보기에 패딩 속성을 추가하면됩니다.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:padding="4dp"
>
..... item structure
</RelativeLayout>
내가 설정 한대로 ItemAnimators
. 는 ItemDecorator
입력하거나 애니메이션과 함께 종료되지 않습니다.
나는 모든 항목의 항목보기 레이아웃을 끝냈다. 제 사건을 해결했습니다. DividerItemDecoration
단순한 분배기에는 너무 많은 마법이라고합니다.
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:background="@color/lt_gray"/>
간단합니다. 이렇게 복잡한 코드가 필요하지 않습니다.
DividerItemDecoration divider = new
DividerItemDecoration(mRVMovieReview.getContext(),
DividerItemDecoration.VERTICAL);
divider.setDrawable(
ContextCompat.getDrawable(getBaseContext(), R.drawable.line_divider)
);
mRVMovieReview.addItemDecoration(divider);
드로어 블에 추가하십시오 : line_divider.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size android:height="1dp" />
<solid android:color="@android:color/black" />
</shape>
머티리얼 디자인을 사용하여 제대로 구현할 수있는 올바른 방법이 없기 때문에 목록 항목에 구분선을 추가하기 위해 다음 트릭을 수행했습니다.
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/dividerColor"/>
2016 년 10 월 업데이트
지원 라이브러리 v25.0.0을 사용하면 기본 수평 및 수직 분할기의 기본 구현을 사용할 수 있습니다!
https://developer.android.com/reference/android/support/v7/widget/DividerItemDecoration.html
항목 사이에 10dp 간격 만 추가하려는 경우 드로어 블을 DividerItemDecoration
다음과 같이 설정하면 됩니다.
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(
recyclerView.getContext(),
layoutManager.getOrientation()
);
dividerItemDecoration.setDrawable(
ContextCompat.getDrawable(getContext(), R.drawable.divider_10dp)
);
다음을 포함 divider_10dp
하는 드로어 블 리소스는 어디에 있습니까?
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<size android:height="10dp"/>
<solid android:color="@android:color/transparent"/>
</shape>
단지를 찾고있는 사람들을 위해 항목 사이에 공백 에 RecyclerView
당신은 내가 더 큰 패딩을 준 첫 번째 항목과 마지막 항목을 사용하는 모든 항목과 동일한 공간을 내 접근 방식을 참조하십시오. 나는 패딩을 수평에서 왼쪽 / 오른쪽, 수직 LayoutManager
에서 위 / 아래에만 적용 LayoutManager
합니다.
public class PaddingItemDecoration extends RecyclerView.ItemDecoration {
private int mPaddingPx;
private int mPaddingEdgesPx;
public PaddingItemDecoration(Activity activity) {
final Resources resources = activity.getResources();
mPaddingPx = (int) resources.getDimension(R.dimen.paddingItemDecorationDefault);
mPaddingEdgesPx = (int) resources.getDimension(R.dimen.paddingItemDecorationEdge);
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
final int itemPosition = parent.getChildAdapterPosition(view);
if (itemPosition == RecyclerView.NO_POSITION) {
return;
}
int orientation = getOrientation(parent);
final int itemCount = state.getItemCount();
int left = 0;
int top = 0;
int right = 0;
int bottom = 0;
/** HORIZONTAL */
if (orientation == LinearLayoutManager.HORIZONTAL) {
/** all positions */
left = mPaddingPx;
right = mPaddingPx;
/** first position */
if (itemPosition == 0) {
left += mPaddingEdgesPx;
}
/** last position */
else if (itemCount > 0 && itemPosition == itemCount - 1) {
right += mPaddingEdgesPx;
}
}
/** VERTICAL */
else {
/** all positions */
top = mPaddingPx;
bottom = mPaddingPx;
/** first position */
if (itemPosition == 0) {
top += mPaddingEdgesPx;
}
/** last position */
else if (itemCount > 0 && itemPosition == itemCount - 1) {
bottom += mPaddingEdgesPx;
}
}
if (!isReverseLayout(parent)) {
outRect.set(left, top, right, bottom);
} else {
outRect.set(right, bottom, left, top);
}
}
private boolean isReverseLayout(RecyclerView parent) {
if (parent.getLayoutManager() instanceof LinearLayoutManager) {
LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
return layoutManager.getReverseLayout();
} else {
throw new IllegalStateException("PaddingItemDecoration can only be used with a LinearLayoutManager.");
}
}
private int getOrientation(RecyclerView parent) {
if (parent.getLayoutManager() instanceof LinearLayoutManager) {
LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
return layoutManager.getOrientation();
} else {
throw new IllegalStateException("PaddingItemDecoration can only be used with a LinearLayoutManager.");
}
}
}
dimens.xml
<resources>
<dimen name="paddingItemDecorationDefault">10dp</dimen>
<dimen name="paddingItemDecorationEdge">20dp</dimen>
</resources>
- 여기에 구분선을 추가하는 간단한 해킹이 있습니다.
다음과 같이 리사이클 러 항목의 레이아웃에 배경을 추가하십시오.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/shape_border" android:gravity="center" android:orientation="horizontal" android:padding="5dp"> <ImageView android:id="@+id/imageViewContactLogo" android:layout_width="60dp" android:layout_height="60dp" android:layout_marginRight="10dp" android:src="@drawable/ic_user" /> <LinearLayout android:id="@+id/linearLayout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0.92" android:gravity="center|start" android:orientation="vertical"> <TextView android:id="@+id/textViewContactName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:id="@+id/textViewStatusOrNumber" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:singleLine="true" android:text="" android:textAppearance="?android:attr/textAppearanceMedium" /> </LinearLayout> <TextView android:id="@+id/textViewUnreadCount" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="10dp" android:padding="5dp" android:text="" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="@color/red" android:textSize="22sp" /> <Button android:id="@+id/buttonInvite" android:layout_width="54dp" android:layout_height="wrap_content" android:background="@drawable/ic_add_friend" /> </LinearLayout>
드로어 블 폴더에 다음 shape_border.xml 생성
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<gradient
android:angle="270"
android:centerColor="@android:color/transparent"
android:centerX="0.01"
android:startColor="#000" />
</shape>
최종 결과는 다음과 가변적입니다. 구분선이있는 RecyclerView입니다.
이 실제로 문제를 해결하지 못하지만 임시 해결 방법으로 XML 레이아웃의 카드에 useCompatPadding 속성을 설정하여 Lollipop 이전 버전에서와 동일하게 측정 할 수 있습니다.
card_view:cardUseCompatPadding="true"
당신의 견해에 여백을 추가하십시오.
android:layout_marginTop="10dp"
동일한 간격 을 추가 하고 XML 에서 수행 할 추가 확장 항목에 동일한 양을 설정 padding
하고 배경색이 간격 색상을 결정합니다.RecyclerView
layoutMargin
RecyclerView
이전 요점에서 DividerItemDecoration을 분기하고 사용 사례에 맞게 단순화 된 마지막 목록 뒤의 구분선을 포함하여 ListView에서 그리는 방식으로 그리도록 수정 항목이 있습니다. 이는 수직 ItemAnimator 애니메이션도 처리합니다.
1)이 클래스를 프로젝트에 추가하십시오.
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
private Drawable divider;
public DividerItemDecoration(Context context) {
try {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
divider = a.getDrawable(0);
a.recycle();
} catch (Resources.NotFoundException e) {
// TODO Log or handle as necessary.
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
if (divider == null) return;
if (parent.getChildAdapterPosition(view) < 1) return;
if (getOrientation(parent) == LinearLayoutManager.VERTICAL)
outRect.top = divider.getIntrinsicHeight();
else
throw new IllegalArgumentException("Only usable with vertical lists");
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (divider == null) {
super.onDrawOver(c, parent, state);
return;
}
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; ++i) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
final int size = divider.getIntrinsicHeight();
final int top = (int) (child.getTop() - params.topMargin - size + child.getTranslationY());
final int bottom = top + size;
divider.setBounds(left, top, right, bottom);
divider.draw(c);
if (i == childCount - 1) {
final int newTop = (int) (child.getBottom() + params.bottomMargin + child.getTranslationY());
final int newBottom = newTop + size;
divider.setBounds(left, newTop, right, newBottom);
divider.draw(c);
}
}
}
private int getOrientation(RecyclerView parent) {
if (!(parent.getLayoutManager() instanceof LinearLayoutManager))
throw new IllegalStateException("Layout manager must be an instance of LinearLayoutManager");
return ((LinearLayoutManager) parent.getLayoutManager()).getOrientation();
}
}
2) RecylerView에 데코레이터 추가 :
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity()));
구글에서 검색 가져온 다음 ItemDecoration 을 다음에 추가 하십시오 RecyclerView
.
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private Drawable mDivider;
private boolean mShowFirstDivider = false;
private boolean mShowLastDivider = false;
public DividerItemDecoration(Context context, AttributeSet attrs) {
final TypedArray a = context
.obtainStyledAttributes(attrs, new int[]{android.R.attr.listDivider});
mDivider = a.getDrawable(0);
a.recycle();
}
public DividerItemDecoration(Context context, AttributeSet attrs, boolean showFirstDivider,
boolean showLastDivider) {
this(context, attrs);
mShowFirstDivider = showFirstDivider;
mShowLastDivider = showLastDivider;
}
public DividerItemDecoration(Drawable divider) {
mDivider = divider;
}
public DividerItemDecoration(Drawable divider, boolean showFirstDivider,
boolean showLastDivider) {
this(divider);
mShowFirstDivider = showFirstDivider;
mShowLastDivider = showLastDivider;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
if (mDivider == null) {
return;
}
if (parent.getChildPosition(view) < 1) {
return;
}
if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
outRect.top = mDivider.getIntrinsicHeight();
} else {
outRect.left = mDivider.getIntrinsicWidth();
}
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (mDivider == null) {
super.onDrawOver(c, parent, state);
return;
}
// Initialization needed to avoid compiler warning
int left = 0, right = 0, top = 0, bottom = 0, size;
int orientation = getOrientation(parent);
int childCount = parent.getChildCount();
if (orientation == LinearLayoutManager.VERTICAL) {
size = mDivider.getIntrinsicHeight();
left = parent.getPaddingLeft();
right = parent.getWidth() - parent.getPaddingRight();
} else { //horizontal
size = mDivider.getIntrinsicWidth();
top = parent.getPaddingTop();
bottom = parent.getHeight() - parent.getPaddingBottom();
}
for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
if (orientation == LinearLayoutManager.VERTICAL) {
top = child.getTop() - params.topMargin;
bottom = top + size;
} else { //horizontal
left = child.getLeft() - params.leftMargin;
right = left + size;
}
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
// show last divider
if (mShowLastDivider && childCount > 0) {
View child = parent.getChildAt(childCount - 1);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
if (orientation == LinearLayoutManager.VERTICAL) {
top = child.getBottom() + params.bottomMargin;
bottom = top + size;
} else { // horizontal
left = child.getRight() + params.rightMargin;
right = left + size;
}
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
private int getOrientation(RecyclerView parent) {
if (parent.getLayoutManager() instanceof LinearLayoutManager) {
LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
return layoutManager.getOrientation();
} else {
throw new IllegalStateException(
"DividerItemDecoration can only be used with a LinearLayoutManager.");
}
}
}
이 링크는 나에게 매력처럼 작동했습니다.
https://gist.github.com/lapastillaroja/858caf1a82791b6c1a36
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private Drawable mDivider;
private boolean mShowFirstDivider = false;
private boolean mShowLastDivider = false;
public DividerItemDecoration(Context context, AttributeSet attrs) {
final TypedArray a = context
.obtainStyledAttributes(attrs, new int[]{android.R.attr.listDivider});
mDivider = a.getDrawable(0);
a.recycle();
}
public DividerItemDecoration(Context context, AttributeSet attrs, boolean showFirstDivider,
boolean showLastDivider) {
this(context, attrs);
mShowFirstDivider = showFirstDivider;
mShowLastDivider = showLastDivider;
}
public DividerItemDecoration(Drawable divider) {
mDivider = divider;
}
public DividerItemDecoration(Drawable divider, boolean showFirstDivider,
boolean showLastDivider) {
this(divider);
mShowFirstDivider = showFirstDivider;
mShowLastDivider = showLastDivider;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
if (mDivider == null) {
return;
}
if (parent.getChildPosition(view) < 1) {
return;
}
if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
outRect.top = mDivider.getIntrinsicHeight();
} else {
outRect.left = mDivider.getIntrinsicWidth();
}
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (mDivider == null) {
super.onDrawOver(c, parent, state);
return;
}
// Initialization needed to avoid compiler warning
int left = 0, right = 0, top = 0, bottom = 0, size;
int orientation = getOrientation(parent);
int childCount = parent.getChildCount();
if (orientation == LinearLayoutManager.VERTICAL) {
size = mDivider.getIntrinsicHeight();
left = parent.getPaddingLeft();
right = parent.getWidth() - parent.getPaddingRight();
} else { //horizontal
size = mDivider.getIntrinsicWidth();
top = parent.getPaddingTop();
bottom = parent.getHeight() - parent.getPaddingBottom();
}
for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
if (orientation == LinearLayoutManager.VERTICAL) {
top = child.getTop() - params.topMargin;
bottom = top + size;
} else { //horizontal
left = child.getLeft() - params.leftMargin;
right = left + size;
}
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
// show last divider
if (mShowLastDivider && childCount > 0) {
View child = parent.getChildAt(childCount - 1);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
if (orientation == LinearLayoutManager.VERTICAL) {
top = child.getBottom() + params.bottomMargin;
bottom = top + size;
} else { // horizontal
left = child.getRight() + params.rightMargin;
right = left + size;
}
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
private int getOrientation(RecyclerView parent) {
if (parent.getLayoutManager() instanceof LinearLayoutManager) {
LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
return layoutManager.getOrientation();
} else {
throw new IllegalStateException(
"DividerItemDecoration can only be used with a LinearLayoutManager.");
}
}
}
그런 다음 활동에서 :
mCategoryRecyclerView.addItemDecoration(
new DividerItemDecoration(this, null));
또는 조각을 사용하는 경우 :
mCategoryRecyclerView.addItemDecoration(
new DividerItemDecoration(getActivity(), null));
DividerItemDecoration과 같이 recyclerview에 다양한 데코레이터를 사용하여 항목을 장식 할 수 있습니다.
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
private Drawable mDivider;
/**
* Default divider will be used
*/
public DividerItemDecoration(Context context) {
final TypedArray styledAttributes = context.obtainStyledAttributes(ATTRS);
mDivider = styledAttributes.getDrawable(0);
styledAttributes.recycle();
}
/**
* Custom divider will be used
*/
public DividerItemDecoration(Context context, int resId) {
mDivider = ContextCompat.getDrawable(context, resId);
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
} 다음과 같이 위를 사용하십시오.
RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST);
recyclerView.addItemDecoration(itemDecoration);
다음은 같이 목록 내의 각 항목 사이에 구분선이 표시됩니다.
더 자세한 정보를 원하시는 분들은이 가이드 에서 RecyclerView 사용 _ CodePath Android Cliffnotes를 확인하세요.
여기에 몇 가지 대답은 여백 사용을 제안하지만 문제는 다음과 같습니다. 추가 된 항목 및 여백을 모두 추가하면 나타나고 너무 커집니다. 둘 중 하나만 추가하면 전체 목록의 맨 위 또는 맨 아래에 여백이 없습니다. 거리의 절반을 위쪽에, 절반을 아래쪽에 추가하면 바깥 쪽 여백이 너무 작아집니다.
따라서 미학적으로 올바른 해결책은 시스템이 존재하게 적용 할 위치를 알고있는 구분선입니다.
아래 의견에 의문 사항이 있으면 알려주십시오. :)
너무 늦 GridLayoutManager
습니다만 사용합니다.
public class GridSpacesItemDecoration : RecyclerView.ItemDecoration
{
private int space;
public GridSpacesItemDecoration(int space) {
this.space = space;
}
public override void GetItemOffsets(Android.Graphics.Rect outRect, View view, RecyclerView parent, RecyclerView.State state)
{
var position = parent.GetChildLayoutPosition(view);
/// Only for GridLayoutManager Layouts
var manager = parent.GetLayoutManager() as GridLayoutManager;
if (parent.GetChildLayoutPosition(view) < manager.SpanCount)
outRect.Top = space;
if (position % 2 != 0) {
outRect.Right = space;
}
outRect.Left = space;
outRect.Bottom = space;
}
}
이것은 당신이 모든 스팬에 대해 작동합니다.
올리.
shape xml
for change을 만드는 대신 구분선 높이와 색상을 변경하십시오. 다음과 같이 프로그래밍 방식으로 만들 수 있습니다.
val divider = DividerItemDecoration(context,
DividerItemDecoration.VERTICAL)
divider.setDrawable(ShapeDrawable().apply {
intrinsicHeight = resources.getDimensionPixelOffset(R.dimen.dp_15)
paint.color = Color.RED // note: currently (support version 28.0.0), we can not use tranparent color here, if we use transparent, we still see a small divider line. So if we want to display transparent space, we can set color = background color or we can create a custom ItemDecoration instead of DividerItemDecoration.
})
recycler_devices.addItemDecoration(divider)
항목에 대해 동일한 공간을 추가하려는 경우 가장 간단한 방법은 RecycleView에 대해 위쪽 + 왼쪽 여백을 추가하고 카드 항목에 오른쪽 + 하단 여백을 추가하는 것입니다.
dimens.xml
<resources>
<dimen name="divider">1dp</dimen>
</resources>
list_item.xml
<CardView
android:layout_marginBottom="@dimen/divider"
android:layout_marginRight="@dimen/divider">
...
</CardView>
list.xml
<RecyclerView
android:paddingLeft="@dimen/divider"
android:paddingTop="@dimen/divider"
/>
같이 목록 항목에 줄을 추가했습니다.
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/dividerColor"/>
1px 는가는 선을 그립니다.
마지막 행에 대한 구분선을 숨기려면
divider.setVisiblity(View.GONE);
마지막 목록 항목의 onBindViewHolder에서.
프로그래밍 방식으로 쉽게 추가 할 수 있습니다.
레이아웃 관리자가 선형 레이아웃 인 경우 다음에서 사용할 수 있습니다.
DividerItemDecoration은 LinearLayoutManager의 항목 간 구분선으로 사용할 수있는 RecyclerView.ItemDecoration입니다. HORIZONTAL 및 VERTICAL 방향을 모두 지원합니다.
mDividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
mLayoutManager.getOrientation());
recyclerView.addItemDecoration(mDividerItemDecoration);
XML을 사용하지 않는 간단한 코드 기반 답변이 필요하다고 생각합니다.
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
ShapeDrawable shapeDrawableForDivider = new ShapeDrawable(new RectShape());
int dividerThickness = // (int) (SomeOtherView.getHeight() * desiredPercent);
shapeDrawableForDivider.setIntrinsicHeight(dividerThickness);
shapeDrawableForDivider.setAlpha(0);
dividerItemDecoration.setDrawable(shapeDrawableForDivider);
recyclerView.addItemDecoration(dividerItemDecoration);
은 RecyclerView
에서 조금 다르다 ListView
. 실제로 RecyclerView
는 ListView
비슷한 구조가 필요 합니다. 예를 들어 LinearLayout
. 는 LinearLayout
(가의 각 요소를 구분하는)의 각 요소를 나타냅니다. 아래 코드 에서 항목 사이에 약간의 공간을 두는 "패딩"이있는 개체 로 RecyclerView
구성 되어 있습니다. 그 공간을 정말 작게 만들면 선이 생생합니다.CardView
LinearLayout
다음은 recyclerview_layout.xml의 Recycler보기입니다.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".ToDoList">
<!-- A RecyclerView with some commonly used attributes -->
<android.support.v7.widget.RecyclerView
android:id="@+id/todo_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
그리고 다음은 다른 파일에있는 각 항목의 모양입니다 (그리고 모든 항목을 둘러싼 LinearLayout의 android : padding으로 인해 분할 된 것으로 표시됩니다.) : cards_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
**android:padding="@dimen/activity_vertical_margin"**>
<!-- A CardView that contains a TextView -->
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="100dp"
android:elevation="30dp"
card_view:cardElevation="3dp">
<TextView
android:id="@+id/info_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</android.support.v7.widget.CardView>
</LinearLayout>
정말 쉬운 해결책은 RecyclerView-FlexibleDivider 를 사용하는 것입니다.
추가 추가 :
compile 'com.yqritc:recyclerview-flexibledivider:1.4.0'
recyclerview에 추가하십시오.
recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(context).build());
그리고 당신은 끝났습니다!
1. 방법 중 하나는 cardview와 recycler view를 함께 사용하여 디바이더와 같은 효과를 쉽게 추가 할 수 있습니다. 전의. https://developer.android.com/training/material/lists-cards.html
2. 또 다른 방법은 리사이클 러 뷰의 list_item_layout에 구분선으로 뷰를 추가하는 입니다.
<View
android:id="@+id/view1"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/colorAccent" />
public class CommonItemSpaceDecoration extends RecyclerView.ItemDecoration {
private int mSpace = 0;
private boolean mVerticalOrientation = true;
public CommonItemSpaceDecoration(int space) {
this.mSpace = space;
}
public CommonItemSpaceDecoration(int space, boolean verticalOrientation) {
this.mSpace = space;
this.mVerticalOrientation = verticalOrientation;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.top = SizeUtils.dp2px(view.getContext(), mSpace);
if (mVerticalOrientation) {
if (parent.getChildAdapterPosition(view) == 0) {
outRect.set(0, SizeUtils.dp2px(view.getContext(), mSpace), 0, SizeUtils.dp2px(view.getContext(), mSpace));
} else {
outRect.set(0, 0, 0, SizeUtils.dp2px(view.getContext(), mSpace));
}
} else {
if (parent.getChildAdapterPosition(view) == 0) {
outRect.set(SizeUtils.dp2px(view.getContext(), mSpace), 0, 0, 0);
} else {
outRect.set(SizeUtils.dp2px(view.getContext(), mSpace), 0, SizeUtils.dp2px(view.getContext(), mSpace), 0);
}
}
}
}
이렇게하면 모든 항목의 상단과 하단 (또는 오른쪽과 오른쪽)에 공간이 추가되고 recyclerView로 수 있습니다.
recyclerView.addItemDecoration(new CommonItemSpaceDecoration(16));
SizeUtils.java
public class SizeUtils {
public static int dp2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
자체 버전의 RecyclerView.ItemDecoration 구현
public class SpacingItemDecoration extends RecyclerView.ItemDecoration {
private int spacingPx;
private boolean addStartSpacing;
private boolean addEndSpacing;
public SpacingItemDecoration(int spacingPx) {
this(spacingPx, false, false);
}
public SpacingItemDecoration(int spacingPx, boolean addStartSpacing, boolean addEndSpacing) {
this.spacingPx = spacingPx;
this.addStartSpacing = addStartSpacing;
this.addEndSpacing = addEndSpacing;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
if (spacingPx <= 0) {
return;
}
if (addStartSpacing && parent.getChildLayoutPosition(view) < 1 || parent.getChildLayoutPosition(view) >= 1) {
if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
outRect.top = spacingPx;
} else {
outRect.left = spacingPx;
}
}
if (addEndSpacing && parent.getChildAdapterPosition(view) == getTotalItemCount(parent) - 1) {
if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
outRect.bottom = spacingPx;
} else {
outRect.right = spacingPx;
}
}
}
private int getTotalItemCount(RecyclerView parent) {
return parent.getAdapter().getItemCount();
}
private int getOrientation(RecyclerView parent) {
if (parent.getLayoutManager() instanceof LinearLayoutManager) {
return ((LinearLayoutManager) parent.getLayoutManager()).getOrientation();
} else {
throw new IllegalStateException("SpacingItemDecoration can only be used with a LinearLayoutManager.");
}
}
}
'ProgramingTip' 카테고리의 다른 글
올해는 어떻게 PHP를 사용합니까? (0) | 2020.09.28 |
---|---|
jQuery를 사용하여 HTML 입력 상자에서 숫자 (0-9) 만 허용하는 방법은 무엇입니까? (0) | 2020.09.28 |
값으로 선택 옵션 '선택됨'설정 (0) | 2020.09.28 |
Xcode 프로젝트에 대한 Git 무시 파일 (0) | 2020.09.28 |
'수익률'의 적절한 사용 (0) | 2020.09.28 |