当Android系统提供的控件不能满足我们的需求时,这时可以通过自定义一个控件来实现想要的效果。这里有三种方式:
(1)继承其他控件类(Button、EidtText等);
(2)组合方式。当前控件类从容器类(ViewGroup,一般使用LinearLayout等布局)继承,并将若干个控件添加到当前的容器类中;
(3)绘制控件。控件类直接继承View,并在onDraw()方法中绘制控件,例如TextView。
这里来看一下如何自定义一个组合控件,如果要实现一个EditText和TextView的组合控件,主要功能是当点击这个控件后,在EditText输入的字符串会显示到TextView中。基本实现方法是:
(1)在控件类中定义EditText和TextView类型的变量
(2)在控件类构造方法中获取控件的实例,若在布局文件中创建的控件则加载该布局文件。
(3)根据各控件的属性来设置属性值。
注意:编写控件类时应将可能变化的值通过属性设置,而不是直接固化在 控件类中,比如TextView中的值可能会变化,所以应该通过自定义一个方法,在方法中调用TextView的setText()方法,通过参数可以在自定义控件调用该方法时把所设置的值传进去。
实践部分
1、首先创建一个新的工程,然后新建一个TextEdit类继承LinearLayout,下面是代码:
package com.wk.designUI;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.example.asus.designUI.R;
/**
* Created by wk on 2017/4/8.
*/
public class TextEdit extends LinearLayout {
private TextView tv;
private EditText et;
public TextEdit(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.item,this,true);
tv = (TextView) findViewById(R.id.tv);
et = (EditText) findViewById(R.id.et);
}
public void setEditText(){
String str = et.getText().toString();
tv.setText(str);
}
}
构造方法中获取各控件的实例,以及加载事先编写好的布局文件,该布局文件主要创建控件并设置其位置,下面是布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30sp"
/>
<EditText
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
创建好后,然后在MainActivity中引用该自定义控件
package com.example.asus.designUI;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import com.wk.designUI.TextEdit;
public class MainActivity extends AppCompatActivity {
private TextEdit te;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
te = (TextEdit) findViewById(R.id.te);
te.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
te.setEditText();
}
});
}
}
为该控件设置一个监听器,点击后后将EditText内容赋给TextView,下面是主布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
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.asus.designUI.MainActivity">
<com.wk.designUI.TextEdit
android:id="@+id/te"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.wk.designUI.TextEdit>
</LinearLayout>
下面是效果
说明
这里是通过直接获取资源来定义控件的,当然还可以通过集成View来重写其onDraw()方法来进行绘制控件,以及通过attr.xml自定义新控件的属性,在代码中解析出来然后加入相应的逻辑,即可实现不同的效果。