기금넷 공식사이트 - 금 선물 - 1.Android recycleView 범용 구분 기호 GridLayoutManager 레이아웃 항목 왼쪽 및 오른쪽 등거리 (가장 이해하기 쉬움).

1.Android recycleView 범용 구분 기호 GridLayoutManager 레이아웃 항목 왼쪽 및 오른쪽 등거리 (가장 이해하기 쉬움).

오늘은 RecycleView 에 대한 일련의 자습서를 시작하겠습니다. 분할선, 그룹화, 부분 새로 고침, 동적 추가, 캐시 원리, Tik Tok 효과, 폭포수. 중첩, 애니메이션 등.

RecyclerView 의 분할선은 캔버스와 항목 간격띄우기 설정을 통해 그려집니다. 너는 두 가지 방법을 알아야 한다.

GetItemOffsets () 및 onDraw 메서드

GetItemOffsets 는 각 ItemView 에 사용됩니다.

OnDraw: 색상을 탐색하고 수정합니다.

사용자 정의 TestDividerItemDeoration 은 하나의 메서드, getItemOffsets () 만 구현하는 것을 볼 수 있습니다. 이 방법에는 네 개의 매개변수가 있습니다.

직수출

뷰 뷰

RecyclerView 상위

RecyclerView. 상태 상태

녹색 영역은 RecyclerView 의 ItemView 중 하나를 나타내고 외부 주황색 영역은 해당 outRect, 즉 ItemView 와 다른 구성 요소 사이의 오프셋 영역으로 margin 속성에 해당합니다. GetItemOffsets () 메서드를 재정의한 다음 outRect 에서 top, left, right 및 bottom 을 지정하여 모든 방향의 간격을 제어할 수 있습니다.

이렇게 하면 간단한 구분선 효과가 구현되지만 이 방법의 효과는 배경 색상에만 따라 달라질 수 있습니다. 구분선의 색상을 사용자 정의하려면 어떻게 해야 합니까? 이때 OnDraw () 가 필요합니다.

---------

소스 코드 분석: recycleview 에서

분할선에 주의하세요. 색상이 없습니다. 기본값은 흰색이며 보이지 않습니다.

첫 번째 방안, 통과

GetItemOffsets () 메서드를 사용하여 선을 분할합니다!

첫 번째인지 마지막인지, 싱글인지 2 인인지, 어떤 유형인지 판단한다.

/* * *

* 분할선에 주의하십시오. 색상이 없습니다. 기본값은 흰색이며 보이지 않습니다.

* @param outRect

* @param 보기

* @param parent

* @param 상태

*/

Private void testitem offset (rectoutrect, View view, RecyclerView parent, RecyclerView). State state) {

Intchildadapterposition = parent.getchildadapterposition (뷰);

If (childAdapterPosition ==0) {

Outrect.set (0,20,0,20);

} 그렇지 않으면 {

Outrect.set (0,0,0,20);

}

}

두 번째 시나리오: ondraw ()

@ 덮어쓰기

Public void onDraw(Canvas c, RecyclerView parent, recyclerview). State state) {

Super.onDraw(c, parent, state);

Intchildcount = parent.getchildcount ();

For(int I = 0;; 나< 아동 수; I++) {

Viewview = parent.getchildat (I);

Intindex = parent.getchildadapterposition (뷰);

//첫 번째 ItemView 를 그릴 필요가 없습니다.

If (index ==0) {

계속;

}

Float divider top = view.gettop ()-mdividerheight;

Floatdividerleft = parent.getpaddingleft ();

Float divider bottom = view.gettop ();

Floatdividerright = parent.getwidth ()-parent.getpaddingright ();

C.drawRect(dividerLeft, dividerTop, dividerRight, dividerBottom, mpaint);

}

}

-응? GridLayoutManager 레이아웃 항목의 왼쪽 및 오른쪽 간격이 같습니다.

사고 분석

우선 GridLayoutmanager 의 경우 spancount 를 3 으로 설정하면 각 항목의 최대 폭은 itemmaxw = recyclerw/spancount = recyclew3 입니다.

우리의 spancount 가 3 이라고 가정하면, itemdata 를 설정하지 않은 경우 분포는 이와 같습니다. 첫 번째 열과 마지막 행 사이의 거리가 다르다는 것을 알 수 있습니다.

GridVIew 문제: item 의 높이와 폭은 처음에 고정되어 있습니다.

1. 분할선이 존재하며 이상적이지 않습니다. 좌우가 상당합니다.

2. 상하의 구분이 없다.

소스 코드는 다음과 같이 얻습니다.

위에서 분석한 소스 코드에 따르면 Outrect 의 메서드를 호출할 때 알 수 있습니다. 설정 (intleft, int top, int right, int bottom), 왼쪽은 항상 0, 오른쪽은 항상 분할선의 폭, 각 항목의 폭에서 (left+right) 크기를 뺀 값입니다.

왼쪽은 항상 0 이고 오른쪽은 항상 구분선의 폭입니다.

왼쪽 위 오른쪽 아래 값은 얼마입니까?

각 항목의 이동 거리를 계산하고 왼쪽 및 오른쪽 이동 거리를 계산합니다.

계산 분석:

1. 왼쪽 분할선의 폭은 sW (알려진) 입니다.

2. 표시된 각 품목의 폭 및 레이아웃에 정의된 품목의 폭.

