自定义组合控件

来源:互联网 发布:微博刷粉丝软件安卓版 编辑:程序博客网 时间:2024/05/21 14:04

先上效果图:


首先说明下,实现这种效果有很多种方式,就是用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>

好了,基本完成,源码下载:请点击



0 0