ExpandableListView - 父项及其子项的边框

时间:2018-03-21 14:12:56

标签: android expandablelistview

我有一个使用ExpandableListView的视图,它在它周围和适配器中有很多逻辑。例如,它看起来像这样

enter image description here

我需要使用不同的皮肤显示相同的视图,其中隐藏了展开/折叠,并且在父级及其子级周围有一个边框,类似这样

enter image description here

我看到属性有整个控件的边框,或只是父或子的边框,但没有任何东西在父母及其子女周围有边框。

有人做过这样的事吗?如果没有使用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

我仍然愿意接受更好的解决方案,并且会为那些比我的解决方案更少的任何东西提供奖励。

3 个答案:

答案 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
    ));

旧答案:

这是RecyclerViewItemDecoration的实施方式,在我知道您已经使用遗留代码之前,我已经编写了此解决方案,所以我还是要分享这个

项目装饰:

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等功能。