Android常用控件用法

jopen 10年前

包含Checkbox 二、RadioButton 三、ImageView 四、深入LinearLayout 五、相对布局 六、TimePicker 七、DatePicker。

一、Checkbox

1.布局文件的定义

<CheckBox

       android:id="@+id/eatId"

       android:layout_width="wrap_content"

        android:layout_height="wrap_content"

       android:text="吃饭"/>

   

    <CheckBox

       android:id="@+id/sleepId"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:text="睡觉"/>

   

    <CheckBox

       android:id="@+id/dotaId"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:text="dota"/>

2.Activity中的使用

先声明三个成员变量:

    private CheckBox eatBox;

    private CheckBox sleepBox;

    private CheckBox dotaBox;

再在onCreate函数里找到它们

       eatBox = (CheckBox) findViewById(R.id.eatId);

       sleepBox = (CheckBox) findViewById(R.id.sleepId);

       dotaBox = (CheckBox) findViewById(R.id.dotaId);

3.OnClickListener监听器

现在需要定义一个监听器,监听click这个事件

class onClickBoxListener implements OnClickListener{

        @Override

        public void onClick(View v) {

            // TODOAuto-generated method stub

            System.out.println("Checkbox is clicked!");

        }

   }

然后在onCreate函数实例化这个监听器

onClickBoxListener listener = new onClickBoxListener();

将监听器绑定到Checkbox上。这里可以把一个listener绑定到多个控件。

        eatBox.setOnClickListener(listener);

        sleepBox.setOnClickListener(listener);

        dotaBox.setOnClickListener(listener);

现在运行这个程序,如图:

Android常用控件用法

三个选项出现,我们进行勾选,Eclipse的后台会显示Checkbox is clicked!

1) 在监听器中获取checkbox ID

虽然实现了基本流程,但是有一个问题没有解决,不管我勾选或取消哪个Checkbox,响应的行为都是一样的,而且不知道是选中还是取消选中。这满足不了编程的需要。

要实现这种功能,我们要通过监听器传参:

        public void onClick(View v) {

            // TODOAuto-generated method stub

            System.out.println("Checkbox is clicked!");

        }

函数里的vView类型,它有一个方法是getId(),它得到的就是控件的ID

现在事情就很好办了。

if (v.getId() == R.id.eatId){

    System.out.println("eatBox");

} else if (v.getId() == R.id.sleepId){

    System.out.println("sleepBox");

} else if (v.getId() == R.id.dotaId){

    System.out.println("dotaBox");

}

2) 在监听器中获取checkbox 的选中状态

我们需要知道,对某个checkbox操作的是选中还是取消选中。

还是通过v这个参数,由于这个参数是View类型,我们需要向下转型为CheckBox,才能获取选中状态。

CheckBox checkbox = (CheckBox) v;

CheckBox类型有一个方法,是isChecked()。返回值是真,表示选中,返回值是假,表示未选中。

4.OnCheckedChangeListener监听器

依然是定义一个监听器,监听CheckedChange这个事件,即Checkbox的选中状态发生改变时:

    class boxListener implements OnCheckedChangeListener{

   

}

导入包的时候注意,选CompoundButton这个。Checkbox其实是它的子类。

Android常用控件用法

添加未实现的方法时,我们发现函数的传参是个CompoundButton类型,还有第二个参数,是个布尔值。

当选中状态发生改变时,就把控件对象和当前状态传递进来。

        @Override

        public void onCheckedChanged(CompoundButton buttonView,

                booleanisChecked) {

            // TODO Auto-generated method stub

           

        }

照旧是实例化这个监听器,绑定到控件上。

       boxListener listener2 = new boxListener();

       

        eatBox.setOnCheckedChangeListener(listener2);

        sleepBox.setOnCheckedChangeListener(listener2);

        dotaBox.setOnCheckedChangeListener(listener2);

现在我们来完善监听代码

if (buttonView.getId() == R.id.eatId){

    System.out.println("eatBox Changed");

    if (isChecked)

        System.out.println("eatBox Changed True");

}

不用多说了,这对程序员来说已经很简单了。

 

OnClickListener监听和OnCheckedChangeListener监听的区别在于:

前者是监听点击事件,后者是监听状态的改变,因为状态的改变不全是由于直接的点击,也可以是由于代码的控制,代码里设置checkbox状态的函数是setChecked(状态) ,状态的值是truefalse

 

 

二、RadioButton

1.布局文件的定义

