由于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是自己起的名字,你可以随便起。