布局及视图(三)
5、列表视图(List View)
列表布局:是一个ViewGroup以列表显示它的子视图(view)元素,列表是可滚动的列表。列表元素通过ListAdapter自动插入到列表。
ListAdapter
:扩展自Adapter
,它是ListView
和数据列表之间的桥梁。ListView可以显示任何包装在ListAdapter中的数据。该类提供两个公有类型的抽象方法:
- public abstract boolean areAllItemsEnabled () :表示ListAdapter中的所有元素是否可激活的?如果返回真,即所有的元素是可选择的即可点击的。
- public abstract boolean isEnabled (int position) :判断指定位置的元素是否可激活的?
下面通过一个例子来,创建一个可滚动的列表,并从一个字符串数组读取列表元素。当一个元素被选择时,显示该元素在列表中的位置的消息。
1)、首先,将res/layour/main.xml的内容置为如下:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp" >
</TextView>
2)、src/skynet.com.cnblogs.www/HelloWorld.java文件的代码如下: package skynet.com.cnblogs.www; import android.app.ListActivity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import android.widget.AdapterView.OnItemClickListener; public class HelloWorld extends ListActivity { //注意这里Helloworld类不是扩展自Acitvity,而是扩展自ListAcitivty /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setListAdapter(new ArrayAdapter<String>(this, R.layout.main, COUNTRIES)); ListView lv = getListView(); lv.setTextFilterEnabled(true); lv.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // When clicked, show a toast with the TextView text Toast.makeText(getApplicationContext(), ((TextView) view).getText(), Toast.LENGTH_SHORT).show(); } }); } static final String[] COUNTRIES = new String[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24" }; } Note:onCreate()函数中并不像往常一样通过setContentView()为活动(Activity)加载布局文件,替代的是通过
3)、运行应用程序得如下结果(点击1之后,在下面显示了1): 图7、列表布局 NOTE:如果你改了HelloWorld extends ListActivity 而不是Activity之后,运行程序是提示:“Conversion to Dalvik format failed with error 1”。可以这么解决:解决办法是 Project > Clean... > Clean project selected below > Ok 5.1、一个小的改进上面我们是把要填充到ListView中的元素硬编码到HelloWorld.java文件中,这样就缺乏灵活性!也不符合推荐的应用程序的界面与控制它行为的代码更好地分离的准则! 其实我们可以把要填充到ListView的元素写到 <?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="countries_array"> <item>1</item> <item>2</item> <item>3</item> <item>4</item> <item>5</item> <item>6</item> <item>7</item> </string-array> </resources> 然而HelloWorld.java文件中的onCreate()函数,则这样动态访问这个数组及填充到ListVies: 5.2、补充说明首先总结一下列表布局的关键部分:
其中Adapter是ListView和数据源之间的桥梁,根据数据源的不同Adapter可以分为三类:
使用ArrayAdapter(数组适配器)顾名思义,需要把数据放入一个数组以便显示,上面的例子就是这样的;SimpleAdapter能定义各种各样的布局出来,可以放上ImageView(图片),还可以放上Button(按钮),CheckBox(复选框)等等;SimpleCursorAdapter是和数据库有关的东西。篇幅有限后面两种就不举例实践了。你可以参考android ListView详解orArrayAdapter ,SimpleAdapter ,SimpleCursorAdapter 区别。 6、网格视图(Grid View)网格布局:是一个ViewGroup以网格显示它的子视图(view)元素,即二维的、滚动的网格。网格元素通过 下面也通过一个例子来,创建一个显示图片缩略图的网格。当一个元素被选择时,显示该元素在列表中的位置的消息。 1)、首先,将上面实践截取的图片放入 2)、res/layour/main.xml的内容置为如下:这个GridView填满整个屏幕,而且它的属性都很好理解,按英文单词的意思就对了。 <?xml version="1.0" encoding="utf-8"?> <GridView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/gridview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:columnWidth="90dp" android:numColumns="auto_fit" android:verticalSpacing="10dp" android:horizontalSpacing="10dp" android:stretchMode="columnWidth" android:gravity="center" /> 3)、然后,HelloWorld.java文件中onCreate()函数如下: public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); GridView gridview = (GridView) findViewById(R.id.gridview); gridview.setAdapter(new ImageAdapter(this)); gridview.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View v, int position, long id) { Toast.makeText(HelloWorld.this, " " + position, Toast.LENGTH_SHORT).show(); } }); }
onCreate()函数跟通常一样,首先调用超类的onCreate()函数函数,然后通过setContentView()为活动(Activity)加载布局文件。紧接着是,通过GridView的id获取布局文件中的gridview,然后调用它的 4)、实现我们自定义ImageAdapter,新添加一个类文件,它的代码如下: package skynet.com.cnblogs.www; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.GridView; import android.widget.ImageView; public class ImageAdapter extends BaseAdapter { private Context mContext; public ImageAdapter(Context c) { mContext = c; } public int getCount() { return mThumbIds.length; } public Object getItem(int position) { return null; } public long getItemId(int position) { return 0; } // create a new ImageView for each item referenced by the Adapter public View getView(int position, View convertView, ViewGroup parent) { ImageView imageView; if (convertView == null) { // if it's not recycled, initialize some attributes imageView = new ImageView(mContext); imageView.setLayoutParams(new GridView.LayoutParams(85, 85)); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); imageView.setPadding(8, 8, 8, 8); } else { imageView = (ImageView) convertView; } imageView.setImageResource(mThumbIds[position]); return imageView; } // references to our images private Integer[] mThumbIds = { R.drawable.linearlayout1, R.drawable.linearlayout2, R.drawable.linearlayout3, R.drawable.listview, R.drawable.relativelayout, R.drawable.tablelayout }; }
ImageAdapter类扩展自
如果View传到getView()不是空的,则本地的ImageView初始化时将循环再用View对象。在getView()方法末尾,position整数传入setImageResource()方法以从mThumbIds数组中选择图片。 运行程序会得到如下结果(点击第一张图片之后): 图8、网格布局 |