RadioGroup是指一组单选按键,一组单选按钮只能选中一个。RadioButtonRadioGroup的子标签(RadioButtonRadioGroup分别是不同的控件)。所以在布局文件里,要先定义一个RadioGroup,内部再包含RadioButton

<RadioGroup

       android:id="@+id/radios"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:orientation="horizontal">

        <RadioButton

            android:id="@+id/femaleId"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="female"

        />

        <RadioButton

            android:id="@+id/maleId"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="male"

        />

</RadioGroup>

注意:RadioGroup有个特殊的属性orientation,是指各单选按钮的排列方向,可以设置水平或垂直。

2.Activity中的使用

声明成员变量,注意RadioGroupRadioButton分开声明:

    private RadioGroupradioGroup;

    privateRadioButton femaleButton;

    privateRadioButton maleButton;

findViewById找到它们:

        radioGroup = (RadioGroup) findViewById(R.id.radios);

        femaleButton = (RadioButton) findViewById(R.id.femaleId);

        maleButton = (RadioButton) findViewById(R.id.maleId);

实现选中之后的行为,需要绑定监听器了。

3.OnClickListener监听器

可以给RadioButton添加OnClickListener,监听各个RadioButton被点击的状态。操作方法与前一讲Checkbox类似,此不赘述。

4.OnCheckedChangeListener监听器

1) RadioGroupOnCheckedChangeListener

RadioGroup绑定监听器OnCheckedChangeListener,表示当这个RadioGroup内部的RadioButton被选中时,就会调用OnCheckedChangeListener监听器:

class listener implements OnCheckedChangeListener(){

   

}

在导入包的时候注意了,这与Checkbox不同,我们须选择第二个

Android常用控件用法

导入包以后,onCreate里绑定到RadioGroup

       listener listener = new listener();

        radioGroup.setOnCheckedChangeListener(listener);

然后在监听器里实现未实现的函数:

class listener implements OnCheckedChangeListener{

    @Override

    public voidonCheckedChanged(RadioGroup group, int checkedId) {

           

    }

}

发现这个函数有两个参数,

第二个参数代表这个RadioGroup里被选中的RadioButtonID,因为同时被选中的只可能有一个嘛,所以就直接传进来了。

实现监听器的代码:

        public voidonCheckedChanged(RadioGroup group, int checkedId) {

            if (checkedId == R.id.femaleId){

                System.out.println("femaleId is checked");

            } else {

                System.out.println("maleId is checked");

            }

        }

 

2) RadioButtonOnCheckedChangeListener

定义这个监听器的时候,要特别注意,实现的接口不是RadioGroup.OnCheckedChangeListener,而是CompoundButton.OnCheckedChangeListener

于是我们定义这个监听器的时候,为避免重名,要写全:

    class listener2 implements android.widget.CompoundButton.OnCheckedChangeListener{

        @Override

        public void onCheckedChanged(CompoundButton buttonView,

                boolean isChecked) {

            // TODO Auto-generated method stub

           

        }

}

为什么是CompoundButton

这里解释一下,所谓CompoundButton,是指两种状态的button的抽象父类,CheckboxRadioButton都是它的子类。

绑定它到femaleButton上:

       listener2 listener2 = new listener2();

        femaleButton.setOnCheckedChangeListener(listener2);

如此表示,当femaleButton的选中状态发生改变时,触发listener2监听器里的代码。

注意:如果我们选中了maleButton,也会调用这个监听器,因为选中maleButton的同时,femaleButton的选中状态也发生了改变。

我们实现这个监听器里的代码:

public void onCheckedChanged(CompoundButton buttonView,

                boolean isChecked) {

    System.out.println("female is "+ isChecked);

}

第二个参数就是当前选中的状态。

三、ImageView

1.布局文件的定义

    <ImageView

       android:id="@+id/imageId"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:src="@drawable/qq" />

这里有个src属性,很好理解,不过里面的东东是怎么来的呢?

之前我们提到过的res这个资源目录,里面的drawable表示存放图片。

我们将图片拷进目录:

Android常用控件用法

R.java文件会自动生成它的ID

    public static final class drawable {

        public static final int ic_launcher=0x7f020000;

        public static final int qq=0x7f020001;

    }

因此,我们使用android:src="@drawable/qq"就可以引用到它了。

2.Activity中的使用

声明变量

    private ImageView image;

找到控件

image = (ImageView) findViewById(R.id.imageId);

之前是在布局文件中设置它的源文件,也可以在代码中设置:

