我有一个使用ExpandableListView的视图,它在它周围和适配器中有很多逻辑。例如,它看起来像这样
我需要使用不同的皮肤显示相同的视图,其中隐藏了展开/折叠,并且在父级及其子级周围有一个边框,类似这样
我看到属性有整个控件的边框,或只是父或子的边框,但没有任何东西在父母及其子女周围有边框。
有人做过这样的事吗?如果没有使用Expandablelistview并重新创建视图,我还能实现边界吗?
编辑1:
Here is a gist具有我想要做的模板。
编辑2:
我有一个使用父母和子女边界的解决方案,
setting parent to ┎─┒
and all-but-last children to ┃ ┃
and last child to ┖─┚
Here is the gist for the solution I have so far
我仍然愿意接受更好的解决方案,并且会为那些比我的解决方案更少的任何东西提供奖励。
答案 0 :(得分:3)
编辑所以我已将ItemDecoration
功能添加到ExpandableListView
,它的功能与RecyclerView
'相同。 s ItemDecoration
,这是代码:
对ExpandableListView
public class ExpandableListViewItemDecoration extends ExpandableListView {
private List<ItemDecorationListView> itemDecorations = new ArrayList<>(1);
/* ... */
public void addItemDecoration(ItemDecorationListView item){
itemDecorations.add(item);
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
final int count = itemDecorations.size();
for (int i = 0; i < count; i++) {
itemDecorations.get(i).onDrawOver(canvas, this);
}
}
ItemDecorationListView:
public abstract class ItemDecorationListView {
public void onDrawOver(Canvas c, ListView parent) {
}
}
ItemDecorator:
public class ItemDecoratorBorderListView extends ItemDecorationListView {
private final Paint paint = new Paint();
private final int size;
public ItemDecoratorBorderListView(int size, @ColorInt int color) {
this.size = size;
paint.setColor(color);
paint.setStrokeWidth(size);
paint.setStyle(Paint.Style.STROKE);
}
public static final String TAG = ItemDecoratorBorderListView.class.getSimpleName();
@Override
public void onDrawOver(Canvas c, ListView parent) {
super.onDrawOver(c, parent);
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
if (isHeader(child, parent, i)) {
for (int j = i + 1; j < childCount; j++) {
View childEnd = parent.getChildAt(j);
boolean end = isHeader(childEnd, parent, i) || j == childCount - 1;
if (end) {
if (BuildConfig.DEBUG) { Log.d(TAG, String.format(Locale.ENGLISH, "Draw called i: %d, j: %d", i, j)); }
childEnd = parent.getChildAt(j - 1);
if (j == childCount - 1) { childEnd = parent.getChildAt(j); }
float top = child.getTop() + child.getTranslationY() + size + child.getPaddingTop();
float bottom = childEnd.getBottom() + childEnd.getTranslationY() - size - childEnd
.getPaddingBottom();
float right = child.getRight() + child.getTranslationX() - size - child.getPaddingRight();
float left = child.getLeft() + child.getTranslationX() + size + child.getPaddingLeft();
c.drawRect(left, top, right, bottom, paint);
i = j - 1;
break;
}
}
}
}
}
public boolean isHeader(View child, ListView parent, int position) {
//You need to set an Id for your layout
return child.getId() == R.id.header;
}
}
只需将其添加到ExpandableListView
:
expandableList.addItemDecoration(new ItemDecoratorBorderListView(
getResources().getDimensionPixelSize(R.dimen.stroke_size),
Color.GRAY
));
旧答案:
这是RecyclerView
和ItemDecoration
的实施方式,在我知道您已经使用遗留代码之前,我已经编写了此解决方案,所以我还是要分享这个
项目装饰:
public class ItemDecoratorBorder extends RecyclerView.ItemDecoration {
private final Paint paint = new Paint();
private final int size;
public ItemDecoratorBorder(int size, @ColorInt int color) {
this.size = size;
paint.setColor(color);
paint.setStrokeWidth(size);
paint.setStyle(Paint.Style.STROKE);
}
public static final String TAG = ItemDecoratorBorder.class.getSimpleName();
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDrawOver(c, parent, state);
if (parent.getLayoutManager() == null) { return; }
int childCount = parent.getChildCount();
RecyclerView.LayoutManager lm = parent.getLayoutManager();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
if (isHeader(child, parent)) {
for (int j = i + 1; j < childCount; j++) {
View childEnd = parent.getChildAt(j);
boolean end = isHeader(childEnd, parent) || j == childCount - 1;
if (end) {
if (BuildConfig.DEBUG) { Log.d(TAG, String.format(Locale.ENGLISH, "Draw called i: %d, j: %d", i, j)); }
childEnd = parent.getChildAt(j - 1);
if (j == childCount - 1) {
childEnd = parent.getChildAt(j);
}
float top = child.getTop() + child.getTranslationY() + size + child.getPaddingTop();
float bottom = lm.getDecoratedBottom(childEnd) + childEnd.getTranslationY() - size - childEnd.getPaddingBottom();
float right = lm.getDecoratedRight(child) + child.getTranslationX() - size - child.getPaddingRight();
float left = lm.getDecoratedLeft(child) + child.getTranslationX() + size + child.getPaddingLeft();
c.drawRect(left, top, right, bottom, paint);
i = j - 1;
break;
}
}
}
}
}
public boolean isHeader(View child, RecyclerView parent) {
int viewType = parent.getLayoutManager().getItemViewType(child);
return viewType == R.layout.layout_header;
}
我使用视图类型查找组的开始和结束位置,并在开始和结束位置周围绘制一个矩形。
该代码位于my github repo
答案 1 :(得分:1)
我有一个解决方案,但是最好使用recycleView而不是listView,但是,我们可以为每一方画线,例如:
对于父组,它将类似于┎─┒
,对于没有最后一个孩子的所有孩子,它将类似于:┎ ┒
,对于最后一个孩子,它将是:{{ {1}}。
代码:`groupbg.xml:
──
normalchild.xml :
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#000" />
</shape>
</item>
<item android:left="2dp" android:top="2dp" android:right="2dp">
<shape android:shape="rectangle">
<solid android:color="#fff" />
</shape>
</item>
</layer-list>
bottomchild.xml :
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#000" />
</shape>
</item>
<item android:left="2dp" android:right="2dp">
<shape android:shape="rectangle">
<solid android:color="#fff" />
</shape>
</item>
没有设置适配器:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#000" />
</shape>
</item>
<item android:bottom="2dp">
<shape android:shape="rectangle">
<solid android:color="#fff" />
</shape>
</item>
答案 2 :(得分:0)
您可以尝试使用this库。自定义RecyclerView实现ExpandableListView等功能。