多个六边形按钮
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>
我正在尝试创建一个具有多个六边形形状的设计 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>