Android 自定义组合控件

来源:互联网 发布:万得for mac 编辑:程序博客网 时间:2024/06/06 21:05

基本使用

用一个带有清除按钮和EditText的LinearLayout作为案例。

1,定义布局文件
<?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="match_parent"    android:orientation="horizontal"    android:gravity="center">    <EditText        android:id="@+id/et"        android:layout_width="0dp"        android:layout_weight="1"        android:layout_height="wrap_content"        android:hint="@string/auto_delete_edittext_hint" />    <ImageView        android:id="@+id/iv"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:contentDescription="@string/auto_delete_edittext_hint"        android:src="@android:drawable/ic_delete" /></LinearLayout>
2,定义组合控件类

直接继承一个ViewGroup即可,此处用的是LinearLayout

public class AutoDeleteEditText extends LinearLayout {    private EditText mEditText;    private ImageView mImageView;    public AutoDeleteEditText(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    public AutoDeleteEditText(Context context, AttributeSet attrs) {        super(context, attrs);        LayoutInflater.from(context).inflate(R.layout.view_auto_delete_edittext, this, true);        mEditText = (EditText) findViewById(R.id.et);        mEditText.addTextChangedListener(mWatcher);        mImageView = (ImageView) findViewById(R.id.iv);        mImageView.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                mEditText.setText("");            }        });    }    public AutoDeleteEditText(Context context) {        super(context);    }    public void setDeleteIcon(int id){        mImageView.setImageResource(id);    }    private TextWatcher mWatcher = new TextWatcher() {        @Override        public void beforeTextChanged(CharSequence s, int start, int count, int after) {        }        @Override        public void onTextChanged(CharSequence s, int start, int before, int count) {        }        @Override        public void afterTextChanged(Editable s) {            String content = s.toString();            if(TextUtils.isEmpty(content)){                mImageView.setVisibility(View.GONE);            } else {                mImageView.setVisibility(View.VISIBLE);            }        }    };}
3,在布局中引用

MainActivity的布局如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.example.lightmoon.learn.OwnFixedActivity"    >    <com.example.lightmoon.learn.views.AutoDeleteEditText        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/fixed_widget"        /></RelativeLayout>

完成,这样就可以将一些相同操作的组件封装起来,直接在一个类中定义方法。


自定义属性

1,定义attrs.xml

在values下新建attrs.xml文件(如果有则修改)

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="AutoDeleteEditText">        <attr name="et_hint" format="string"/>    </declare-styleable></resources>

各个name都是自定的

2,布局中引用

将上述的MainActivity布局改为如下内容

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    xmlns:light="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.example.lightmoon.learn.OwnFixedActivity"    >    <com.example.lightmoon.learn.views.AutoDeleteEditText        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/fixed_widget"        light:et_hint="@string/test_hint"/></RelativeLayout>

增加语句:

  1. xmlns:light="http://schemas.android.com/apk/res-auto" 其中xmlns:light中的light为自定义名称,与下面2中引用一致即可,url为gradle规定的url格式,如果不是gradle编译,则应该为http://schemas.android.com/apk/res/组件包名 (非gradle未测试)
  2. light:et_hint="@string/test_hint" light: 为上面的xmlns后面的名称,et_hint为attrs中定义的属性。
3,在自定义类中引用

在构造方法(为了能直接引用到AttributeSet) 中增加如下语句

        TypedArray ownAttrs = context.obtainStyledAttributes(attrs,             R.styleable.AutoDeleteEditText);  // 获取参数        String etHint = ownAttrs.getString(R.styleable.            AutoDeleteEditText_et_hint); // 获取自定义参数值        mEditText.setHint(etHint); // 使用        ownAttrs.recycle(); // 回收资源

这样自定义属性就起作用了。

0 0
原创粉丝点击