Android 自定义控件

来源:互联网 发布:淘宝仿真娃娃 编辑:程序博客网 时间:2024/05/17 09:01

简介:

在平常应用的开发的过程中,系统提供的一些控件是不能够满足我们的需求的。在这种情况下,我们可以自定义自己的控件,达到我们需要的效果。
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的自定控件课程