zoukankan      html  css  js  c++  java
  • Android自定义组合控件

    目标:实现textview和ImageButton组合,可以通过Xml设置自定义控件的属性。
      1.控件布局:以Linearlayout为根布局,一个TextView,一个ImageButton。
      
    Xml代码  收藏代码
    1 < ?xml version="1.0" encoding="utf-8"?>  
    2    < LinearLayout xmlns:Android="http://schemas.android.com/apk/res/android"  
    3    android:layout_width="fill_parent" android:layout_height="fill_parent"  
    4    android:gravity="center_vertical">  
    5    < TextView android:layout_height="wrap_content" android:id="@+id/text1"  
    6    android:layout_width="wrap_content">< /TextView>  
    7    < ImageButton android:layout_width="wrap_content"  
    8    android:layout_height="wrap_content" android:id="@+id/btn1">< /ImageButton>  
    9    < /LinearLayout> 

      2.自定义控件代码,从LinearLayout继承:
      
    Java代码  收藏代码
        public class ImageBtnWithText extends LinearLayout {  
         }  
          public ImageBtnWithText(Context context) {  
          this(context, null);  
          }  
           
          public ImageBtnWithText(Context context, AttributeSet attrs) {  
          super(context, attrs);  
          LayoutInflater.from(context).inflate(R.layout.imagebtn_with_text, thistrue);  
            }  
          } 

      在构造函数中将Xml中定义的布局解析出来。
      3.在主界面布局xml中使用自定义控件:
      
    Xml代码  收藏代码
    < com.demo.widget2.ImageBtnWithText  
       
    android:id="@+id/widget"  
       android:layout_width
    ="fill_parent"  
       android:layout_height
    ="fill_parent" />    

      即使用完整的自定义控件类路径:com.demo.widget2.ImageBtnWithText定义一个元素。
      运行可以看到控件已经能够被加载到界面上。
      4.给按钮设置图片和文本
      如果图片是固定不变的,那么直接在控件布局中设置ImageButton的src属性即可。
      4.1通过Java代码设置,在控件代码中提供函数接口:
      
    Java代码  收藏代码
    public void setButtonImageResource(int resId) {  
       mBtn.setImageResource(resId);  
       }  
        
       public void setTextViewText(String text) {  
       mTv.setText(text);  
       }  
      

      然后再在主界面的onCreate()通过函数调用设置即可。
      4.2通过Xml设置属性
      4.2.1首先定义Xml可以设置的属性集合,在values下创建attrs.xml,文件名可随意,一般都叫attrs.xml
      
    Xml代码  收藏代码
    < ?xml version="1.0" encoding="utf-8"?>  
      < resources>  
       < declare-styleable name="ImageBtnWithText">  
       < attr name="android:text"/>  
       < attr name="android:src"/>  
       < /declare-styleable>  
       < /resources>   

      属性集合名字:ImageBtnWithText,自己可根据实际来定义;
      集合中包含的属性列表,每行一个属性。
      4.2.2修改自定义控件实现代码,以获取xml中定义的属性
      
    Java代码  收藏代码
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ImageBtnWithText);  
      CharSequence text = a.getText(R.styleable.ImageBtnWithText_android_text);  
      if(text != null) mTv.setText(text);  
      Drawable drawable = a.getDrawable(R.styleable.ImageBtnWithText_android_src);  
      if(drawable != null) mBtn.setImageDrawable(drawable);  
      a.recycle();

      首先通过context.obtainStyledAttributes获得所有属性数组;
      然后通过TypedArray类的getXXXX()系列接口获得相应的值。
      4.2.3在主界面布局中设置自定义控件的属
      android:text="ABC" android:src="@drawable/icon
      4.3自定义名称属性:
      在4.2中使用的属性名是Android系统命名空间的,都以android开头,比如android:text等。
    实际开发中会自定义一些属性名,这些属性名仍然定义在4.2.1提到的attrs.xml中:
      4.3.1定义属性名
      
    Xml代码  收藏代码
    1. < attr name="appendText" format="string"/>
       

      和直接使用系统的attr不同的是要增加一个format属性,说明此属性是什么格式的。format可选项可参见注1
      4.3.2使用自定义属性
      
    Xml代码  收藏代码
    < ?xml version="1.0" encoding="utf-8"?>  
       < LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
       xmlns:myspace
    ="http://schemas.android.com/apk/res/com.demo.customwidget"  
       android:orientation
    ="vertical" android:layout_width="fill_parent"  
       android:layout_height
    ="fill_parent">  
       < com.demo.widget2.ImageBtnWithText  
       
    android:text="ABC" android:src="@drawable/icon" android:id="@+id/widget"  
       android:layout_width
    ="fill_parent" android:layout_gravity="center"  
       android:layout_height
    ="fill_parent" myspace:appendText="123456">  
       < /com.demo.widget2.ImageBtnWithText>  
       < /LinearLayout> 
    1.     

      直接在主布局文件中使用此属性appendText="abc"是不会设置生效的,而是要在主布局xml中定义一个xml命名空间:
    xmlns:myspace="http://schemas.android.com/apk/res/com.demo.customwidget"
      命名空间的名字可以自己随便定义,此处为myspace,即xmlns:myspace;
      后面的地址则有限制,其开始必须为:"http://schemas.android.com/apk/res/",后面则是包名com.demo.customwidget,
      此处的包名与AndroidManifest.xml中< manifest>节点的属性package="com.demo.customwidget"一致,不是自定义控件Java代码所在的包,当然简单的程序自定义控件Java代码也一般在此包内。
      注1:format可选项
      "reference" //引用
      "color" //颜色
      "boolean" //布尔值
      "dimension" //尺寸值
      "float" //浮点值
      "integer" //整型值
      "string" //字符串
      "fraction" //百分数,比如200%
      枚举值,格式如下:
      < attr name="orientation">
      < enum name="horizontal" value="0" />
      < enum name="vertical" value="1" />
      < /attr>
      xml中使用时:
      android:orientation = "vertical"
      标志位,位或运算,格式如下:
      < attr name="windowSoftInputMode">
      < flag name = "stateUnspecified" value = "0" />
      < flag name = "stateUnchanged" value = "1" />
      < flag name = "stateHidden" value = "2" />
      < flag name = "stateAlwaysHidden" value = "3" />
      < flag name = "stateVisible" value = "4" />
      < flag name = "stateAlwaysVisible" value = "5" />
      < flag name = "adjustUnspecified" value = "0x00" />
      < flag name = "adjustResize" value = "0x10" />
      < flag name = "adjustPan" value = "0x20" />
      < flag name = "adjustNothing" value = "0x30" />
      < /attr>
      xml中使用时:
      android:windowSoftInputMode = "stateUnspecified | stateUnchanged | stateHidden">
      另外属性定义时可以指定多种类型值,比如:
      < attr name = "background" format = "reference|color" />
      xml中使用时:
      android:background = "@drawable/图片ID|#00FF00"


    最后来个完整实例:
    Java代码  收藏代码
        import android.content.Context;  
        import android.content.res.TypedArray;  
        import android.util.AttributeSet;  
        import android.view.LayoutInflater;  
        import android.view.View;  
        import android.widget.ImageButton;  
        import android.widget.LinearLayout;  
        import android.widget.ProgressBar;  
          
        public class Meter extends LinearLayout {  
            private int max=100;  
            private int incrAmount=1;  
            private int decrAmount=-1;  
            private ProgressBar bar=null;  
            public Meter(final Context ctxt, AttributeSet attrs) {  
                super(ctxt, attrs);  
                  
                this.setOrientation(HORIZONTAL);  
                  
                TypedArray a=ctxt.obtainStyledAttributes(attrs,R.styleable.Meter);  
                  
                //获取里面属性用 "名字_ 属性" 连接起来  
                max=a.getInt(R.styleable.Meter_max, 100);  
                incrAmount=a.getInt(R.styleable.Meter_incr, 1);  
                decrAmount=-1*a.getInt(R.styleable.Meter_decr, 1);  
                  
                a.recycle();  
            }  
            //当View中所有的子控件 均被映射成xml后触发  
            @Override  
            protected void onFinishInflate() {  
                super.onFinishInflate();  
                  
        //      ((Activity)getContext()).getLayoutInflater().inflate(R.layout.meter, this);  
                  
                LayoutInflater.from(getContext()).inflate(R.layout.meter, this);  
                  
                bar=(ProgressBar)findViewById(R.id.bar);  
                bar.setMax(max);  
                  
                ImageButton btn=(ImageButton)findViewById(R.id.incr);  
                btn.setOnClickListener(new View.OnClickListener() {  
                    public void onClick(View v) {  
                        bar.incrementProgressBy(incrAmount);  
                    }  
                });  
                  
                btn=(ImageButton)findViewById(R.id.decr);  
                btn.setOnClickListener(new View.OnClickListener() {  
                    public void onClick(View v) {  
                        bar.incrementProgressBy(decrAmount);  
                    }  
                });  
        //      this.addView(view);//不需要add,默认已经add了  
            }  
        } 

    attrs.xml:
    Xml代码  收藏代码
        <?xml version="1.0" encoding="utf-8"?>  
        <resources>  
            <declare-styleable name="Meter">  
                <attr name="max" format="integer" />  
                <attr name="incr" format="integer" />  
                <attr name="decr" format="integer" />  
            </declare-styleable>  
        </resources> 

    meter.xml文件:
    Xml代码  收藏代码
        <?xml version="1.0" encoding="utf-8"?>  
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
            android:orientation
    ="horizontal"  
            android:layout_width
    ="fill_parent"  
            android:layout_height
    ="wrap_content"  
        
    >  
            <ImageButton android:id="@+id/decr"  
                android:layout_height
    ="wrap_content"  
                android:layout_width
    ="wrap_content"  
                android:scaleType
    ="fitCenter"  
                android:src
    ="@drawable/arrow_down"  
            
    />  
            <ProgressBar android:id="@+id/bar"  
                style
    ="?android:attr/progressBarStyleHorizontal"  
                android:layout_width
    ="wrap_content"  
                android:layout_height
    ="wrap_content"  
                android:layout_weight
    ="1"  
                android:layout_gravity
    ="center_vertical"  
            
    />  
            <ImageButton android:id="@+id/incr"  
                android:layout_height
    ="wrap_content"  
                android:layout_width
    ="wrap_content"  
                android:scaleType
    ="fitCenter"  
                android:src
    ="@drawable/arrow_up"  
            
    />  
        </LinearLayout> 

    使用:
    Java代码  收藏代码
        @Override  
            public void onCreate(Bundle savedInstanceState) {  
                super.onCreate(savedInstanceState);  
                setContentView(R.layout.main);  
            } 

    main.xml:
    Xml代码  收藏代码
        <?xml version="1.0" encoding="utf-8"?>  
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
            xmlns:app
    ="http://schemas.android.com/apk/res/com.ql.app"  
            android:orientation
    ="horizontal"  
            android:layout_width
    ="fill_parent"  
            android:layout_height
    ="wrap_content"  
            
    >  
            <com.ql.app.Meter  
                
    android:id="@+id/meter"  
                android:layout_width
    ="fill_parent"  
                android:layout_height
    ="wrap_content"  
                app:max
    ="100"  
                app:incr
    ="5"  
                app:decr
    ="5"  
            
    />  
        </LinearLayout> 


    Trackback:http://gundumw100.iteye.com/blog/1040917

  • 相关阅读:
    Coded UI Test(二)创建一个Coded UI Test
    Coded UI Test(一)概述
    面向接口编程思想与实现可维护的代码 (一)
    KMP算法字符串模式匹配算法
    新的博客,新的起点
    第十三章:字符串 《Thinking in java》学习笔记
    稀疏矩阵三元组表来压缩存储及转置
    eclipse svn的使用+小组开发
    第十一章:持有对象 《Thinking in java》学习笔记
    双端队列(deque)课堂跳了的内容
  • 原文地址:https://www.cnblogs.com/hdjjun/p/2209467.html
Copyright © 2011-2022 走看看