简介:
在平常应用的开发的过程中,系统提供的一些控件是不能够满足我们的需求的。在这种情况下,我们可以自定义自己的控件,达到我们需要的效果。
1、继承其它控件类(EditText、Button)
2、 组合方式。当前控件类从容器类继承,并将若干个控件添加到当前的
容器中。
3、 绘制控件,也就是控件类从View继承,并在onDraw方法中从零绘制
控件。例如,TextView。
下面,给出几个例子实现自定义控件的例子:
1、不带命名空间,直接读取设定的xml上面的参数值
public class LIView extends LinearLayout {
String labText;
Bitmap bitmap;
public LIView(Context context, AttributeSet attrs) {
super(context, attrs);
int resourseId=attrs.getAttributeResourceValue(null,"labText",0);
if (0 == resourseId){
// 设置的值是直接存在于使用的地方 如 labText='我是文字'
labText=attrs.getAttributeValue(null,"labText");
}else {
//设置的值是在 value的xml文件中
labText=getResources().getString(resourseId);
}
if (labText == null){
throw new RuntimeException("必须设置labText 参数");
}
resourseId=attrs.getAttributeResourceValue(null,"ico",0);
Log.d("NEW","resourseId "+resourseId);
if (0 != resourseId){
Log.d(this.getClass()+"","resourseId "+resourseId);
bitmap= BitmapFactory.decodeResource(getResources(),resourseId);
}
LayoutInflater inflater;
inflater= (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout linearLayout= (LinearLayout) inflater.inflate(R.layout.layoutitem,this);
TextView textView= (TextView) findViewById(R.id.textview1);
ImageView imageView= (ImageView) findViewById(R.id.img);
textView.setText(labText);
if (null != bitmap){
imageView.setImageBitmap(bitmap);
}
}
}
2、带命名空间,读取xml上面的参数的值。
public class LIViewWithSpaceName extends LinearLayout {
String nameSpace="http://testNamespace";
String labText;
Bitmap bitmap;
public LIViewWithSpaceName(Context context, AttributeSet attrs) {
super(context, attrs);
int resourseId=attrs.getAttributeResourceValue(nameSpace,"labText",0);
if (0 == resourseId){
// 设置的值是直接存在于使用的地方 如 labText='我是文字'
labText=attrs.getAttributeValue(nameSpace,"labText");
}else {
//设置的值是在 value的xml文件中
labText=getResources().getString(resourseId);
}
if (labText == null){
throw new RuntimeException("必须设置labText 参数");
}
resourseId=attrs.getAttributeResourceValue(nameSpace, "ico", 0);
Log.d("NEW","resourseId "+resourseId);
if (0 != resourseId){
Log.d(this.getClass()+"","resourseId "+resourseId);
bitmap= BitmapFactory.decodeResource(getResources(),resourseId);
}
LayoutInflater inflater;
inflater= (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout linearLayout= (LinearLayout) inflater.inflate(R.layout.layoutitem,this);
TextView textView= (TextView) findViewById(R.id.textview1);
ImageView imageView= (ImageView) findViewById(R.id.img);
textView.setText(labText);
if (null != bitmap){
imageView.setImageBitmap(bitmap);
}
}
}
3、标准的控件的定义的形式
public class LIViewWithSpaceNameAndStandrd extends LinearLayout {
String labText;
Bitmap bitmap;
public LIViewWithSpaceNameAndStandrd(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray;
/**
* 将布局中的值都封装在 TypedArray
* 获取布局中xml设定的值:
* 1、通过typedArray.getResourceId 获取id
* 2、通过这个 typedArray.getXXX(id) 获取所需要的值
*/
typedArray = context.obtainStyledAttributes(attrs,R.styleable.LIViewWithSpaceNameAndStandrd);
int resourseId;
resourseId=typedArray.getResourceId(R.styleable.LIViewWithSpaceNameAndStandrd_labText, -1);
if (resourseId!=-1) {
labText=typedArray.getString(resourseId);
}
if (labText == null){
throw new RuntimeException("必须设置labText 参数");
}
resourseId=typedArray.getResourceId(R.styleable.LIViewWithSpaceNameAndStandrd_ico, 0);
System.out.println(" "+R.styleable.LIViewWithSpaceNameAndStandrd_ico+" "+resourseId);
Bitmap bitmap = null;
if (0 != resourseId) {
bitmap=BitmapFactory.decodeResource(getResources(), resourseId);
}
LayoutInflater inflater;
inflater= (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout linearLayout= (LinearLayout) inflater.inflate(R.layout.layoutitem,this);
TextView textView= (TextView) findViewById(R.id.textview1);
ImageView imageView= (ImageView) findViewById(R.id.img);
textView.setText(labText);
if (null != bitmap){
imageView.setImageBitmap(bitmap);
}
}
}
在xml的中命名空间:
xmlns:app="http://schemas.android.com/apk/res/com.example.mydemo928"
在后面的包名必须的命名成R 中的包名。
<declare-styleable name="LIViewWithSpaceNameAndStandrd">
<attr name="labText" format="string"></attr>
<attr name="ico" format="reference"></attr>
</declare-styleable>
因为xml 声明的attr 好与之对应。
Mian XML :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res/com.example.mydemo928"
xmlns:myspacename="http://testNamespace"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<com.example.mydemo928.LIView
android:layout_width="match_parent"
android:layout_height="wrap_content"
ico="@drawable/ic_launcher"
labText="我是文字" >
</com.example.mydemo928.LIView>
<com.example.mydemo928.LIViewWithSpaceName
android:layout_width="match_parent"
android:layout_height="wrap_content"
myspacename:ico="@drawable/ic_launcher"
myspacename:labText="我是文字2" >
</com.example.mydemo928.LIViewWithSpaceName>
<com.example.mydemo928.LIViewWithSpaceNameAndStandrd
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:ico="@drawable/ic_launcher"
app:labText="我是文字3" >
</com.example.mydemo928.LIViewWithSpaceNameAndStandrd>
截图:
源代码地址:
http://git.oschina.net/wbl/DefineView
参考:
- android自定义控件(一) 官方文档的翻译 http://blog.csdn.net/ethan_xue/article/details/7313575
- android自定义控件(二) 入门,继承View http://blog.csdn.net/ethan_xue/article/details/7313788
- android自定义控件(三) 自定义属性 http://blog.csdn.net/ethan_xue/article/details/7314907
- eoe的自定控件课程