这里是介绍安卓的一些组件,也就是书上面的第二章UI界面那一章。
之前进行到FrameLayout的时候去研究Handler的消息机智了,现在回来。
不是说View是所有组件的父类么。是这样的。
textview组件(就是那个文本框)直接继承了View。而且他还是EditView和Button组件的父类。
文本中有大量的方法,查看API
他派生了两个子类,
AutoCompleteTextView自动完成的子类,一般和adapter搭配使用。
一个是ExtractEditText:这个你一般也用不着。
下面这个xml文件是和组件的xml属性有关的:
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stretchColumns="1">
<TableRow>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="用户名:"
android:textSize="16sp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请填写登录账号"
android:selectAllOnFocus="true"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberPassword"/>
TableRow>
<TableRow>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="年龄:"
android:textSize="16sp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"/>
TableRow>
<TableRow>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="生日:"
android:textSize="16sp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="date"/>
TableRow>
<TableRow>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="电话号码:"
android:textSize="16sp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请填写您的电话号码"
android:selectAllOnFocus="true"
android:inputType="phone"/>
TableRow>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="注册"/>
TableLayout>
android:inputType这个属性很重要的。EditText输入的类型。
另外注意hint这个东西是可以改变颜色的。
在drawable里面可以用xml自定义Drawable对象。
他的根节点是selector。选择器?
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/red"
/>
<item android:state_pressed="false"
android:drawable="@drawable/purple"
/>
selector>
条目是选择不同的状态。
RadioButton是一组一组的用,搭配RadioGroup。哟一个小细节就是,如果指定了有默认选择的RadioButton,那RadioGroup之中的每一个RadioButton都要有id属性。
另外如果用了RadioGroup,加事件监听器的时候是为RadioGroup加的。
public class MainActivity extends Activity
{
//在这里添加组件
RadioGroup rg;
TextView show;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 获取界面上rg、show两个组件
rg = (RadioGroup) findViewById(R.id.rg);
show = (TextView) findViewById(R.id.show);
// 为RadioGroup组件的OnCheckedChange事件绑定事件监听器
//下面用的是匿名对的方式。为rg绑定一个oncheckchangelistener是很常见的。
//另外不要困惑为什么括号里面有new RadioGroup.OnCheckedChangeListener()这个
//你把RadioGroup这个定西去掉,会报错,你import就行了,就是少引入了个包而已。
rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener()
{
@Override
//下面这个其实一开始没有完全理解。int checkedId其实是系统传进来的,不是自己传进来的。
public void onCheckedChanged(RadioGroup group, int checkedId)
{
// 根据用户勾选的单选按钮来动态改变tip字符串的值
String tip = checkedId == R.id.male ?
"您的性别是男人": "您的性别是女人";
// 修改show组件中的文本
show.setText(tip);
//用switch其实也行。但是注意这个是个int值。
}
});
}
}
下面这个,关于imageview,你就记住
image1.setImageResource(images[++currentImg % images.length]);
setImageResource()这个函数就行了。他能接受一个int类型的id值。
下面的这一堆组件比较麻烦,就是用AdapterView的组件。
其实不是listview,spinner用adapter,而是他们本来就是AdapterView的组件,他们本来就要用到Adapter去提供内容。
这个继承图也是挺醉的:
树形啊:
viewgroup
AdapterView
AbsListView AbsSpinner AdapterViewAnimator
上面三个虽然分了一些类,但是仍然是抽象的。所以理解了为什么spinner也是需要Adapter去提供内容。
直接使用ListView
让activity去继承ListActivity
ListView使用的setAdapter()方法其实是AdapterView的方法。
ListView,spinner都是容器,而Adapter负责提供列表项组件。注意是列表项。
AbsListview他的这个属性很重要:
>android:choiceMode
他有几个属性值:singleChoice允许单选,multipleChoice允许多选。
我大胆的推测一下是不是LIistView列表指定了之后就能多选了?
但是那样的话返回的话是怎么返回的?
ListView本身的xml属性不多
android:divider 指定分隔条(可以直接指定颜色,可以指定Drawable资源)
android:dividerHeight 指定分隔条的高度(px像素为单位一般是)
android:entries 指定一个数组资源
利用LiseView的entries属性是很快,但是也很简陋,不能改变列表项的样式,资源也一般是固定的。
不过要是我每次读下来一个xml文件,然后显示在列表里面呢?好像也行。
重要的是entries指定的是一个数组资源。
<resources>
<string-array name="books">
<item>疯狂Java讲义item>
<item>疯狂Ajax讲义item>
<item>疯狂XML讲义item>
<item>疯狂Android讲义item>
string-array>
resources>
注意数组资源是在values文件夹下的,根元素是resources
如果要想为列表项弄不一样的东西,那就得动用adapter了。
Adapter本身也是一个接口,他下面有一堆子孩子,比如ListAdapter和SpinnerAdapter。他们的继承关系比较复杂,参观书上91页。
常用的是BsaseAdapter和ArrayAdapter和SimplelAdapter。
ArrayAdapter是一般提供数组的包装。
BasrAdapter用于扩展可以被扩展为任意的Adapter。
SimpleAdapter这个里面的参数很复杂。
-SimpleCursorAdapter通常包装cursor提供的内容。
arrayAdapter
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView list1 = (ListView) findViewById(R.id.list1);
// 定义一个数组
String[] arr1 = { "孙悟空", "猪八戒", "牛魔王" };
// 将数组包装为ArrayAdapter
ArrayAdapter adapter1 = new ArrayAdapter
(this, R.layout.array_item, arr1);
// 为ListView设置Adapter
list1.setAdapter(adapter1);
ListView list2 = (ListView) findViewById(R.id.list2);
// 定义一个数组
String[] arr2 = { "Java", "Hibernate", "Spring" , "Android" };
// 将数组包装为ArrayAdapter
//我觉着吧,既然后边那个参数是一个数组,那adapter包装的应该就是一个数组,而不是丹丹的一个条目。
//中间的参数也可以单纯的理解为是“样式”,一个条目应该有的样式。
//数组资源我一定要写在java文件中吗?好像一般不用吧。
ArrayAdapter adapter2 = new ArrayAdapter
(this, R.layout.checked_item, arr2);
// 为ListView设置Adapter
list2.setAdapter(adapter2);
}
}
函数的原型:
android.widget.ArrayAdapter.ArrayAdapter< String >(Context context, int resource, String[] objects)
第一个是上下文,第二个是条目的资源,第三个是数组资源。
还有一个问题。第二个参数是int resource,这个工程中的xml文件中是单独的一个Textview。
是因为这个adapter是ArrayAdapter吗?对的,这句话:
**arrayadapter虽然简单,但是只能用TextView作为列表项,功能很局限。貌似也是不能响应点击事件的。
我记得别的是可以用linearLayout的。
大概这就是为什么ArrayAdapter只适合数组的缘故吧,layout文件夹里面的条目适合用Textview去指定。
基于ListAdapter的不需要实现setContentView()方法。
一般的activity都会有这个方法去显示activity_main文件,比如:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
他一般是在OnCreate()方法中的。
但是如果继承了ListActivity的话就不用这个方法了,直接传入一个Adapter,这样这个Activity就只剩下一个LIstView了。
public class MainActivity extends ListActivity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// 无须使用布局文件
String[] arr = { "孙悟空", "猪八戒", "唐僧" };
// 创建ArrayAdapter对象
//连layout里面的东西也省了啊,直接用的系统的系统的界面
//android.R.layout.simple_list_item_multiple_choice,
//选中怎么没反应呢?应该是设置监听器。
//这个设置监听器的比较麻烦,因为整个继承了ListActivity,里面有什么方法,什么时候调用这个方法都不知道。
//这算是一个遗留问题:继承了activity的怎么放置监听器呢?
ArrayAdapter adapter = new ArrayAdapter(this,
android.R.layout.simple_list_item_multiple_choice, arr);
// 设置该窗口显示列表
setListAdapter(adapter);
}
}
这个倒是省事儿啊。
SimpleAdapter有一个好长好长的构造函数:
先看下面这一堆代码:
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 创建一个List集合,List集合的元素是Map
//首先这个list集合就比较难理解。他是一个List集合,List可以看做是一个数组。
//里面的元素是Map<>,而map<>是个特殊的东西,他里面的东西是靠键值对来存放的,string是key,都是字符串
//listItems就是那个集合
List