3. 총구분 선 너비: totalDivider= 화면 너비 -spanCount*itemWidth

4. 열 간 구분선의 너비는 dw = (화면 너비 -spanCount*item-2*sW? ) /(spantcount- 1)

5. 각 항목마다 얼마나 많은 공간을 남겨야 합니까? Ew=totalDivider/spanCount (예: paddingLeft+paddingRight).

왼쪽:? 왼쪽 간격 값 (절대값, 차이)

Right: 오른쪽의 간격 값입니다.

각 항목이 이동하는 거리:

첫 번째: l0 = SW? R0=eW-sW

두 번째 항목: l1= dw-r0 = dw-ew+SWR1= ew-l1= 2ew-dew

세 번째 항목: L2 = dw-r1= 2 (dw-ew)+swr2 = ew-L2 = 3ew-2dw-SW.

공식을 가져오려면 다음과 같이 하십시오.

Ln= (위치% 범위) *(dw-ew)+sw

Rn=ew-Ln

요약: dw, ew, SW 의 세 가지 값을 얻습니다.

스테파니 화이트: 왼쪽 거리

Ew: 각각의 평균 분할선.

Dw: 열 간 구분선의 폭

Int firstLastSpace = 50// 맨 왼쪽 구분 선의 폭

@SuppressLint("LongLogTag ")

@ 덮어쓰기

Public void getitem offsets (rectoutrect, View view, RecyclerView parent, RecyclerView). State state) {

Super.getItemOffsets(outRect, view, parent, state);

Count++;+;

OutRect.top = 20

MDividerHeight = 0;;

Int itemWidth =dip2px(context,100);

Intscreenwidth = getscreenwidth (컨텍스트);

Intdw = (screen width-3 * item width-2 * first last space)/2; //마지막으로 이 채우기 값을 계산합니다.

//오해: 중간 분할선의 총 거리는 왼쪽에서 오른쪽으로 동일하지 않을 수 있습니다.

Inttotaldivder = screen width-3 * item width;

Log.d ("testdivideritemdecoration", "totaldivider"+totaldivider);

Inteachdivder = total divder/3;

Int item position =((recycle view). Layoutparams) view.getlayoutparams ()) 를 참조하십시오. Getviewlayoutposition ();

//for 루프를 사용하지 마십시오.

Outrect.left = (항목 위치% 3) * (dw-eachdivder)+first last space;

Outrect.right = eachdivder-outrect.right;

}

잘못된 생각:

//오해: 중간 분할선의 총 거리는 왼쪽에서 오른쪽으로 동일하지 않을 수 있습니다.

//for 루프를 사용하지 마십시오.

Int firstLastSpace = 50// 맨 왼쪽 구분 선의 폭

@SuppressLint("LongLogTag ")

@ 덮어쓰기

Public void getitem offsets (rectoutrect, View view, RecyclerView parent, RecyclerView). State state) {

Super.getItemOffsets(outRect, view, parent, state);

Count++;+;

OutRect.top = 20

MDividerHeight = 0;;

Int itemWidth =dip2px(context,100);

Intscreenwidth = getscreenwidth (컨텍스트);

Intpadding = (screen width-3 * item width-2 * first last space)/4; //마지막으로 이 채우기 값을 계산합니다.

//너는 이렇게 할 수 없다. 각 항목의 분할선이 같은지 확인해야 합니다.

Log. d(" testdivideitemdecotion ","GetItemOffsets"+Count+ "항목 너비:"+item width+"padding" "

//좌우 거리만 계산합니다.

Intchildcount = parent.getchildcount ();

For(int I = 0;; 나< 아동 수; I++) {

If (i %3 ==0) {// 맨 왼쪽 항목

Outrect.left = first lastspace;

OutRect.right = 채우기;

}else if (i %3 == 1) {

OutRect.left = 채우기;

OutRect.right = 채우기;

}else if (i %3 ==2) {

OutRect.left = 채우기;

Outrect.right = first lastspace;

}

}

}

폭포수 설정:

Intspanindex = layoutparams.getspanindex ();

공용 클래스 feeddorationextends recyclerview. 프로젝트 장식 {

개인 homepagecardaptermhomepagecardapter;

공용 feed decoration (homepagecardapter mhomepagecardapter) {

This.mhomepagecardapter = mhomepagecardapter;

}

@ 덮어쓰기

Public void getitem offsets (@ nonnull rect outrect, @NonNull View view, @ NonNull RecyclerView parent, @ nonnull recycler State state) {

If(mhomepagecardapter = = null){

반환;

}

If (mhomepagecardapter.getitemviewtype (parent.getchildadapterposition (view)) = = homepagemultiplecard Homepage _ multiple _ card _ type _ fitness _ feed) {

StaggeredGridLayoutManager. Layoutparams layoutparams = (staggeredgridlayoutmanager). Layoutparams) view.getlayoutparams ();

Intspanindex = layoutparams.getspanindex ();

If (spanIndex ==0) {

Outrect.set (densityutil.dip2px (shadowapp.context (), 14), 0, densityutil ..

} 그렇지 않으면 {

Outrect.set (densityutil.dip2px (shadowapp.context (), 5), 0, densityutil.dip2px (shadow

}

}

}

}

데모 주소: /Peng Cai Hua 123456/ 심남대로