image.setImageResource(R.drawable.qq);

Android常用控件用法

3.ScaleType属性

现在的问题是,图片铺不满全屏。ScaleType就是用来解决这个问题的,它用于定义图片拉伸的类型是什么。

先让我们把准备工作做好,写两个ImageView写好高宽和背景色,以方便做对比。

上一张是刚才那只卖萌狗,下一张是安卓机器人图标:

    <ImageView

       android:id="@+id/imageId"

       android:layout_width="100dp"

       android:layout_height="100dp"

       android:background="#FF0000"

       android:scaleType="center"

       android:src="@drawable/qq" />

   

    <ImageView

       android:id="@+id/image2Id"

       android:layout_width="100dp"

       android:layout_height="100dp"

       android:background="#00FF00"

       android:scaleType="center"

       android:src="@drawable/ic_launcher"/>

ScaleType有以下几种,让我们来分别试验一下:

1)  center

不缩放。

如果图比ImageView小,就居中。如果图比ImageView大,就截取中间部分。

Android常用控件用法

2)  centerCrop

等比例缩放。

并以短边为准铺满。长出的部分截掉。

Android常用控件用法

3)  centerInside

等比例缩小并居中对齐。

如果图比ImageView小,就不变。如果图比ImageView大,就缩小。

Android常用控件用法

4)  fitCenter

等比例缩放并居中对齐。

如果图比ImageView小,就放大。如果图比ImageView大,就缩小。

Android常用控件用法

5)  fitStart

等比例缩放并靠左上角对齐。

Android常用控件用法

6)  fitEnd

等比例缩放并靠右下角对齐。

Android常用控件用法

7)  fitXY

不等比例缩放,拉伸为与ImageView同样大小。

Android常用控件用法

 

在代码里怎么控制scaleType呢?

image.setScaleType(ScaleType.CENTER);

四、深入LinearLayout

1.LinearLayout的嵌套

Android常用控件用法

这样一个布局用一个LinearLayout是无法实现的。需要用到LinearLayout的嵌套。

 

布局代码如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

   xmlns:tools="http://schemas.android.com/tools"

   android:layout_width="match_parent"

   android:layout_height="match_parent"

   android:background="#FF0000"

   android:orientation="horizontal"

    tools:context=".MainActivity" >

    <LinearLayout

      android:layout_width="wrap_content"

      android:layout_height="wrap_content"

      android:background="#880000"

      android:layout_marginRight="10dp"

      android:orientation="vertical">

        <TextView

           android:layout_width="wrap_content"

           android:layout_height="wrap_content"

            android:textSize="20sp"

           android:text="first"/>

        <TextView

           android:layout_width="wrap_content"

           android:layout_height="wrap_content"

           android:textSize="20sp"

           android:text="second"/>

    </LinearLayout>

    <LinearLayout

      android:layout_width="wrap_content"

      android:layout_height="wrap_content"

      android:background="#880000"

      android:orientation="vertical">

        <TextView

           android:layout_width="wrap_content"

           android:layout_height="wrap_content"

           android:textSize="20sp"

           android:text="first"/>

        <TextView

           android:layout_width="wrap_content"

           android:layout_height="wrap_content"

           android:textSize="20sp"

           android:text="second"/>

    </LinearLayout>

</LinearLayout>

这个嵌套对程序员来说太容易理解了,就不多说了。

2.layout_weight属性

Layout_weight这个属性的值用于指定空闲空间的分配比例,如下图:

Android常用控件用法

使用layout_weight,要求子控件并未占满你控件的所有空间。否则这个属性将不具意义。

Layout_weight的值是整型。

例如,上面这张图,如果我们给两个控件的layout_weight分别给定值1

Android常用控件用法

那么,这两个控件将平分空闲空间。达到的效果见下图:

Android常用控件用法

有一点需要特别注意:

layout_weight=1不代表两个控件平分父控件的空间,而是在本身占据的空间基础上,将剩下的空间一分为二,分别加给两控件。所以,两控件并不一定是各占父控件的二分之一的。

见下图:

Android常用控件用法

红线所划的距离是相等的。而绿色和蓝色的长度却不等。

 

这是layout_weight1的情况,如果将控件一的layout_weight设为2呢?

那么,就将剩余空间平均分为三份,其中两份给控件一,一份给控件二。

以此类推。

 

我们在实际开发中常常需要让控件占父控件的1/2,或1/3等等。这样layout_weight就满足不了我们的要求。但有个办法可以做到:

