先上效果图:
首先说明下,实现这种效果有很多种方式,就是用Linearlayout来写,完全可以做到这种效果,但是,后期维护起来,那真是谁接手谁知道。如果是固定项,并条数不多,可以不用费这么多精力,当然,并不是说这样做不方便,其他不多说,谁用谁知道。
先讲下思路:
1、每一条左边是个icon,中间是一个text,右边是一个向右箭头
2、每一条之间用一条线隔开
3、最外层用一个垂直的LinearLayout来包着,Linearlayout背景选用带弧角的矩形
我这里采用组合控件,即用布局来写自定义控件,命名为ItemView
布局非常简单,就一个水平LinearLayout,再加ImageView+TextView+ImageView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/item_height"
android:minHeight="@dimen/item_height"
android:orientation="horizontal" >
<ImageView
android:id="@+id/iv_icon"
android:layout_width="@dimen/item_height"
android:layout_height="@dimen/item_height"
android:padding="5dp"
android:scaleType="fitCenter"
android:src="@drawable/app_loading0" />
<TextView
android:id="@+id/tv_content"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_weight="1.0"
android:gravity="center_vertical"
android:text="@string/app_name"
android:textColor="@color/black_90"
android:textSize="@dimen/text_size_normal" />
<ImageView
android:layout_width="@dimen/item_height"
android:layout_height="@dimen/item_height"
android:scaleType="center"
android:src="@drawable/arrow_right" />
</LinearLayout>
接下来,我们希望在用这个ItemView可以直接在布局时引用drawable和string,在res目录的value目录下,建立一个xml的资源文件attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- item style -->
<declare-styleable name="item_view">
<attr name="item_icon" format="reference" />
<attr name="item_title" format="reference|string" />
</declare-styleable>
</resources>
attrs.xml里声明了一个item_view的自定义属性,在写xml布局时,可以直接引用的
<attr name="item_icon" format="reference" /> item_icon是一个引用类型,即 item_view:item_icon="@drawable/abc"
<pre name="code" class="html"><attr name="item_title" format="reference|string" /> item_title是一个引用类型,也可以直接用字符串,即 item_view:item_title="@string/app_name" 或 "测试"
声明了这些之后,开始写代码ItemView.java:
package com.ytmfdw.item;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
public class ItemView extends FrameLayout {
View view;
Context mContext;
public ItemView(Context context) {
super(context);
init(context);
}
public ItemView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
TypedArray localTypedArray = context.obtainStyledAttributes(attrs,
R.styleable.item_view);
Drawable drawable = localTypedArray.getDrawable(0);
String title = localTypedArray.getString(1);
setData(drawable, title);
localTypedArray.recycle();
}
private void init(Context context) {
mContext = context;
view = LayoutInflater.from(mContext).inflate(R.layout.item_tool, this,
true);
}
public void setData(Drawable drawable, String str) {
((ImageView) (view.findViewById(R.id.iv_icon)))
.setImageDrawable(drawable);
((TextView) (view.findViewById(R.id.tv_content))).setText(str);
}
}
代码非常少,只有一个要点:
public ItemView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
TypedArray localTypedArray = context.obtainStyledAttributes(attrs,
R.styleable.item_view);
Drawable drawable = localTypedArray.getDrawable(0);
String title = localTypedArray.getString(1);
setData(drawable, title);
localTypedArray.recycle();
}
在这个构造方法里,要对属性进行设置,
TypedArray localTypedArray = context.obtainStyledAttributes(attrs,
R.styleable.item_view);//这行代码的意思,就是读取xml布局文件中的item_view的属性
//这两行代码的意思是把读取出来的属性数组取出来,并分别赋值给对应的变量,需要注意的是
Drawable drawable = localTypedArray.getDrawable(0);
String title = localTypedArray.getString(1);
或许这样写更明了些:
Drawable drawable = localTypedArray
.getDrawable(R.styleable.item_view_item_icon);
String title = localTypedArray
.getString(R.styleable.item_view_item_title);
//获取到了值后,就给ItemView设置值
setData(drawable, title);
//完事后,记得把localTypedArray释放掉:
localTypedArray.recycle();
完了
使用也很方便,在activity_main.xml布局中这样写:
需要注意一点: 要加上一条:xmlns:item="http://schemas.android.com/apk/res-auto",这句的作用就是声明item属性来自于自定义的
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:item="http://schemas.android.com/apk/res-auto"
android:id="@+id/sv_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/wheat" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/bg_tool_content"
android:orientation="vertical"
android:padding="1dp" >
<com.ytmfdw.item.ItemView
android:id="@+id/item_qrcode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_item_bg_top_selector"
android:clickable="true"
item:item_icon="@drawable/qrcode_icon"
item:item_title="@string/item_qrcode" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/red" />
<com.ytmfdw.item.ItemView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_item_bg_normal_selector"
android:clickable="true"
item:item_icon="@drawable/app_loading0"
item:item_title="充数一" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/red" />
<com.ytmfdw.item.ItemView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_item_bg_normal_selector"
android:clickable="true"
item:item_icon="@drawable/app_loading0"
item:item_title="充数一" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/red" />
<com.ytmfdw.item.ItemView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_item_bg_normal_selector"
android:clickable="true"
item:item_icon="@drawable/app_loading0"
item:item_title="充数一" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/red" />
<com.ytmfdw.item.ItemView
android:id="@+id/item_barcode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_item_bg_bottom_selector"
android:clickable="true"
item:item_icon="@drawable/barcode_icon"
item:item_title="@string/item_barcode" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="5dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/bg_tool_content"
android:orientation="vertical"
android:padding="1dp" >
<com.ytmfdw.item.ItemView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_item_bg_top_selector"
android:clickable="true"
item:item_icon="@drawable/qrcode_icon"
item:item_title="@string/item_qrcode" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/red" />
<com.ytmfdw.item.ItemView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_item_bg_normal_selector"
android:clickable="true"
item:item_icon="@drawable/app_loading0"
item:item_title="充数一" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/red" />
<com.ytmfdw.item.ItemView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_item_bg_normal_selector"
android:clickable="true"
item:item_icon="@drawable/app_loading0"
item:item_title="充数一" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/red" />
<com.ytmfdw.item.ItemView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_item_bg_normal_selector"
android:clickable="true"
item:item_icon="@drawable/app_loading0"
item:item_title="充数一" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/red" />
<com.ytmfdw.item.ItemView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_item_bg_bottom_selector"
android:clickable="true"
item:item_icon="@drawable/barcode_icon"
item:item_title="@string/item_barcode" />
</LinearLayout>
</LinearLayout>
</ScrollView>
另外讲些题外话,像这样的布局,Linearlayout背景是个带弧的矩形,完全可以用xml的shap来写 bg_tool_content.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<corners android:radius="@dimen/item_arc" />
<solid android:color="#00000000" />
<stroke
android:width="1dp"
android:color="@color/red" />
</shape>
<corners android:radius="@dimen/item_arc" /> 表示弧角
<pre name="code" class="html"> <solid android:color="#00000000" /> 表示填空颜色,这里写的是透明的
<pre name="code" class="html"> <stroke
android:width="1dp"
android:color="@color/red" /> 这表示的是描边颜色
像这样写,不会有屏幕适配问题,怎么放大缩小都不会有问题,但会有另外一个问题:里面的item如果是方角,就会把外面的弧角给遮住,就不会有上图那样的效果了,我的解决方法是:
第一个item采用左上角右上角为弧角形,弧度与LinearLayout的四个弧度一致(这里还加了点击效果) button_item_bg_normal_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<corners android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp" android:topLeftRadius="@dimen/item_arc" android:topRightRadius="@dimen/item_arc" />
<solid android:color="@color/bisque" />
</shape></item>
<item><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<corners android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp" android:topLeftRadius="@dimen/item_arc" android:topRightRadius="@dimen/item_arc" />
<solid android:color="@color/beige" />
</shape></item>
</selector>
最后一个item采用左下角右下角为弧角形,弧度与LinearLayout的四个弧度一致 button_item_bg_bottom_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<corners android:bottomLeftRadius="@dimen/item_arc" android:bottomRightRadius="@dimen/item_arc" android:topLeftRadius="0dp" android:topRightRadius="0dp" />
<solid android:color="@color/bisque" />
</shape></item>
<item><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<corners android:bottomLeftRadius="@dimen/item_arc" android:bottomRightRadius="@dimen/item_arc" android:topLeftRadius="0dp" android:topRightRadius="0dp" />
<solid android:color="@color/beige" />
</shape></item>
</selector>
中间的项,就不用弧角形:button_item_bg_normal_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="@color/bisque" />
</shape></item>
<item><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="@color/beige" />
</shape></item>
</selector>
好了,基本完成,源码下载: 请点击