需要实现下面的这种选项卡的功能。
刚开始准备使用第三方的tab来实现,但项目中该功能不需要滑动,只要点击来进行切换。
就想着通过shape 来实现对应的样式。
思路一
1.父布局设置边框stroke、solid、corners,padding。
2.子布局根据android:state_selected 展示选中的布局样式,并把corners的大小设置成和父布局一致。
3.在color 目录中编写布局,根据android:state_selected 设置选中和默认的字体颜色。
4.在Java代码中根据点击事件设置view.setSelect(true).
其中第二步设置子布局的corners 非常重要。因为shape设置为rectangle 默认没有圆角,这样子布局就会覆盖父布局的圆角,显式为矩形。
代码如下:
父布局的shape 如下:
注意:这里的padding 和stroke 设置成一致,才能正常展示出父布局的stroke 。要不然会被子布局覆盖。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:dither="true">
<stroke
android:color="#10B3B7"
android:width="@dimen/dp_1"
/>
<corners android:radius="@dimen/dp_8" />
<solid android:color="#10B3B7"/>
<padding android:top="@dimen/dp_1" android:left="@dimen/dp_1" android:right="@dimen/dp_1" android:bottom="@dimen/dp_1"/>
</shape>
左边的子布局shape 如下:
注意:其中左上角和左下角的圆角和父布局保持一致。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" >
<shape android:shape="rectangle">
<solid android:color="#10B3B7"/>
<corners android:topLeftRadius="@dimen/dp_8" android:bottomLeftRadius="@dimen/dp_8" />
</shape>
</item>
<item>
<shape android:shape="rectangle" android:dither="true">
<solid android:color="@color/white"/>
<corners android:topLeftRadius="@dimen/dp_8" android:bottomLeftRadius="@dimen/dp_8" />
</shape>
</item>
</selector>
右边的子布局shape 如下:
注意:其中右上角和右下角的圆角和父布局保持一致。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<shape android:shape="rectangle" android:dither="true">
<solid android:color="#10B3B7"/>
<corners android:topRightRadius="@dimen/dp_8" android:bottomRightRadius="@dimen/dp_8" />
</shape>
</item>
<item>
<shape android:shape="rectangle" android:dither="true">
<solid android:color="@color/white"/>
<corners android:topRightRadius="@dimen/dp_8" android:bottomRightRadius="@dimen/dp_8" />
</shape>
</item>
</selector>
展示界面布局如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dp_8"
android:background="@drawable/bg_father_shape"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/core_measure_view"
android:textSize="@dimen/sp_18"
android:gravity="center"
android:layout_weight="1"
android:textColor="@color/core_measure_text_selector"
android:background="@drawable/bg_left_selector"
android:padding="@dimen/dp_10"
/>
<TextView
android:id="@+id/tv_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/all_measure_view"
android:textSize="@dimen/sp_18"
android:gravity="center"
android:layout_weight="1"
android:textColor="@color/core_measure_text_selector"
android:background="@drawable/bg_right_selector"
android:padding="@dimen/dp_10"
/>
</LinearLayout>
</LinearLayout>
运行到手机效果如下:
猛一看似乎和设计图没有什么区别,左右点击切换也没有问题。
但仔细查看,特别是未选中选项卡的圆角,父布局和子布局有些重叠,致使看起来有些模糊。出现这种情况的原因是设置了父布局的padding 和stroke .由于是圆角,所以设置的padding和实际的间隔会有偏差,这样才造成重叠的情况。
如果父布局没有设置stroke 或者对布局要求没有那么严格,使用上面的方式完全是可行的。
但是。。。
对于追求完美的我们,还是想办法实现和设计图一致的效果。
既然是由于父布局设置padding 和stroke 造成的,那就不适用父布局,直接在每个子布局中设置stroke 是否可行呢。
思路二
1.单独编写各种情况的子布局样式。设置一致的stroke .
2.处理相邻子布局相交的线,设置成不展示该线,或者只展示其中一个子布局的相交线。
3.子布局根据android:state_selected 展示选中的布局样式。
4.在color 目录中编写布局,根据android:state_selected 设置选中和默认的字体颜色。
5.在Java代码中根据点击事件设置view.setSelect(true).
关于第二条, 多个有相同边框的 view 拼接在一块,会有重复的边框,造成中间边框变粗,从而影响效果。 处理方式是使用标签layer-list 来隐藏矩形的某个边。 比如右边 view 的左边框设置为 - 1dp(绝对值和边框一致),则右边 view 的左边框不再显示。或者给左边 view 的右边框设置为 - 1dp(绝对值和边框一致) 亦可。
左边选中的样式代码如下:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:right="-1dp">
<shape>
<solid android:color="#10B3B7" />
<stroke
android:width="@dimen/dp_1"
android:color="@color/actionbar_bg" />
<corners
android:topLeftRadius="@dimen/dp_8"
android:bottomLeftRadius="@dimen/dp_8" />
</shape>
</item>
</layer-list>
左边未选中的样式代码如下:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:right="-1dp">
<shape>
<solid android:color="@color/white" />
<stroke
android:width="@dimen/dp_1"
android:color="#10B3B7" />
<corners
android:topLeftRadius="@dimen/dp_8"
android:bottomLeftRadius="@dimen/dp_8" />
</shape>
</item>
</layer-list>
左边布局的样式代码如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/bg_left_have_selector"/>
<item android:drawable="@drawable/bg_left_no_selector"/>
</selector>
右边布局的样式代码和左边的大致一致。这里就不展示啦。
最后运行到手机的效果如下:
和实际的设计图还是很接近的。完美~
总结
1.如果父布局不设置stroke ,使用思路一就可以很好的实现。
2.父布局设置了stroke ,使用思路二。
|