将控件的宽不再wrap_content,而是设为0dp

五、相对布局

1.什么是相对布局

相对布局是通过指定当前控件与兄弟控件或父控件之间的相对位置,从而达到控制控件位置的目的。

和线性布局相比有什么优势呢?看下面这张图:

Android常用控件用法

这个布局如果用线性布局,需要嵌套好几层,而如果用相对布局,一个布局就搞定了。

Android UI来说,几层布局嵌套,性能比一个布局要差。

2.相对布局基本思路

先确定一个控件的位置,第二个控件,确定它相对于第一个控件的位置。

这种情况下,如果第一个控件因为某种原因发生位置改变,那么,第二个控件与它的相对位置不变,也跟着位移。

 

在相对布局中,如果不指定相对位置,默认会放在父控件的左上角:Android常用控件用法

如果第二个控件也不指定相对位置,那么,第二个控件会覆盖第一个控件,仍然放在左上角:

Android常用控件用法

要实现相对布局,就要指定相对位置,以下我们分别介绍:

1)  与兄弟控件边缘对齐

layout_toRightOf

把当前控件的左边缘对齐到指定控件的右边缘。

第一个控件给定IDfirst

    <TextView

       android:id="@+id/first"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:background="#FF0000"

        android:text="第一个控件" />

第二个控件设置layout_toRightOf属性为@id/first

注意:这里没有++表示增加一个id

    <TextView

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:background="#00FF00"

       android:layout_toRightOf="@id/first"

       android:text="第二个控件" />

这样就能把第二个控件放置在第一个控件的右边

Android常用控件用法

layout_toLeftOf

把当前控件的右边缘对齐到指定控件的左边缘。

理同layout_toRightOf

 

如果第一个控件没有指定相对位置,而第二个控件指定到它的左边缘,那么第二个控件会被挤到屏幕外面,不可见。见下图:

 Android常用控件用法

layout_below

把当前控件的上边缘对齐到指定控件的下边缘。

Android常用控件用法

layout_above

把当前控件的上边缘对齐到指定控件的下边缘。

layout_toLeftOf理,在屏幕外,不可见了。

Android常用控件用法

layout_alignLeft

把当前控件的左边缘对齐到指定控件的左边缘。

我们先把第一个控件的文本改得“第一个控件比较长”,这样看得出来。

把第二个控件的layout_alignLeft值设为@id/first

Android常用控件用法

第一个控件被覆盖掉了一部分。

layout_alignRight

把当前控件的右边缘对齐到指定控件的右边缘。

理同layout_alignLeft

Android常用控件用法

layout_alignTop

把当前控件的上边缘对齐到指定控件的上边缘。

Android常用控件用法

layout_alignBottom

把当前控件的下边缘对齐到指定控件的下边缘。

Android常用控件用法

2)  与兄弟控件基准线对齐

什么是基准线

基准线(baseline):为了保证印刷字母的整齐而划定的线。这主要针对英文,对于中文其实没有这个问题。

Android常用控件用法

第三条线就是基准线。

对齐到基准线的属性是layout_alignBaseLine

layout_alignBaseLine

把当前控件的基准线对齐到指定控件的基准线。

沿用之前的代码,第二个控件的定义如下:

    <TextView

       android:id="@+id/second"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:background="#00FF00"

       android:layout_alignBaseline="@id/first"

       android:layout_toRightOf="@id/first"

       android:text="第二个控件" />

定义了两个对齐属性,layout_alignBaselinelayout_toRightOf都指定为@id/first

为了比较明显,把第一个控件的字体设大,为30sp

效果如下:

Android常用控件用法

对齐的不再是边缘,而是字体的基准线。

3)  与父控件边缘对齐

我们去掉第二个控件,将第一个控件设置以下属性:

注意:这些属性的值不再是某控件的id,而是truefalse

layout_alignParentRight

把当前控件的右边缘对齐到父控件的右边缘。

    <TextView

       android:id="@+id/first"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:background="#FF0000"

       android:textSize="30sp"

       android:layout_alignParentRight="true"

        android:text="第一个控件" />

Android常用控件用法

layout_alignParentLeft

把当前控件的左边缘对齐到父控件的左边缘。

如果我同时设定layout_alignParentRightlayout_alignParentLeft都为true,会出现什么情况呢?

Android常用控件用法

它的效果会叠加,即左边缘对齐父控件的左边缘,右边缘对齐父控件的右边缘。

layout_alignParentTop

把当前控件的上边缘对齐到父控件的上边缘。

