-
Star
(268)
You must be signed in to star a gist -
Fork
(50)
You must be signed in to fork a gist
-
-
Save alexfu/0f464fc3742f134ccd1e to your computer and use it in GitHub Desktop.
| /* | |
| * Copyright (C) 2014 The Android Open Source Project | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| public class DividerItemDecoration extends RecyclerView.ItemDecoration { | |
| private static final int[] ATTRS = new int[]{ | |
| android.R.attr.listDivider | |
| }; | |
| public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL; | |
| public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL; | |
| private Drawable mDivider; | |
| private int mOrientation; | |
| public DividerItemDecoration(Context context, int orientation) { | |
| final TypedArray a = context.obtainStyledAttributes(ATTRS); | |
| mDivider = a.getDrawable(0); | |
| a.recycle(); | |
| setOrientation(orientation); | |
| } | |
| public void setOrientation(int orientation) { | |
| if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) { | |
| throw new IllegalArgumentException("invalid orientation"); | |
| } | |
| mOrientation = orientation; | |
| } | |
| @Override | |
| public void onDraw(Canvas c, RecyclerView parent) { | |
| if (mOrientation == VERTICAL_LIST) { | |
| drawVertical(c, parent); | |
| } else { | |
| drawHorizontal(c, parent); | |
| } | |
| } | |
| public void drawVertical(Canvas c, RecyclerView parent) { | |
| 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 top = child.getBottom() + params.bottomMargin; | |
| final int bottom = top + mDivider.getIntrinsicHeight(); | |
| mDivider.setBounds(left, top, right, bottom); | |
| mDivider.draw(c); | |
| } | |
| } | |
| public void drawHorizontal(Canvas c, RecyclerView parent) { | |
| final int top = parent.getPaddingTop(); | |
| final int bottom = parent.getHeight() - parent.getPaddingBottom(); | |
| 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 left = child.getRight() + params.rightMargin; | |
| final int right = left + mDivider.getIntrinsicHeight(); | |
| mDivider.setBounds(left, top, right, bottom); | |
| mDivider.draw(c); | |
| } | |
| } | |
| @Override | |
| public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { | |
| if (mOrientation == VERTICAL_LIST) { | |
| outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); | |
| } else { | |
| outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); | |
| } | |
| } | |
| } |
I wonder if it is a good idea to use Paint instead of bothering creating a drawable resource?
Any performance difference?
public DividerItemDecoration(Context context, int colorResId, int dividerWidthDimenResId) {
mPaint = new Paint();
mPaint.setColor(context.getResources().getColor(colorResId));
mPaint.setStrokeWidth((int) context.getResources().getDimension(dividerWidthDimenResId));
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
int startX = parent.getPaddingLeft();
int stopX = 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 y = child.getBottom() + params.bottomMargin;
c.drawLine(startX, y, stopX, y, mPaint);
}
}
possible bug at line 79, it should be
final int right = left + mDivider.getIntrinsicWidth();
mDivider = a.getDrawable(0);
Returns null for 5.1.1
Also adding:
mDivider = a.getDrawable(0);
returns a null drawable.
Also adding:
Line 79:
final int right = left + mDivider.getIntrinsicWidth();
Thanks for this code. I am using it to set the divider in a PreferenceFragmentCompat. For a PreferenceFragmentCompat I had to make a change so not to display a divider line under the last element. To do this, I changed drawVertical() and drawHorizontal():
from:
for (int i = 0; i < childCount; i++) {
to:
for (int i = 0; i < childCount-1; i++) {
Thanks.
You should not be looping over 0 to childCount (with or without the -1). You should loop from findFirstVisibleItemPosition() to findLastVisibleItemPosition(), checking them first for NO_POSITION. The last item check would then be whether the position is the last item from the adapter.
Didn't work for android 5.0 +
how i can increase divider width and height???????
At line 58 possible to be used childCount-1 to avoid drawing divider after last item in list