AdapterView本身是一个抽象基类,它派生的子类在用法上十分相似,只是显示界面有一定区别
AdapterView继承了ViewGroup
AdapterView可以包括多个“列表项”
AdapterView显示的多个“列表项”由Adapter提供调用AdapterView的setAdapter(Adapter)方法设置Adapter
AdapterView派生了三个子类:AbsListView、AbsSpinner和AdapterViewAnimator,这三个依旧是抽象类
2.5.1 列表视图ListView和 ListActivity
手机系统中广泛采用了ListView
可以通过以下两种方式创建ListView:
1.直接使用ListView进行创建
2.让Activity继承ListActivity
AbsListView提供了如下XML属性:
android:choiceMode
|
|
设置AbsListView的选择行为:
none
singleChoice
multipleChoice
multipleChoiceMode
|
android:drawSelectorOnTop
|
|
若设为true,选中列表项将会显示在上面
|
android:fastScrollEnabled
|
| 是否允许快速滚动 |
android:listSelector
|
|
指定被选中的列表项上绘制的Drawable
|
android:scrollingCache
|
|
是否使用绘制缓存
|
android:stackFromBottom
|
|
是否从底端开始排列列表项
|
android:smoothScrollbar
|
|
若设为false,则不在header View之后绘制分隔条
|
android:textFilterEnabled
|
|
是否对列表项进行过滤。当AbsListView对应的Adapter实现了Filter接口时才会起作用
|
android:transcriptMode
|
|
滚动模式:
disable
normal
alwaysScroll
|
ListView 提供了如下XML属性:
android:divider
|
分隔条(颜色、Drawable)
|
android:dividerHeight
|
|
android:entries
| 数组资源 |
android:footerDividerEnabled
|
若为false,则不在footer View之前绘制分隔条
|
android:headerDividerEnabled
|
若为false,则不在header View之前绘制分隔条
|
示例代码:(需要添加arrays.xml)
<
ListView
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:entries = "@array/books"
android:divider = "#f00"
android:dividerHeight = "2px"
android:headerDividersEnabled = "false"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:entries = "@array/books"
android:divider = "#f00"
android:dividerHeight = "2px"
android:headerDividersEnabled = "false"
/>
使用ListView能定制的内容很少,甚至每个列表项的字号大小、颜色都不能改变。
如果想改变这些特性,就需要把ListView作为AdapterView使用
2.5.2 Adapter接口及实现类
Adapter本身只是一个接口,它派生了ListAdapter和SpinnerAdapter两个子接口,其中ListAdapter为AbsListView提供列表项,而SpinnerAdapter为AbsSpinner提供列表项
ArrayAdapter:简单易用的Adapter,通常用于将数组或List集合的多个值包装成列表项
SimpleAdapter:将List集合的多个对象包装成多个列表项
SimpleCursorAdapter:包装Cursor提供的数据
BaseAdapter:通常用于被扩展,可以对各列表项提供最大限度的定制
ArrayAdapter 示例程序的代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. activity_main );
ListView list1 = (ListView) findViewById(R.id. list1 );
String[] arr1 = { "悟空" , "八戒" , "悟能" };
ArrayAdapter<String> adapter1 = new ArrayAdapter<String>( this ,
R.layout. array_item , arr1);
list1.setAdapter(adapter1);
ListView list2 = (ListView) findViewById(R.id. list2 );
String[] arr2 = { "曹操" , "孙权" , "刘备" };
ArrayAdapter<String> adapter2 = new ArrayAdapter<String>( this ,
R.layout. checked_item , arr2);
list2.setAdapter(adapter2);
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. activity_main );
ListView list1 = (ListView) findViewById(R.id. list1 );
String[] arr1 = { "悟空" , "八戒" , "悟能" };
ArrayAdapter<String> adapter1 = new ArrayAdapter<String>( this ,
R.layout. array_item , arr1);
list1.setAdapter(adapter1);
ListView list2 = (ListView) findViewById(R.id. list2 );
String[] arr2 = { "曹操" , "孙权" , "刘备" };
ArrayAdapter<String> adapter2 = new ArrayAdapter<String>( this ,
R.layout. checked_item , arr2);
list2.setAdapter(adapter2);
}
array_item.xml,checked_item.xml两个文件控制列表项组件的外观
checked_item.xml代码如下:
android:id="@+id/TextView"
android:layout_width
=
"match_parent"
android:layout_height = "wrap_content"
android:textSize = "14dp"
android:padding = "20px"
android:shadowDx = "4"
android:shadowDy = "4"
android:shadowColor = "#0f0"
android:layout_height = "wrap_content"
android:textSize = "14dp"
android:padding = "20px"
android:shadowDx = "4"
android:shadowDy = "4"
android:shadowColor = "#0f0"
android:shadowRadius="2"
android:checkMark="@drawable/ok"
/>
基于ListActivity实现列表——当程序窗口仅需显示一个列表,则可以直接让Activity继承ListActivity来实现,ListActivity的子类无须调用setContentView()方法来显示某个界面,而可以直接传入一个内容Adapter,ListActivity的子类就呈现出一个列表
Java实现代码如下:(onCreate部分内容)
String[] arr = {
"悟空"
,
"八戒"
,
"悟能"
};
ArrayAdapter<String> adapter = new ArrayAdapter<String>( this ,
R.layout. simple_list_item_multiple_choice , arr);
ArrayAdapter<String> adapter = new ArrayAdapter<String>( this ,
R.layout. simple_list_item_multiple_choice , arr);
setListAdapter(adapter);
simple_list_tem…………该xml文件代码类似上例中的checked_item.xml
使用SimpleAdapter创建ListView
通过ArrayAdapter实现Adapter虽然简单、易用,但ArrayAdapter的功能有限。它的每个列表项只能是TextView。如果开发者需要实现更复杂的列表项,则可以考虑使用SimpleAdapter(实际上SimpleAdapter使用并不简单)
oops 陷阱
Drawable文件下的图片资源文件名不能含大写字母
SimpleAdapter simpleAdapter =
new
SimpleAdapter(
this
, listItems,
R.layout.simple_item,
new String[]{ "personName" , "header" , "desc" },
R.layout.simple_item,
new String[]{ "personName" , "header" , "desc" },
上面这句代码创建了一个SimpleAdapter,使用SimpleAdapter最大的难点在于创建SimpleAdapter对象,它需要5个参数,后面4个参数十分关键:
param2:该参数应该是一个List<? extends Map<String, ?>>类型的集合对象,该集合中每个Map<String,?>对象生成一个列表项
param3:指定一个界面布局的ID
param4:应为一个String[]类型的参数,该参数决定提取Map<String, ?>对象中那些key对应的value来生成的列表项
param5:int[],决定填充哪些组件
示例代码:
public
class
MainActivity
extends
ActionBarActivity {
private String[] names = new String[]
{ "Libai" , "Dupu" , "Liqingzhao" };
private String[] descs = new String[]
{ "Lovely boy" , "A girl good at piano" ,
"Romantic poet" };
private int [] imageIds = new int []
{R.drawable. libai ,R.drawable. dupu ,R.drawable. liqingzhao };
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. activity_main );
List<Map<String, Object>> listItems =
new ArrayList<Map<String, Object>>();
for ( int i = 0; i < names . length ; i++)
{
Map<String, Object> listItem = new HashMap<String, Object>();
listItem.put( "header" , imageIds [i]);
listItem.put( "personName" , names [i]);
listItem.put( "desc" , descs [i]);
listItems.add(listItem);
}
SimpleAdapter simpleAdapter = new SimpleAdapter( this , listItems,
R.layout. simple_item ,
new String[]{ "personName" , "header" , "desc" },
new int []{R.id. name , R.id. header , R.id. desc });
ListView list = (ListView) findViewById(R.id. mylist );
list.setAdapter(simpleAdapter);
private String[] names = new String[]
{ "Libai" , "Dupu" , "Liqingzhao" };
private String[] descs = new String[]
{ "Lovely boy" , "A girl good at piano" ,
"Romantic poet" };
private int [] imageIds = new int []
{R.drawable. libai ,R.drawable. dupu ,R.drawable. liqingzhao };
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. activity_main );
List<Map<String, Object>> listItems =
new ArrayList<Map<String, Object>>();
for ( int i = 0; i < names . length ; i++)
{
Map<String, Object> listItem = new HashMap<String, Object>();
listItem.put( "header" , imageIds [i]);
listItem.put( "personName" , names [i]);
listItem.put( "desc" , descs [i]);
listItems.add(listItem);
}
SimpleAdapter simpleAdapter = new SimpleAdapter( this , listItems,
R.layout. simple_item ,
new String[]{ "personName" , "header" , "desc" },
new int []{R.id. name , R.id. header , R.id. desc });
ListView list = (ListView) findViewById(R.id. mylist );
list.setAdapter(simpleAdapter);
}
}
xml文件代码:
<
LinearLayout
xmlns:android
=
"http://schemas.android.com/apk/res/android"
android:orientation = "horizontal"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
>
< ImageView
android:id = "@+id/header"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:paddingLeft = "10dp"
/>
< LinearLayout
android:orientation = "vertical"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
>
< TextView
android:id = "@+id/name"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:textSize = "20dp"
android:textColor = "#f0f"
android:paddingLeft = "10dp"
/>
< TextView
android:id = "@+id/desc"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:textSize = "14dp"
android:paddingLeft = "10dp"
/>
</ LinearLayout >
android:orientation = "horizontal"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
>
< ImageView
android:id = "@+id/header"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:paddingLeft = "10dp"
/>
< LinearLayout
android:orientation = "vertical"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
>
< TextView
android:id = "@+id/name"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:textSize = "20dp"
android:textColor = "#f0f"
android:paddingLeft = "10dp"
/>
< TextView
android:id = "@+id/desc"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:textSize = "14dp"
android:paddingLeft = "10dp"
/>
</ LinearLayout >
</
LinearLayout
>
SimpleAdapter同样可以作为ListActivity的内容Adapter,这样可以让用户方便地定制ListActivity所显示的列表
如果需要监听用户单击、选中某个列表项的事件,可以通过AdapterView的setOnItemClickListener()方法为单击事件添加监听器,或通过setOnItemSelectedListener()方法为列表项选中事件添加监听器。
添加方法如下:
list.setOnItemClickListener( new OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
System. out .println( names [position] + "was clicked" );
}
});
list.setOnItemSelectedListener( new OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
System. out .println( names [position] + "was selected" );
}
@Override
public void onNothingSelected(AdapterView<?> parent)
{
}
});
下面扩展BaseAdapter实现不存储列表项的ListView
扩展BaseAdapter可以取得对Adapter最大的控制权
示例程序代码:
public
class
MainActivity
extends
ActionBarActivity {
ListView myList ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. activity_main );
myList = (ListView) findViewById(R.id. myList );
BaseAdapter adapter = new BaseAdapter()
{
@Override
public int getCount()
{
return 40;
}
@Override
public Object getItem( int position)
{
return null ;
}
@Override
public long getItemId( int position)
{
return position;
}
@Override
public View getView( int position
, View convertView, ViewGroup parent)
{
LinearLayout line = new LinearLayout(MainActivity. this );
line.setOrientation(0);
ImageView image = new ImageView(MainActivity. this );
image.setImageResource(R.drawable. ic_launcher );
TextView text = new TextView(MainActivity. this );
text.setText( "第" + (position + 1) + "个列表项" );
text.setTextSize(20);
text.setTextColor(Color. RED );
line.addView(image);
line.addView(text);
return line;
}
};
ListView myList ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. activity_main );
myList = (ListView) findViewById(R.id. myList );
BaseAdapter adapter = new BaseAdapter()
{
@Override
public int getCount()
{
return 40;
}
@Override
public Object getItem( int position)
{
return null ;
}
@Override
public long getItemId( int position)
{
return position;
}
@Override
public View getView( int position
, View convertView, ViewGroup parent)
{
LinearLayout line = new LinearLayout(MainActivity. this );
line.setOrientation(0);
ImageView image = new ImageView(MainActivity. this );
image.setImageResource(R.drawable. ic_launcher );
TextView text = new TextView(MainActivity. this );
text.setText( "第" + (position + 1) + "个列表项" );
text.setTextSize(20);
text.setTextColor(Color. RED );
line.addView(image);
line.addView(text);
return line;
}
};
myList.setAdapter(adapter);
}
}
上述代码中重写了Adapter的如下4个方法:
getCount():返回值控制列表项数量
getItem(int position):返回值决定第position处列表项内容
getItemId(int position):返回值决定第position处列表项的ID
getView(int position, View convertView, ViewGroup parent):返回值决定第position处的列表项组件
利用Adapter步骤:
1.用四种方式之一创建Adapter
2.调用AdapterView的setAdapter(Adapter)方法设置Adapter
2.5.3 AutoCompleteTextView 自动完成文本框的功能和用法
AutoCompleteTextView从EditText派生而出,实际比文本编辑框多一个功能:当用户输入一定字符后,自动完成文本框会显示一个下拉菜单,供用户从中选择
AutoCompleteTextView除了可使用EditText提供的XML属性和方法之外,还支持如下XML属性:
android:completionHint
|
|
设置下拉菜单中的提示标题
|
android:completionHintView
|
|
设置下拉菜单中提示标题的试图
|
android:completionThreshold
|
|
设置用户至少输入几个字符才会显示提示
|
android:dropDownAnchor
|
|
设置下拉菜单的定位“锚点”组件,如果没有指定该属性,将使用该TextView本身作为定位“锚点”组件
|
android:dropDownHeight
|
|
设置下拉菜单的高度
|
android:dropDownVerticalOffset
|
|
设置下拉菜单与文本框之间的垂直偏移,默认紧跟
|
android:dropDownWidth
|
|
设置下拉菜单宽度
|
android:popupBackground
|
|
设置下拉菜单的背景
|
使用AutoCompleteTextView很简单,只要为它设置一个Adapter,该Adapter封装了AutoCompleteTextView预设的提示文本;其还派生了一个子类:MultiAutoCompleteTextView,该子类允许输入多个提示项,多个提示项以分隔符分隔,另有setTokenizer()方法设置分隔符
2.5.4 GridView 网格试图的功能和用法
GridView用于在界面上按行、列分布的方式来显示多个组件。GridView与ListView有共同的AbsListView,GridView与ListView的唯一区别在于:ListView只显示一列,而GridView可以显示多列;GridView也需要Adapter来提供显示的数据,开发者可以采用上面介绍的4种方式中的一种来创建Adapter,GridView与ListView的用法基本一致,GridView提供了如下XML属性:
android:columnWidth
|
设置列宽度
|
android:gravity
|
设置对齐方式
|
android:horizontalSpacing
|
设置各元素之间的水平间距
|
android:numColumns
|
设置列数
|
android:stretchMode
|
设置拉伸模式
NO_STRETCH 不拉伸
STRETCH_SPACING 仅拉伸元素之间的间距
STRETCH_SPACING_UNIFORM 表格元素本身、元素之间的间距一起拉伸
STRETCH_COLUMN_WIDTH 仅元素表格本身
|
android:verticalSpacing
|
设置各元素之间的垂直间距
|
示例代码:
public
class
MainActivity
extends
ActionBarActivity {
GridView grid ;
ImageView imageView ;
int [] imageIds = new int [] { R.drawable. bomb5 , R.drawable. bomb6 ,
R.drawable. bomb7 , R.drawable. bomb8 , R.drawable. bomb9 ,
R.drawable. bomb10 , R.drawable. bomb11 , R.drawable. bomb12 ,
R.drawable. bomb13 , R.drawable. bomb14 , R.drawable. bomb15 ,
R.drawable. bomb16 , };
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. activity_main );
List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();
for ( int i = 0; i < imageIds . length ; i++) {
Map<String, Object> listItem = new HashMap<String, Object>();
listItem.put( "image" , imageIds [i]);
listItems.add(listItem);
}
imageView = (ImageView) findViewById(R.id. imageView );
SimpleAdapter simpleAdapter = new SimpleAdapter( this , listItems,
R.layout. cell , new String[] { "image" },
new int [] { R.id. image1 });
grid = (GridView) findViewById(R.id. grid01 );
grid .setAdapter(simpleAdapter);
grid .setOnItemSelectedListener( new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
imageView .setImageResource( imageIds [position]);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
grid .setOnItemClickListener( new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
imageView .setImageResource( imageIds [position]);
}
GridView grid ;
ImageView imageView ;
int [] imageIds = new int [] { R.drawable. bomb5 , R.drawable. bomb6 ,
R.drawable. bomb7 , R.drawable. bomb8 , R.drawable. bomb9 ,
R.drawable. bomb10 , R.drawable. bomb11 , R.drawable. bomb12 ,
R.drawable. bomb13 , R.drawable. bomb14 , R.drawable. bomb15 ,
R.drawable. bomb16 , };
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. activity_main );
List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();
for ( int i = 0; i < imageIds . length ; i++) {
Map<String, Object> listItem = new HashMap<String, Object>();
listItem.put( "image" , imageIds [i]);
listItems.add(listItem);
}
imageView = (ImageView) findViewById(R.id. imageView );
SimpleAdapter simpleAdapter = new SimpleAdapter( this , listItems,
R.layout. cell , new String[] { "image" },
new int [] { R.id. image1 });
grid = (GridView) findViewById(R.id. grid01 );
grid .setAdapter(simpleAdapter);
grid .setOnItemSelectedListener( new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
imageView .setImageResource( imageIds [position]);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
grid .setOnItemClickListener( new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
imageView .setImageResource( imageIds [position]);
}
});
}
}
xml代码:cell.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 = "fill_parent"
android:gravity = "center_horizontal"
android:padding = "2pt"
>
< ImageView
android:id = "@+id/image1"
android:layout_width = "50dp"
android:layout_height = "50dp"
/>
< LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
android:orientation = "horizontal"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"
android:gravity = "center_horizontal"
android:padding = "2pt"
>
< ImageView
android:id = "@+id/image1"
android:layout_width = "50dp"
android:layout_height = "50dp"
/>
</
LinearLayout
>
2.5.5 可展开的列表组件 ExpandableListView
ExpandableListView是ListView子类,它在普通ListView的基础上进行了扩展,它把应用中的列表项分为几组,每组可包含多个列表项
其所显示的列表项应该由ExpandableListAdapter提供。实现ExpandableListAdapter有如下三种方式:
1.扩展BaseExpandableListAdapter实现ExpandableListAdapter
2.使用SimpleExpandableListAdapter将两个List集合包装成ExpandableListAdapter
3.使用SimpleCursorTreeAdapter将Cursor中的数据包装成SimpleCursor-TreeAdapter
ExpandableListView所额外支持的常用xml属性有:
android:childDivider
|
指定各组内列表项之间的分隔条
|
android:childIndicator
|
显示在子列表旁边的Drawable对象
|
android:groupIndicator
|
显示在组列表项旁边的Drawable对象
|
示例代码:main.xml
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
< LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
android:orientation = "vertical"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"
>
< ExpandableListView
android:id = "@+id/list"
android:layout_width = "fill_parent"
android:layout_height = "wrap_content"
android:childIndicator = "@drawable/ic_launcher"
/>
< LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
android:orientation = "vertical"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"
>
< ExpandableListView
android:id = "@+id/list"
android:layout_width = "fill_parent"
android:layout_height = "wrap_content"
android:childIndicator = "@drawable/ic_launcher"
/>
</
LinearLayout
>
Java程序代码:
public
class
MainActivity
extends
ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. activity_main );
ExpandableListAdapter adapter = new BaseExpandableListAdapter()
{
int [] logos = new int []
{
R.drawable. p ,
R.drawable. z ,
R.drawable. t
};
private String[] armTypes = new String[]
{ "GodArmy" , "IncideArmy" , "HumanArmy" };
private String[][] arms = new String[][]
{
{ "Yeal" , "Dragon" , "Flyer" },
{ "Pets" , "Ants" },
{ "Nurse" , "Sodiler" }
};
@Override
public Object getChild( int groupPosition, int childPosition)
{
return arms [groupPosition][childPosition];
}
@Override
public long getChildId( int groupPosition, int childPosition)
{
return childPosition;
}
@Override
public int getChildrenCount( int groupPosition)
{
return arms [groupPosition]. length ;
}
private TextView getTextView()
{
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
ViewGroup.LayoutParams. MATCH_PARENT , 64);
TextView textView = new TextView(MainActivity. this );
textView.setLayoutParams(lp);
textView.setGravity(Gravity. CENTER_VERTICAL |Gravity. LEFT );
textView.setPadding(36, 0, 0, 0);
textView.setTextSize(20);
return textView;
}
@Override
public View getChildView( int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent)
{
TextView textView = getTextView();
textView.setText(getChild(groupPosition,childPosition).toString());
return textView;
}
@Override
public Object getGroup( int groupPosition)
{
return armTypes [groupPosition];
}
@Override
public int getGroupCount()
{
return armTypes . length ;
}
@Override
public long getGroupId( int groupPosition)
{
return groupPosition;
}
@Override
public View getGroupView( int groupPosition,
boolean isExpanded, View convertView, ViewGroup parent)
{
LinearLayout ll = new LinearLayout(MainActivity. this );
ll.setOrientation(0);
ImageView logo = new ImageView(MainActivity. this );
logo.setImageResource( logos [groupPosition]);
ll.addView(logo);
TextView textView = getTextView();
textView.setText(getGroup(groupPosition).toString());
ll.addView(textView);
return ll;
}
@Override
public boolean isChildSelectable( int groupPosition,
int childPosition)
{
return true ;
}
@Override
public boolean hasStableIds()
{
return true ;
}
};
ExpandableListView expandListView = (ExpandableListView) findViewById(R.id. list );
expandListView.setAdapter(adapter);
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. activity_main );
ExpandableListAdapter adapter = new BaseExpandableListAdapter()
{
int [] logos = new int []
{
R.drawable. p ,
R.drawable. z ,
R.drawable. t
};
private String[] armTypes = new String[]
{ "GodArmy" , "IncideArmy" , "HumanArmy" };
private String[][] arms = new String[][]
{
{ "Yeal" , "Dragon" , "Flyer" },
{ "Pets" , "Ants" },
{ "Nurse" , "Sodiler" }
};
@Override
public Object getChild( int groupPosition, int childPosition)
{
return arms [groupPosition][childPosition];
}
@Override
public long getChildId( int groupPosition, int childPosition)
{
return childPosition;
}
@Override
public int getChildrenCount( int groupPosition)
{
return arms [groupPosition]. length ;
}
private TextView getTextView()
{
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
ViewGroup.LayoutParams. MATCH_PARENT , 64);
TextView textView = new TextView(MainActivity. this );
textView.setLayoutParams(lp);
textView.setGravity(Gravity. CENTER_VERTICAL |Gravity. LEFT );
textView.setPadding(36, 0, 0, 0);
textView.setTextSize(20);
return textView;
}
@Override
public View getChildView( int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent)
{
TextView textView = getTextView();
textView.setText(getChild(groupPosition,childPosition).toString());
return textView;
}
@Override
public Object getGroup( int groupPosition)
{
return armTypes [groupPosition];
}
@Override
public int getGroupCount()
{
return armTypes . length ;
}
@Override
public long getGroupId( int groupPosition)
{
return groupPosition;
}
@Override
public View getGroupView( int groupPosition,
boolean isExpanded, View convertView, ViewGroup parent)
{
LinearLayout ll = new LinearLayout(MainActivity. this );
ll.setOrientation(0);
ImageView logo = new ImageView(MainActivity. this );
logo.setImageResource( logos [groupPosition]);
ll.addView(logo);
TextView textView = getTextView();
textView.setText(getGroup(groupPosition).toString());
ll.addView(textView);
return ll;
}
@Override
public boolean isChildSelectable( int groupPosition,
int childPosition)
{
return true ;
}
@Override
public boolean hasStableIds()
{
return true ;
}
};
ExpandableListView expandListView = (ExpandableListView) findViewById(R.id. list );
expandListView.setAdapter(adapter);
}
}
扩展BaseExpandableListAdapter时,关键是实现如下4个方法:
getGroupCount()
getGroupView()
getChildrenCount()
getChildView()
2.5.6 Spinner的功能与用法
Spinner就是一个列表选择框,二十弹出一个菜单供用户选择
Spinner与Gallery都继承了AbsSpinner,AbsSpinner继承了AdapterView,因此它也表现出AdapterView的特征:只要为AdapterView提供Adapter即可
Spinner支持的常用XML属性如下:
android:entries
|
|
使用数组资源设置该下拉列表框的列表项目
|
android:dropDownHorizontalOffset
|
|
设置下拉列表框的水平偏移距离
|
android:dropDownVerticalOffset
|
|
设置下拉列表框的垂直偏移距离
|
android:dropDownWidth
|
|
设置下拉列表框的宽度
|
android:popupBackground
|
|
设置下拉列表框的背景色
|
android:prompt
|
|
设置该列表选择框的提示信息
|
android:entries属性并不是Spinner定义的,后面介绍的Gallery也支持该xml属性
oops
arrays.xml(注意s)在main.xml中的引用方法是(示例):
android:entries="@array/books"
另外,string-array无大写
2.5.7 Gallery的功能与用法
Gallery & Spinner有共同的父类:AbsSpinner,Gallery & Spinner都是一个列表框,区别在于:
1.Gallery显示的是一个垂直的列表框
2.Spinner供用户选择,而Gallery则允许用户通过拖动来查看上一个、下一个列表项
Gallery额外提供了如下的XML属性:
android:animationDuration
|
|
设置图片切换时的动画持续时间
|
android:gravity
|
|
设置对齐方式
|
android:spacing
|
|
设置图片之间的间距
|
android:unselectedAlpha
|
|
设置没有选中的图片的透明度
|
Gallery本身的用法非常简单——基本与Spinner用法相似,只要为它提供一个内容Adapter即可,该Adapter的getView方法所返回的View将作为Gallery的列表项;可通过为Gallery添加OnItemSelectedListener监听器即可实现
Android已经不再推荐使用Gallery组件,而是推荐使用其他水平滚动组件如HorizontalScrollView和ViewPager来代替Gallery组件
2.5.8 AdapterViewFlipper的功能与用法
AdapterViewFlipper继承了AdapterViewAnimator,它也会显示Adapter提供的多个组件,但它每次只能显示一个,程序通过showPrevious()和showNext()方法控制该组件显示上一个、下一个组件
AdapterViewFlipper可以在多个View切换过程中使用渐隐渐显的动画效果,还可以调用startFlipping()控制它自动播放下一个View组件
可指定的XML属性有:
android:animateFirstView
|
设置显示该组件的第一个View时是否使用动画
|
android:inAnimation
|
设置该组件显示时使用的动画
|
android:loopViews
|
设置循环到最后一个组件后是否自动“转头”到第一个组件
|
android:outAnimation
|
设置隐藏时使用的动画
|
android:autoStart
|
|
android:flipInterval
|
自动播放时间间隔
|
示例代码如下:
xml
<
RelativeLayout
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"
>
< AdapterViewFlipper
android:id = "@+id/flipper"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:flipInterval = "1000"
android:layout_alignParentTop = "true"
></ AdapterViewFlipper >
< Button
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentBottom = "true"
android:layout_alignParentLeft = "true"
android:onClick = "prev"
android:text = "previous one"
/>
< Button
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentBottom = "true"
android:layout_centerHorizontal = "true"
android:onClick = "next"
android:text = "next one"
/>
< Button
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentBottom = "true"
android:layout_alignParentRight = "true"
android:onClick = "auto"
android:text = "play gallery"
/>
xmlns:tools = "http://schemas.android.com/tools"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
>
< AdapterViewFlipper
android:id = "@+id/flipper"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:flipInterval = "1000"
android:layout_alignParentTop = "true"
></ AdapterViewFlipper >
< Button
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentBottom = "true"
android:layout_alignParentLeft = "true"
android:onClick = "prev"
android:text = "previous one"
/>
< Button
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentBottom = "true"
android:layout_centerHorizontal = "true"
android:onClick = "next"
android:text = "next one"
/>
< Button
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentBottom = "true"
android:layout_alignParentRight = "true"
android:onClick = "auto"
android:text = "play gallery"
/>
</
RelativeLayout
>
Java代码
public
class
MainActivity
extends
ActionBarActivity {
int [] imageIds = new int [] { R.drawable. shuangzi , R.drawable. shuangyu ,
R.drawable. chunv , R.drawable. tiancheng , R.drawable. tianxie ,
R.drawable. sheshou , R.drawable. juxie , R.drawable. shuiping ,
R.drawable. shizi , R.drawable. baiyang , R.drawable. jinniu ,
R.drawable. mojie };
AdapterViewFlipper flipper ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. activity_main );
flipper = (AdapterViewFlipper) findViewById(R.id. flipper );
BaseAdapter adapter = new BaseAdapter(){
@Override
public int getCount()
{
return imageIds . length ;
}
@Override
public Object getItem( int position)
{
return position;
}
@Override
public long getItemId( int position)
{
return position;
}
//
@Override
public View getView( int position, View convertView, ViewGroup parent)
{
//
ImageView imageView = new ImageView(MainActivity. this );
imageView.setImageResource( imageIds [position]);
//
imageView.setScaleType(ImageView.ScaleType. FIT_XY );
//
imageView.setLayoutParams( new LayoutParams(
LayoutParams. MATCH_PARENT , LayoutParams. MATCH_PARENT
));
return imageView;
}
};
flipper .setAdapter(adapter);
}
public void prev(View source)
{
flipper .showPrevious();
flipper .stopFlipping();
}
public void next(View source)
{
flipper .showNext();
flipper .stopFlipping();
}
public void auto(View source)
{
flipper .startFlipping();
int [] imageIds = new int [] { R.drawable. shuangzi , R.drawable. shuangyu ,
R.drawable. chunv , R.drawable. tiancheng , R.drawable. tianxie ,
R.drawable. sheshou , R.drawable. juxie , R.drawable. shuiping ,
R.drawable. shizi , R.drawable. baiyang , R.drawable. jinniu ,
R.drawable. mojie };
AdapterViewFlipper flipper ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. activity_main );
flipper = (AdapterViewFlipper) findViewById(R.id. flipper );
BaseAdapter adapter = new BaseAdapter(){
@Override
public int getCount()
{
return imageIds . length ;
}
@Override
public Object getItem( int position)
{
return position;
}
@Override
public long getItemId( int position)
{
return position;
}
//
@Override
public View getView( int position, View convertView, ViewGroup parent)
{
//
ImageView imageView = new ImageView(MainActivity. this );
imageView.setImageResource( imageIds [position]);
//
imageView.setScaleType(ImageView.ScaleType. FIT_XY );
//
imageView.setLayoutParams( new LayoutParams(
LayoutParams. MATCH_PARENT , LayoutParams. MATCH_PARENT
));
return imageView;
}
};
flipper .setAdapter(adapter);
}
public void prev(View source)
{
flipper .showPrevious();
flipper .stopFlipping();
}
public void next(View source)
{
flipper .showNext();
flipper .stopFlipping();
}
public void auto(View source)
{
flipper .startFlipping();
}
}
2.5.9 StackView的功能与用法
StackView也是AdapterViewAnimator的子类,它也用于显示Adapter提供的系列View。以堆叠方式显示多个列表项
提供了如下两种控制方式:
1.拖走StackView中处于顶端的View,下一个View将会显示出来。
2.通过调用StackView的showNext()、showPrevious()控制显示上一个、下一个组件
示例代码:
public
class
MainActivity
extends
ActionBarActivity {
StackView stackView ;
int [] imageIds = new int [] { R.drawable. shuangzi , R.drawable. shuangyu ,
R.drawable. chunv , R.drawable. tiancheng , R.drawable. tianxie ,
R.drawable. sheshou , R.drawable. juxie , R.drawable. shuiping ,
R.drawable. shizi , R.drawable. baiyang , R.drawable. jinniu ,
R.drawable. mojie };
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. activity_main );
stackView = (StackView) findViewById(R.id. mStackView );
List<Map<String, Object>> listItems =
new ArrayList<Map<String, Object>>();
for ( int i = 0; i < imageIds . length ; i++)
{
Map<String, Object> listItem = new HashMap<String, Object>();
listItem.put( "image" , imageIds [i]);
listItems.add(listItem);
}
StackView stackView ;
int [] imageIds = new int [] { R.drawable. shuangzi , R.drawable. shuangyu ,
R.drawable. chunv , R.drawable. tiancheng , R.drawable. tianxie ,
R.drawable. sheshou , R.drawable. juxie , R.drawable. shuiping ,
R.drawable. shizi , R.drawable. baiyang , R.drawable. jinniu ,
R.drawable. mojie };
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. activity_main );
stackView = (StackView) findViewById(R.id. mStackView );
List<Map<String, Object>> listItems =
new ArrayList<Map<String, Object>>();
for ( int i = 0; i < imageIds . length ; i++)
{
Map<String, Object> listItem = new HashMap<String, Object>();
listItem.put( "image" , imageIds [i]);
listItems.add(listItem);
}
SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems,
R.layout.cell, new String[]{"image"},new int[]{R.id.image1});
stackView
.setAdapter(simpleAdapter);
}
public void prev(View view)
{
stackView .showPrevious();
}
public void next(View source)
{
stackView .showNext();
}
public void prev(View view)
{
stackView .showPrevious();
}
public void next(View source)
{
stackView .showNext();
}
}
xml代码:
main.xml
<
RelativeLayout
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"
>
< AdapterViewFlipper
android:id = "@+id/flipper"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:flipInterval = "1000"
android:layout_alignParentTop = "true"
></ AdapterViewFlipper >
< Button
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentBottom = "true"
android:layout_alignParentLeft = "true"
android:onClick = "prev"
android:text = "previous one"
/>
< Button
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentBottom = "true"
android:layout_centerHorizontal = "true"
android:onClick = "next"
android:text = "next one"
/>
< Button
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentBottom = "true"
android:layout_alignParentRight = "true"
android:onClick = "auto"
android:text = "play gallery"
/>
xmlns:tools = "http://schemas.android.com/tools"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
>
< AdapterViewFlipper
android:id = "@+id/flipper"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:flipInterval = "1000"
android:layout_alignParentTop = "true"
></ AdapterViewFlipper >
< Button
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentBottom = "true"
android:layout_alignParentLeft = "true"
android:onClick = "prev"
android:text = "previous one"
/>
< Button
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentBottom = "true"
android:layout_centerHorizontal = "true"
android:onClick = "next"
android:text = "next one"
/>
< Button
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_alignParentBottom = "true"
android:layout_alignParentRight = "true"
android:onClick = "auto"
android:text = "play gallery"
/>
</
RelativeLayout
>
cell.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 = "fill_parent"
android:gravity = "center_horizontal"
android:padding = "2pt"
>
< ImageView
android:id = "@+id/image1"
android:layout_width = "120dp"
android:layout_height = "120dp"
/>
< LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
android:orientation = "horizontal"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"
android:gravity = "center_horizontal"
android:padding = "2pt"
>
< ImageView
android:id = "@+id/image1"
android:layout_width = "120dp"
android:layout_height = "120dp"
/>
</
LinearLayout
>