自定控件,自定义View NameTextView



编写一个简单的控件:类似于TextView; 

不知道大家有没有做过常用文本编辑 例如 地址:浦东新区某某地点某某室; 有一大堆的 ":"    用到的地方多,还要写两个TextView 进行编写

简化一下 使用一个控件 NameTextView 可以设置 name  : content 两个属性  分别可以设置字体大小,字体颜色,中间的编剧等属性;

下面是自定控件的内容:

/**
 * Created by Administrator on 2016-12-25.
 */
public class NameTextView extends LinearLayout {
    public final static int TEXT_CONTENT_SIZE = 16;
    public final static int TEXT_NAME_SIZE = 14;
    public final static int TEXT_NAME_COLOR = Color.GRAY;
    public final static int CENTRE_PADDING = 6;
    private TextView tvName;
    private TextView tvContent;

    public NameTextView(Context context) {
        super(context);
        init(context, null, 0);
    }

    public NameTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public NameTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs,defStyleAttr);
    }

    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
        this.setOrientation(LinearLayout.HORIZONTAL);
        tvContent = new TextView(context);
        tvName = new TextView(context);

        this.addView(tvName);
        this.addView(tvContent);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT );
        tvContent.setLayoutParams(lp);
        if (attrs != null) {
			/*
			获得当前自定义属性集
			*/
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NameTextView,defStyleAttr,0);
			/*
			获得当前用户所添加的属性个数
			*/
            int count = a.getIndexCount();
			/*
			遍历用户所添加的自定义属性
			*/
            for (int i = 0; i < count; i++) {
				/*
				获得当前角标下的资源ID 就是当前添加属性的资源Id
				*/
                int attr = a.getIndex(i);
                switch (attr){
                    case R.styleable.NameTextView_content://添加的name:content内容
                        String content =a.getString(attr);
                        setContent(content);
                        break;
                    case R.styleable.NameTextView_name:
                        String name = a.getString(attr);
                        setName(name);
                        break;
                    case R.styleable.NameTextView_nameSize://设置name的大小
                        float nameSize = a.getDimension(attr, TEXT_NAME_SIZE);
                        tvName.setTextSize(TypedValue.COMPLEX_UNIT_PX,nameSize);
                        break;
                    case R.styleable.NameTextView_contentSize://设置content的字体大小
                        float contentSize = a.getDimension(attr,TEXT_CONTENT_SIZE);
                        tvContent.setTextSize(TypedValue.COMPLEX_UNIT_PX,contentSize);
                        break;
                    case R.styleable.NameTextView_contentColor:
                        int color = a.getColor(attr,TEXT_NAME_COLOR);
                        setContentColor(color);
                        break;
                    case R.styleable.NameTextView_nameColor:
                        int nameColor = a.getColor(attr,TEXT_NAME_COLOR);
                        setNameColor(nameColor);
                        break;
                    case R.styleable.NameTextView_centrePadding://设置name: "padding"  content 设置之间padding的距离
                        float d = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,CENTRE_PADDING,getResources().getDisplayMetrics());
                        float padding = a.getDimension(attr,d);
                        setCentrePadding((int) padding);
                        break;
                    case R.styleable.NameTextView_contentMaxLine://设置content内容的最大行数
                        int maxLine = a.getInteger(attr,1);
                        setContentMaxLine(maxLine);
                        break;
                }
            }
            a.recycle();
        }
    }
    public void setCentrePadding(int padding){
        tvName.setPadding(0,0,padding,0);
    }
    public void setContentColor(int color){
        tvContent.setTextColor(color);
    }
    public void setNameColor(int color){
        tvName.setTextColor(color);
    }

    public void setContentMaxLine(int maxLine){
        tvContent.setMaxLines(maxLine);
    }
    public void setContentSize(int size) {
        tvContent.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
    }

    public void setName(String name) {
        tvName.setText(name + ":");
    }

    public void setContent(String content) {
        tvContent.setText(content);
    }
}

下面是创建资源文件创建路径

src\main\res\values ---->创建attr.xml文件

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="NameTextView">
        <attr name="name" format="string"/>
        <attr name="content" format="string|reference"/>
        <attr name="nameSize" format="dimension"/>
        <attr name="contentSize" format="dimension"/>
        <attr name="nameColor"  format="color|reference"/>
        <attr name="contentColor" format="color|reference"/>
        <attr name="centrePadding" format="dimension"/>
        <attr name="contentMaxLine" format="integer"/>
    </declare-styleable>
</resources>

format中的属性:

2. color:颜色值
<declare-styleable name = "名称">
<attr name = "textColor" format = "color" />
</declare-styleable>
3. boolean:布尔值
<declare-styleable name = "名称">
<attr name = "focusable" format = "boolean" />
</declare-styleable>
4. dimension:尺寸值。注意,这里如果是dp那就会做像素转换
<declare-styleable name = "名称">
<attr name = "layout_width" format = "dimension" />
</declare-styleable>
5. float:浮点值。
6. integer:整型值。
7. string:字符串
8. fraction:百分数。
9. enum:枚举值
10. flag:是自己定义的,类似于 android:gravity="top",就是里面对应了自己的属性值。
11. reference|color:颜色的资源文件。
12.reference|boolean:布尔值的资源文件


下面是在布局中的调用NameTextView:

<!--创建出来后设置为闭环,在内容区域一定要加入appNs 导入  这样才能使用自定义属性 使用app来装饰 -->
<ui.view.NameTextView 
		xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/ntv_userNumber"
        app:name="身份号"
		app:contentSize = "16sp"
		app:contentColor = "@color/red" 
		app:nameSize = "14sp"
		app:nameColor = "@color/red"
		app:contentMaxLine = "1"
        android:layout_marginTop="@dimen/x6"
        app:centrePadding="6dp"
        app:content="230182************"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

哦哦。。排版出现问题了。可以直接将代码 拷贝到自己的工程 中 在格式化一下就好了。

在自己的项目中,把经常使用的复杂布局尽量 编写成自定控件,可变的,这样对Acitvity 中编写代码数量减少,而且服用性高;

熟能生巧,得常用,慢慢的你会编写一些自定义View 里面 用Pain画笔画出来的,像进度条 、钟表等一些列的控件;

祝你生活愉快,编写工程无bug。




版权声明:本文为Mr_QiuL原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。