Android中自定义属性attrs.xml、TypedArray的使用

由于Android系统给TextView、EditText等空间提供的drawableLeft的属性无法设置Gravity,系统默认居中,这样无法到达项目中需要的效果。

下面这张图是用的系统的drawableLeft属性所展现出的效果


这样是无法进行调整图片位置的,比如我的项目需求是图片居上的


如图,如果是这样的系统的drawableLeft属性是无法满足的。

如果要实现这样的效果可以加一个Imaview控件,但有时候还需要再外面在套一层LinearLayout或RelativeLayout。

当然还有另外一种方法:就是Android中自定义属性。


上图就是我们想要的Android中自定义属性的使用方式。

废话不多说了,上代码:

一、首先在values文件夹下创建一个attrs.xml文件,来设置自定义属性

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyTextViewDrawable">
        <attr name="leftResourceId" format="reference"></attr>//左侧图片
        <attr name="leftGravity">//图片Gravity
            <flag name="leftTop" value="0" />
            <flag name="leftBottom" value="1" />
            <flag name="leftCenter" value="2" />
        </attr>
        <attr name="text" format="string"></attr>
        <attr name="textGravity">//文字Gravity
            <flag name="textLeftTop" value="0"/>
            <flag name="textLeftBottom" value="1"/>
            <flag name="textRightTop" value="2"/>
            <flag name="textRightBottom" value="3"/>
            <flag name="textCenter" value="4" />
            <flag name="textCenterHorizontal" value="5" />
            <flag name="textCenterVertical" value="6" />
        </attr>
    </declare-styleable>
</resources>
这里要先说明下 format="reference"里面format的值

1. reference:参考某一资源ID。

(1)属性定义:

<declare-styleable name = "名称">

<attr name = "background" format = "reference" />

</declare-styleable>

(2)属性使用:

<ImageView

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

android:background = "@drawable/图片ID"

/>


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:尺寸值。


<declare-styleable name = "名称">

<attr name = "layout_width" format = "dimension" />

</declare-styleable>


5. float:浮点值。


6. integer:整型值。


7. string:字符串


8. fraction:百分数。


9. enum:枚举值


10. flag:位或运算


注意:

属性定义时可以指定多种类型值。

(1)属性定义:

<declare-styleable name = "名称">

<attr name = "background" format = "reference|color" />

</declare-styleable>

(2)属性使用:

<ImageView

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

android:background = "@drawable/图片ID|#000000"

/>


二、创建一个MyTextView类,继承RelativeLayout

package xu.dyso.com.mytextview;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
 * Created by xu on 2017/3/2.
 */

public class MyTextView extends RelativeLayout {

    /**
     * 图片资源ID
     */
    private int imageResourceId;
    /**
     * 图片的Gravity
     */
    private int leftGravity;
    /**
     * 文字的内容
     */
    private String text="";
    /**
     * 文字的Gravity
     */
    private int textGravity;
    /**
     * ImageView控件
     */
    private ImageView leftView;
    /**
     * 图片控件
     */
    private TextView textView;
    /**
     * 图片和文字的LayoutParams属性
     */
    private LayoutParams leftParams,textParams;

    private Context mContext;

    public MyTextView(Context context) {
        super(context);
        this.mContext = context;
        initView(context, null);
    }

    public MyTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
        initView(context, attrs);
    }

    public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        initView(context, attrs);
    }

    /**
     * 初始化
     * @param context
     * @param attrs
     */
    private void initView(Context context, AttributeSet attrs) {
        /**
         * 通过TypeArray获取到attrs里的自定义属性
         */
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyTextViewDrawable);
        /**
         * 图片资源ID赋值
         */
        imageResourceId = typedArray.getResourceId(R.styleable.TextDrawable_leftResourceId, 0);
        leftView = new ImageView(context);
        /**
         * 图片属性初始化
         */
        leftParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        /**
         * 设置图片位于父控件里面偏左侧
         */
        leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT,RelativeLayout.TRUE);
        /**
         * 图片Gravity赋值,默认居中
         */
        leftGravity = typedArray.getInteger(R.styleable.TextDrawable_leftGravity, 2);
        switch (leftGravity){
            case 0://左上
                leftParams.addRule(RelativeLayout.ALIGN_PARENT_TOP,RelativeLayout.TRUE);
                break;
            case 1://左下
                leftParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
                break;
            case 2://左中
                leftParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
                break;
            default:
                leftParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
                break;
        }
        /**
         * 给该控件设置ID值,后面用来设置第二个控件位置
         */
        leftView.setId(R.id.left_iv);
        addView(leftView,leftParams);

        if (imageResourceId > 0) {
            leftView.setImageResource(imageResourceId);
        }

        textView=new TextView(context);
        /**
         * 文字属性初始化
         */
        textParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        /**
         * 文字位置设置,位于leftView右侧
         */
        textParams.addRule(RelativeLayout.RIGHT_OF,leftView.getId());
        /**
         * 文字内容赋值
         */
        text=typedArray.getString(R.styleable.TextDrawable_text);
        textView.setText(text);
        /**
         * 文字Gravity赋值,默认居中
         */
        textGravity=typedArray.getInteger(R.styleable.TextDrawable_textGravity,4);
        /**
         * 因为textParams设置的属性是LayoutParams.MATCH_PARENT,所以TextView的Gravity设置只好用textView.setGravity(int gravity);
         * 当然textParams也可以设置为LayoutParams.WRAP_CONTENT,然后通过textParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);这样来设置
         */
        switch (textGravity){
            case 0:
                textView.setGravity(Gravity.TOP);
                break;
            case 1:
                textView.setGravity(Gravity.BOTTOM);
                break;
            case 2:
                textView.setGravity(Gravity.TOP|Gravity.RIGHT);
                break;
            case 3:
                textView.setGravity(Gravity.BOTTOM|Gravity.RIGHT);
                break;
            case 4:
                textView.setGravity(Gravity.CENTER);
                break;
            case 5:
                textView.setGravity(Gravity.CENTER_HORIZONTAL);
                break;
            case 6:
                textView.setGravity(Gravity.CENTER_VERTICAL);
                break;
            default:
                textView.setGravity(Gravity.CENTER);
                break;
        }
        addView(textView,textParams);
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}
这里要注意下

leftView.setId(int ID)的时候,在Android Studio中不能像Eclipse中那样直接leftView.setId(1);

而是要在values文件夹下新建一个ids.xml文件

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="left_iv" type="id">1</item>
</resources>
否则会空指针错误。

三、在Layout界面中引用自定义属性

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:mytextview="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <xu.dyso.com.mytextview.MyTextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        mytextview:leftResourceId="@mipmap/iv_remark"
        mytextview:leftGravity="leftTop"
        mytextview:text="这是一段\n测试文字\n这是一段\n测试文字"
        mytextview:textGravity="textLeftTop"/>
</LinearLayout>
注意别忘了在根节点添加
xmlns:mytextview="http://schemas.android.com/apk/res-auto"

这个mytextview是自己起的名字,你可以随便起。


源码下载


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值