理同layout_alignParentRight,可与其他三个属性叠加。

比如可设置左上对齐,或右上对齐。

layout_alignParentBottom

把当前控件的右边缘对齐到父控件的右边缘。

理同layout_alignParentRight,可与其他三个属性叠加。

比如可设置左下对齐,或右下对齐。

4)  与父控件中央对齐

layout_centerInParent

把当前控件对齐到父控件垂直和水平的中间位置。

Android常用控件用法

layout_centerHorizontal

把当前控件对齐到父控件水平的中间位置。

Android常用控件用法

layout_centerVertical

把当前控件对齐到父控件垂直的中间位置。

Android常用控件用法

3.相对布局的新属性(Android4.2)

为了使用这些新属性,项目新建时,必须把最低的兼容属性也调整到4.2,否则使用不了这些属性。

 Android常用控件用法

layout_alignStart

把当前控件对齐到指定控件的起始位置。

    <TextView

       android:id="@+id/first"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:background="#FF0000"

       android:text="@string/hello_world" />

   

    <TextView

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

        android:background="#00FF00"

       android:layout_alignEnd="@id/first"

        android:text="abc" />

Android常用控件用法

可以layout_below一起用:

Android常用控件用法

layout_alignEnd

把当前控件对齐到指定控件的结束位置。

layout_below一起用时的效果:

Android常用控件用法

layout_alignParentStart

把当前控件的头部对齐到父控件的开始位置。

值为truefalse

Android常用控件用法

layout_alignParentEnd

把当前控件的尾部对齐到父控件的尾部。

值为truefalse

Android常用控件用法

4.综合运用

来个实用的例子:

Android常用控件用法

实现这个界面之前,先记住两个之前没有提过的东西:

1.内容居中

android:gravity="center"

2.文本框

EditText

EditText有个属性叫hint,表示文本框在未输入前的提示信息:

android:hint="请输入内容"

还有个属性叫inputType,表示输入的类型,如文本(text)、日期(date)、日期时间(datetime)、数字(number)、电话(phone)、密码(textPassword)等等。

android:inputType="textPassword"

 

动手做一做吧。

 

六、TimePicker

1.布局文件的定义

    <TimePicker

       android:id="@+id/timeId"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

         />

效果如下图:

Android常用控件用法

2.Acitivity中的使用

声明这个变量

    private TimePicker timePicker;

找到这个控件

timePicker = (TimePicker) findViewById(R.id.timeId);

3.OnTimeChangedListener监听器

定义这个监听器:

    class Listener implementsOnTimeChangedListener{

 

        @Override

        public voidonTimeChanged(TimePicker view, int hourOfDay, int minute) {

            System.out.println("hour:"+hourOfDay+",minute:"+minute);

           

        }

   

    }

绑定到之前的控件:

       Listener Listener=new Listener();

        timePicker.setOnTimeChangedListener(Listener);

观察未实现的方法,有三个参数:

第二个参数hourOfDay表示用户选择的小时

第三个参数minute表示用户选择的分钟

Android常用控件用法

4.24小时制

用一行代码可以做到:

timePicker.setIs24HourView(true);

5.选定以后提交

如果不要一直变化,而要用户选定以后再点确定提交,怎么做呢?

先加个Button

    <Button

       android:id="@+id/submit"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:text="确定"

       android:layout_below="@id/timeId"

        />

Activity里声明它

private Button submit;

找出它

       submit = (Button) findViewById(R.id.submit);

定义一个OnClickListener的监听器

    class listener2 implementsOnClickListener{

 

        @Override

        public void onClick(View v) {

            int Hour = timePicker.getCurrentHour();

            int Minute = timePicker.getCurrentMinute();

            System.out.println("hour:"+Hour+",minute:"+Minute);

        }

   

    }

int Hour = timePicker.getCurrentHour();表示获取当前选择的小时数。

int Minute = timePicker.getCurrentMinute();表示获取当前选择的分钟数。

绑定这个监听器到Button上。

       listener2 listener2=new listener2();

       submit.setOnClickListener(listener2);

6.设定初始时间

TimePicker默认显示当前时间。可以设置:

timePicker.setCurrentHour(10);

timePicker.setCurrentMinute(00);

七、DatePicker

1.布局文件的定义

定义一个DatePicker和一个Button

    <DatePicker

       android:id="@+id/datePicker"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

        />

   

    <Button

       android:id="@+id/submit"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:layout_below="@id/datePicker"

       android:text="提交"

        />