多个六边形按钮

multiple hexagon shape buttons

我正在尝试创建一个具有多个六边形形状的设计 buttons.I我能够创建一个六边形按钮,但就我而言,我有一个需要在设计中显示的项目列表模式如下。

如果这样的列表设计可以通过RecyclerView实现,那就更好了。

你可以尝试类似的东西。它需要改进,因为两条线之间的差距取决于屏幕尺寸不是恒定的:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin">

    <include
        layout="@layout/partial_squared"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

</RelativeLayout>

partial_squared.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <include
        layout="@layout/partial_first_row"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <include
        layout="@layout/partial_second_row"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/line_height_80" />
</RelativeLayout>

partial_first_row.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ImageView style="@style/InlinedImageView" />

        <ImageView style="@style/InlinedImageView" />

        <ImageView style="@style/InlinedImageView" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:orientation="horizontal">

        <TextView
            style="@style/InlinedTextView"
            android:text="case 1" />

        <TextView
            style="@style/InlinedTextView"
            android:text="case 2" />

        <TextView
            style="@style/InlinedTextView"
            android:text="case 3" />
    </LinearLayout>
</RelativeLayout>

partial_second_row.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:weightSum="3">

        <Space
            android:layout_width="0dp"
            android:layout_height="15dp"
            android:layout_weight=".5" />

        <ImageView style="@style/InlinedImageView" />

        <ImageView style="@style/InlinedImageView" />

        <Space
            android:layout_width="0dp"
            android:layout_height="15dp"
            android:layout_weight=".5" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:orientation="horizontal">

        <Space
            android:layout_width="0dp"
            android:layout_height="15dp"
            android:layout_weight=".5" />

        <TextView
            style="@style/InlinedTextView"
            android:text="case 1" />

        <TextView
            style="@style/InlinedTextView"
            android:text="case 2" />

        <Space
            android:layout_width="0dp"
            android:layout_height="15dp"
            android:layout_weight=".5" />
    </LinearLayout>

</RelativeLayout>

dimens.xml

<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>

    <dimen name="line_height">110dp</dimen>
    <dimen name="line_height_80">72dp</dimen>
    <dimen name="margin_in_between">2dp</dimen>
</resources>

styles.xml

<style name="InlinedImageView">
    <item name="android:layout_width">0dp</item>
    <item name="android:layout_height">@dimen/line_height</item>
    <item name="android:layout_weight">1</item>
    <item name="android:src">@drawable/triangle</item>
    <item name="android:paddingLeft">@dimen/margin_in_between</item>
    <item name="android:paddingRight">@dimen/margin_in_between</item>
</style>

<style name="InlinedTextView">
    <item name="android:gravity">center</item>
    <item name="android:layout_width">0dp</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:layout_weight">1</item>
</style>

结果

有点棘手,但我是这样解决的。 有一个像下面这样的 recyclerView

<android.support.v7.widget.RecyclerView
                android:id="@+id/hexa_rcv"
                android:layout_margin=""@dimen/hexa_dp""
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>

在 res "values-sw360dp" 和 "values-sw400dp" 中创建 2 个文件夹。在两个文件夹中创建 dimens.xml。 dimens.xml 里面的 values-sw360dp 应该有

<resources>
    <dimen name="margin_16_dp">16dp</dimen>
    <dimen name="hexa_dp">25dp</dimen>
</resources>

dimens.xml 里面的 values-sw400dp 应该有

<resources>
    <dimen name="margin_16_dp">16dp</dimen>
    <dimen name="hexa_dp">55dp</dimen>
</resources>

还有一个像下面这样的 recyclerView 项目

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tv_1"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:gravity="center"
    android:textColor="@color/white"
    android:textSize="18sp"
    android:text="ICU_HDW"
    android:background="@drawable/hexagon"/>

接下来获取 recyclerView 的引用并将列大小设置为 3 的 GridaLayoutManager。将每 5 个项目的跨度大小设置为 2(以便第 4 个项目的跨度大小为 1,第 5 个项目的大小为 2,因此两者一起将完成该行,下一项将放在下一行)

我这里用的是kotlin 你可以转换成java

    RecyclerView hexaRcv = (RecyclerView) findViewById(R.id.hexa_rcv);
    GridLayoutManager manager = new GridLayoutManager(this, 3);
    manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            int size = 1;
            if ((position + 1) % 5 == 0){
                size = 2;
            }
            return size;
        }
    });

    hexaRcv.setLayoutManager(manager);
    hexaRcv.setAdapter(new GridAdapter());

下面是GridAdapter()

public class GridAdapter extends RecyclerView.Adapter<GridAdapter.HexagonHolder> {
@Override
public GridAdapter.HexagonHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.hexa_tv, parent, false);
    return new HexagonHolder(view);
}

@Override
public void onBindViewHolder(GridAdapter.HexagonHolder holder, int position) {
    int pos = position + 1;
    int topMargin = pxFromDp(holder.textView.getContext(), -17);
    int leftMargin = pxFromDp(holder.textView.getContext(), 51); //3 times of 17
    GridLayoutManager.LayoutParams param = (GridLayoutManager.LayoutParams) holder.textView.getLayoutParams();
    if (pos < 4) {
        param.setMargins(0, 0, 0, 0);
    } else if ((pos + 1) % 5 == 0 || pos % 5 == 0) {
        param.setMargins(leftMargin, topMargin, 0, 0);
    } else {
        param.setMargins(0, topMargin, 0, 0);
    }
    holder.textView.setLayoutParams(param);

}

@Override
public int getItemCount() {
    return 17;
}

static class HexagonHolder extends RecyclerView.ViewHolder {
    TextView textView;

    HexagonHolder(View v) {
        super(v);
        textView = v.findViewById(R.id.tv_1);
    }
}

private int pxFromDp(final Context context, final float dp) {
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
}

}

前 3 项没有保证金。在那之后,所有项目的上边距都将为负值 75(即 -75 像素)。每第 4 和第 5 个项目不仅有 -75 的上边距,而且还有 165 的左边距。

您可以使用常量或根据屏幕宽度实际计算它们或使用倾角。

下面是结果

下面是 hexagon.xml 将其保存在 drawable 文件夹中

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="512dp"
    android:height="512dp"
    android:viewportWidth="512"
    android:viewportHeight="512">

    <path
        android:fillColor="#148275"
        android:pathData="M485.291,129.408l-224-128c-3.285-1.877-7.296-1.877-10.581,0l-224,128c-3.328,1.899-5.376,5.44-5.376,9.259v234.667
c0,3.819,2.048,7.36,5.376,9.259l224,128c1.643,0.939,3.456,1.408,5.291,1.408s3.648-0.469,5.291-1.408l224-128
c3.328-1.899,5.376-5.44,5.376-9.259V138.667C490.667,134.848,488.619,131.307,485.291,129.408z" />
</vector>