Android学习笔记(六) 自定义控件

  自定义控件则需继承相应的控件类,控件的基类则是View,如果只是开发普通的控件,只继承View类就可以了。控件的构造函数的声明如下

View(Context context)
View(Context context, AttributeSet attrs)
View(Context context, AttributeSet attrs, int defStyle)

定义控件对本人来说要么是定义了控件的视图,要么是外放了控件的属性,要么是外放控件的方法。

 

创建属性 方式1

  布局文件的内容如下

      <com.example.testandroidproject.MyTestControl
        android:id="@+id/con1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        Text="@string/_1234565"
           />

 

 控件名要是类的全名,属性只单纯的Text则可,到类文件的构造函数里面使用

int textId = attrs.getAttributeResourceValue(null, "Text",0);
mtext = context.getResources().getText(textId).toString();

则可以获取布局文件的Text的值,因为这里是从资源里面的值,所以布局文件只能填@string/的值

 

创建属性 方式2

  在res/values的文件夹下面添加一个文件attrs.xml,内容如下

<resources >
<declare-styleable name="MyTestUserControl">
   <attr name="text" format="string" />         
   <attr name="textColor" format="color"  />
</declare-styleable>  
</resources>

在布局文件中需要引用新的命名空间

xmlns:app=http://schemas.android.com/apk/res/com.example.testandroidproject

其实后面那段就是项目的包名

app就是新的命名空间的名称,其实android都是一个命名空间而已,那么控件属性就可以用这种形式设置

      <com.example.testandroidproject.MyTestControl
        android:id="@+id/con1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        app:text="@string/_1234565"
        app:textColor="#0000ff"
           />

然后在控件类的构造函数里面加入以下代码

复制代码
        int resourceId = 0;
        TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.MyTestUserControl);

        int N = typedArray.getIndexCount();

        for (int i = 0; i < N; i++) {

            int attr = typedArray.getIndex(i);

            switch (attr) {

            case R.styleable.MyTestUserControl_text:
                mtext = typedArray.getString(
                        R.styleable.MyTestUserControl_text);
                mtext=typedArray.getString(attr);

                break;
            case R.styleable.MyTestUserControl_textColor:
                resourceId = typedArray.getResourceId(
                        R.styleable.MyTestUserControl_textColor, 0);
                mColor= resourceId > 0 ? 
                        typedArray.getResources().getColor(resourceId):
                        typedArray.getColor(R.styleable.MyTestUserControl_textColor, Color.BLACK);

                break;
            }
        }
        typedArray.recycle();
复制代码

其中第二行context.obtainStyledAttributes方法传入的第二个参数是attrs.xml对应的declare-styleable节点的name属性值。Text属性的值还是要通过资源文件中获取,所以布局文件中的属性设置不能是字面值了。

 

组合控件

  如果定义的控件其实是组合控件来的,那么这个控件是继承一些布局的视图类

例如布局文件如下

复制代码
   < LinearLayout xmlns:Android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent" 
 android:layout_height="fill_parent"  
    android:gravity="center_vertical">  
<TextView 
    android:id="@android:id/lab1"
    android:layout_width="wrap_content" 
 android:layout_height="wrap_content"  
 android:text="Label1"
    />
<EditText
    android:id="@android:id/txt1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
/> 
    < /LinearLayout>
复制代码

 

在类的文件里面就要用这样的构造函数

复制代码
     public LabelText(Context context) {  
     this(context, null);  
     }  
      
     public LabelText(Context context, AttributeSet attrs) {  
     super(context, attrs);  
      //在构造函数中将Xml中定义的布局解析出来。 
     LayoutInflater.from(context).inflate(R.layout.imagebtn_with_text, this, true);
  
   }  
复制代码

 

同时还外放了一些别的方法,整个类的定义如下了

复制代码
public class LabelText extends LinearLayout {  
    
    TextView label;
    EditText textBox;
    
     public LabelText(Context context) {  
     this(context, null);  
     }  
      
     public LabelText(Context context, AttributeSet attrs) {  
     super(context, attrs);  
      //在构造函数中将Xml中定义的布局解析出来。 
     LayoutInflater.from(context).inflate(R.layout.imagebtn_with_text, this, true);
     label=(TextView)findViewById(R.id.lab1);
     textBox=(EditText)findViewById(R.id.txt1);
   }  
     

    public void SetTextBoxText(String val)
    {
        textBox.setText(val);
    }
    
    public String GetTextBoxText()
    {
        return textBox.getText();
    }
    
    public void SetLabelText(String val)
    {
        label.setText(val);
    }
    
    public String GetTextBoxText()
    {
        return label.getText();
    }

}
复制代码

 

基类View的方法

定义控件时,可重写的基类方法,View里面提供的方法如下

  • onFinishInflate() 当View中所有的子控件 均被映射成xml后触发
  • onMeasure(int, int) 确定所有子元素的大小
  • onLayout(boolean, int, int, int, int) 当View分配所有的子元素的大小和位置时触发
  • onSizeChanged(int, int, int, int) 当view的大小发生变化时触发
  • onDraw(Canvas) view渲染内容的细节
  • onKeyDown(int, KeyEvent) 有按键按下后触发
  • onKeyUp(int, KeyEvent) 有按键按下后弹起时触发
  • onTrackballEvent(MotionEvent) 轨迹球事件
  • onTouchEvent(MotionEvent) 触屏事件
  • onFocusChanged(boolean, int, Rect) 当View获取 或失去焦点时触发
  • onWindowFocusChanged(boolean) 当窗口包含的view获取或失去焦点时触发
  • onAttachedToWindow() 当view被附着到一个窗口时触发
  • onDetachedFromWindow() 当view离开附着的窗口时触发,该方法和  onAttachedToWindow() 是相反的。
  • onWindowVisibilityChanged(int) 当窗口中包含的可见的view发生变化时触发
posted @   猴健居士  阅读(269)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示