BaseAdapter就Android应用程序中经常用到的基础数据适配器,它的主要用途是将一组数据传到像ListView、Spinner、Gallery及GridView等UI显示组件,它是继承自接口类Adapter,
自定义Adapter子类,就需要实现上面几个方法,其中最重要的是getView()方法,它是将获取数据后的View组件返回,如ListView中每一行里的TextView、Gallery中的每个ImageView。
2)、Adapter在Android应用程序中起着非常重要的作用,应用也非常广泛,它可看作是数据源和UI组件之间的桥梁,其中Adapter、数据和UI之间的关系,可以用下图表示:
<?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"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Gallery
android:id="@+id/gallery1"
android:layout_width="match_parent"
android:spacing="5px"
android:layout_height="wrap_content"
></Gallery>
<ImageView
android:id="@+id/iv"
android:layout_gravity="center_vertical"
android:layout_marginTop="20px"
android:layout_width="320px"
android:layout_height="320px"
></ImageView>
</LinearLayout>

package com.magc.adapter;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.AdapterView.OnItemClickListener;
publicclass MainActivity extends Activity {
private Gallery gallery;
private ImageView imgview;
privateint[] imgs = {R.drawable.a6,R.drawable.a1,R.drawable.a2,R.drawable.a3,R.drawable.a4,R.drawable.a5};
/** Called when the activity is first created. */
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imgview = (ImageView)findViewById(R.id.iv);
gallery = (Gallery)findViewById(R.id.gallery1);
MyImgAdapter adapter =new MyImgAdapter(this);
gallery.setAdapter(adapter);
gallery.setOnItemClickListener(new OnItemClickListener() {
//用户点击图片时,将该图片的ResourceID设到下面的ImageView中去,
@Override
publicvoid onItemClick(AdapterView<?> arg0, View view, int position,
long arg3) {
imgview.setImageResource(imgs[position]);
}
});
}
class MyImgAdapter extends BaseAdapter {
//自定义图片Adapter以内部类形式存在于MainActivity中,方便访问MainActivity中的各个变量,特别是imgs数组
private Context context;//用于接收传递过来的Context对象
public MyImgAdapter(Context context) {
super();
this.context = context;
}
/* (non-Javadoc)
* @see android.widget.Adapter#getCount()
*/
@Override
publicint getCount() {
return imgs.length;
}
/* (non-Javadoc)
* @see android.widget.Adapter#getItem(int)
*/
@Override
public Object getItem(int position) {
return position;
}
/* (non-Javadoc)
* @see android.widget.Adapter#getItemId(int)
*/
@Override
publiclong getItemId(int position) {
return position;
}
/* (non-Javadoc)
* @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup)
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//针对每一个数据(即每一个图片ID)创建一个ImageView实例,
ImageView iv =new ImageView(context);//针对外面传递过来的Context变量,
iv.setImageResource(imgs[position]);
Log.i("magc", String.valueOf(imgs[position]));
iv.setLayoutParams(new Gallery.LayoutParams(80, 80));//设置Gallery中每一个图片的大小为80*80。
iv.setScaleType(ImageView.ScaleType.FIT_XY);
return iv;
}
}
}

Android ListView使用BaseAdapter与ListView的优化
在ListView的使用中,有时候还需要在里面加入按钮等控件,实现单独的操作。也就是说,这个ListView不再只是展示数据,也不仅仅是这一行要来处理用户的操作,而是里面的控件要获得用户的焦点。读者可以试试用SimpleAdapter添加一个按钮到ListView的条目中,会发现可以添加,但是却无法获得焦点,点击操作被ListView的Item所覆盖。这时候最方便的方法就是使用灵活的适配器BaseAdapter了。

▲图4-35 BaseAdapter中的方法
使用BaseAdapter必须写一个类继承它,同时BaseAdapter是一个抽象类,继承它必须实现它的方法。BaseAdapter的灵活性就在于它要重写很多方法,看一下有哪些方法,如图4-35所示为继承自BaseAdapter的SpeechListAdapter所实现的方法,其中最重要的即为getView()方法。这些方法都有什么作用呢?我们通过分析ListView的原理来为读者解答。
当系统开始绘制ListView的时候,首先调用getCount()方法。得到它的返回值,即ListView的长度。然后系统调用getView()方法,根据这个长度逐一绘制ListView的每一行。也就是说,如果让getCount()返回1,那么只显示一行。而getItem()和getItemId()则在需要处理和取得Adapter中的数据时调用。那么getView如何使用呢?如果有10000行数据,就绘制10000次?这肯定会极大的消耗资源,导致ListView滑动非常的慢,那应该怎么做呢?通过一个例子来讲解如何在使用BaseAdapter的时候优化ListView的显示。例子中将上一节中的ImageView换成Button,并且处理Button的点击事件,其中对ListView的显示做了优化。
布局文件和上一例类同,读者可以在光盘的工程目录中查看,这里只给出Activity类。
001 |
publicclass MyListViewBase extends Activity {
|
005 |
ArrayList<HashMap<String, Object>>listItem; /** Called when the activity is first created. */
|
008 |
publicvoid onCreate(Bundle savedInstanceState) {
|
009 |
super .onCreate(savedInstanceState);
|
010 |
setContentView(R.layout.main);
|
012 |
lv = (ListView) findViewById(R.id.lv);
|
013 |
MyAdapter mAdapter = new MyAdapter( this );
|
014 |
lv.setAdapter(mAdapter);
|
016 |
lv.setOnItemClickListener( new OnItemClickListener() {
|
018 |
publicvoid onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
|
019 |
Log.v( "MyListViewBase" , "你点击了ListView条目" + arg2);
|
023 |
/**添加一个得到数据的方法,方便使用*/
|
024 |
private ArrayList<HashMap<String, Object>> getDate(){
|
025 |
ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String,Object>>();
|
027 |
for ( int i= 0 ;i< 30 ;i++)
|
029 |
HashMap<String, Object> map = new HashMap<String, Object>();
|
030 |
map.put( "ItemTitle" , "第" +i+ "行" );
|
031 |
map.put( "ItemText" , "这是第" +i+ "行" );
|
036 |
/** 新建一个类继承BaseAdapter,实现视图与数据的绑定
|
038 |
privateclass MyAdapter extends BaseAdapter {
|
039 |
private LayoutInflater mInflater;
|
042 |
public MyAdapter(Context context) {
|
043 |
this .mInflater = LayoutInflater.from(context);
|
047 |
publicint getCount() {
|
048 |
return getDate().size();
|
052 |
public Object getItem( int position) {
|
057 |
publiclong getItemId( int position) {
|
063 |
public View getView(finalint position, View convertView, ViewGroup parent) {
|
066 |
Log.v( "MyListViewBase" , "getView " + position + " " + convertView);
|
067 |
if (convertView == null ) {
|
068 |
convertView = mInflater.inflate(R.layout.item, null );
|
069 |
holder = new ViewHolder();
|
071 |
holder.title = (TextView) convertView.findViewById(R.id.ItemTitle);
|
072 |
holder.text = (TextView) convertView.findViewById(R.id.ItemText);
|
073 |
holder.bt = (Button) convertView.findViewById(R.id.ItemButton);
|
074 |
convertView.setTag(holder);
|
077 |
holder = (ViewHolder)convertView.getTag();
|
079 |
/**设置TextView显示的内容,即我们存放在动态数组中的数据*/ |
080 |
holder.title.setText(getDate().get(position).get( "ItemTitle" ).toString());
|
081 |
holder.text.setText(getDate().get(position).get( "ItemText" ).toString());
|
084 |
holder.bt.setOnClickListener( new OnClickListener() {
|
086 |
publicvoid onClick(View v) {
|
087 |
Log.v( "MyListViewBase" , "你点击了按钮" + position);
|
097 |
publicfinalclass ViewHolder{
|
098 |
public TextView title;
|
099 |
public TextView text;
|
运行效果如图4-36所示。还需要注意的是,Button会抢夺ListView的焦点,需要将Button设置为没有焦点。设置非常简单,只需要在xml的Button标签下加入一行:android:focusable=“false”代码就可以了。在LogCat观察点击后输出的信息,如图4-37所示。
▲图4-36 使用BaseAdapter的ListVie
w
▲图4-37 点击ListView条目和Button得到的输出
代码中getView()方法不容易理解。其实完全可以不用所谓的convertView和ViewHolder,直接导入布局并且设置控件显示的内容就可以了。但是这意味着有多少行数据就需要绘制多少行ListView,这显然是不可取的。这里采用了一种优化的方法。代码中,在getView()方法中加入了一行log输出convertView的内容。滚动ListView,输出信息如图4-38所示。
从图4-38中可以看出,当启动Activity呈现第一屏ListView的时候,convertView为零。当用户向下滚动ListView时,上面的条目变为不可见,下面出现新的条目。这时候convertView不再为空,而是创建了一系列的convertView的值。当又往下滚一屏的时候,发现第11行的容器用来容纳第22行,第12行的容器用来容纳第23行。也就是说convertView相当于一个缓存,开始为0,当有条目变为不可见,它缓存了它的数据,后面再出来的条目只需要更新数据就可以了,这样大大节省了系统资料的开销。
还可以继续优化。虽然重复利用了已经绘制的view,但是要得到其中的控件,需要在控件的容器中通过findViewById的方法来获得。如果这个容器非常复杂,这显然会增加系统资源的开销。在上面的例子中,引入了Tag的概念。或许不是最好的办法,但是它确实能使ListView变得更流畅。代码中,当convertView为空时,用setTag()方法为每个View绑定一个存放控件的ViewHolder对象。当convertView不为空,重复利用已经创建的view的时候,使用getTag()方法获取绑定的ViewHolder对象,这样就避免了findViewById对控件的层层查询,而是快速定位到控件。

▲图4-38 滚动ListView输出的convertView的值
总结一下,这节介绍了用BaseAdapter来绑定ListView的数据。因为BaseAdapter非常灵活,使用也相对较其他控件麻烦。同时ListView的优化问题也值得读者去研究,一个流畅的ListView会带来更好的用户体验。
http://blog.csdn.net/wangjia55/article/details/7430759
http://www.oschina.net/code/snippet_203635_7475
[代码] 主类
01 |
package com.android.wei.zidingyib;
|
03 |
import android.app.Activity;
|
04 |
import android.app.AlertDialog;
|
05 |
import android.os.Bundle;
|
06 |
import android.view.View;
|
07 |
import android.view.View.OnClickListener;
|
08 |
import android.widget.ImageButton;
|
09 |
import android.widget.ListView;
|
12 |
public class MyActivity extends Activity {
|
14 |
private ListView listView;
|
15 |
private ImageButton imageButton;
|
16 |
private ListViewAdapter listViewAdapter;
|
17 |
private List<Map<String,Object>> listItems;
|
18 |
private Integer[] imgeIDs = {
|
19 |
R.drawable.niao,R.drawable.niao,R.drawable.rui,R.drawable.rui,
|
20 |
R.drawable.ning,R.drawable.ning
|
22 |
private String[] goodsNames={
|
23 |
"土豆丝" , "土豆块" , "土豆泥" , "红烧土豆" ,
|
26 |
private String[] goodsDetails={
|
27 |
"土豆丝:便宜又好吃" , "土豆丝:便宜又好吃" , "土豆丝:便宜又好吃" ,
|
28 |
"土豆丝:便宜又好吃" , "土豆丝:便宜又好吃" , "土豆丝:便宜又好吃" ,
|
34 |
public void onCreate(Bundle savedInstanceState) {
|
35 |
super .onCreate(savedInstanceState);
|
36 |
setContentView(R.layout.main);
|
37 |
listView=(ListView) this .findViewById(R.id.listview);
|
38 |
imageButton = (ImageButton) this .findViewById(R.id.imagebutton);
|
39 |
imageButton.setOnClickListener( new ClickEvent());
|
40 |
listItems = getListItems();
|
41 |
listViewAdapter = new ListViewAdapter( this ,listItems);
|
42 |
listView.setAdapter(listViewAdapter);
|
44 |
private List<Map<String,Object>> getListItems(){
|
45 |
List<Map<String,Object>> listItems = new ArrayList<Map<String,Object>>();
|
46 |
for ( int i= 0 ;i<goodsNames.length;i++){
|
47 |
Map<String,Object> map = new HashMap<String,Object>();
|
48 |
map.put( "image" , imgeIDs[i]);
|
49 |
map.put( "title" , goodsNames[i]);
|
50 |
map.put( "info" , money[i]+ "元" );
|
51 |
map.put( "detail" , goodsDetails[i]);
|
56 |
class ClickEvent implements OnClickListener{
|
57 |
public void onClick(View v){
|
60 |
for ( int i= 0 ;i<listItems.size();i++){
|
61 |
goodsList += listViewAdapter.hasChecked(i)?goodsNames[i]+ " " : "" ;
|
62 |
sun +=listViewAdapter.hasChecked(i)?money[i]: 0 ;
|
65 |
new AlertDialog.Builder(MyActivity. this )
|
67 |
.setMessage( "你好,你选择的菜:\n" +goodsList+ "\n" + "总消费额为:" +sun+ "元" )
|
68 |
.setPositiveButton( "确定" , null )
|
[代码] 自定义的类
001 |
package com.android.wei.zidingyib;
|
003 |
import java.util.List;
|
004 |
import java.util.Map;
|
006 |
import android.app.AlertDialog;
|
007 |
import android.content.Context;
|
008 |
import android.view.LayoutInflater;
|
009 |
import android.view.View;
|
010 |
import android.view.ViewGroup;
|
011 |
import android.widget.BaseAdapter;
|
012 |
import android.widget.Button;
|
013 |
import android.widget.CheckBox;
|
014 |
import android.widget.CompoundButton;
|
015 |
import android.widget.ImageView;
|
016 |
import android.widget.TextView;
|
018 |
public class ListViewAdapter extends BaseAdapter{
|
019 |
private Context context;
|
021 |
private List<Map<String,Object>> listItems;
|
023 |
private LayoutInflater listContainer;
|
025 |
private boolean [] hasChecked;
|
026 |
public final class ListItemView{
|
027 |
public ImageView image;
|
028 |
public TextView title;
|
029 |
public TextView info;
|
030 |
public CheckBox check;
|
031 |
public Button detail;
|
034 |
public ListViewAdapter(Context context,List<Map<String,Object>> listItems){
|
035 |
this .context = context;
|
036 |
listContainer = LayoutInflater.from(context);
|
037 |
this .listItems = listItems;
|
038 |
hasChecked = new boolean [getCount()];
|
041 |
public int getCount() {
|
043 |
return listItems.size();
|
047 |
public Object getItem( int position) {
|
053 |
public long getItemId( int position) {
|
057 |
private void checkedChange( int checkedID){
|
058 |
hasChecked[checkedID] = !hasChecked[checkedID];
|
060 |
public boolean hasChecked( int checkedID){
|
061 |
return hasChecked[checkedID];
|
063 |
private void showDetailInfo( int clickID){
|
064 |
new AlertDialog.Builder(context)
|
065 |
.setTitle( "本菜详情:" +listItems.get(clickID).get( "title" ))
|
066 |
.setMessage(listItems.get(clickID).get( "detail" ).toString())
|
067 |
.setPositiveButton( "确定" , null )
|
072 |
public View getView( int position, View convertView, ViewGroup parent) {
|
073 |
final int selectID= position;
|
074 |
ListItemView listItemView = null ;
|
075 |
if (convertView == null ){
|
076 |
listItemView = new ListItemView();
|
077 |
convertView = listContainer.inflate(R.layout.list_item, null );
|
079 |
listItemView.image =(ImageView) convertView.findViewById(R.id.imageitem);
|
080 |
listItemView.title =(TextView) convertView.findViewById(R.id.textview);
|
081 |
listItemView.info =(TextView) convertView.findViewById(R.id.textview1);
|
082 |
listItemView.detail=(Button) convertView.findViewById(R.id.button);
|
083 |
listItemView.check = (CheckBox) convertView.findViewById(R.id.checkItem);
|
085 |
convertView.setTag(listItemView);
|
087 |
listItemView = (ListItemView) convertView.getTag();
|
090 |
listItemView.image.setBackgroundResource((Integer)listItems.get(position).get( "image" ));
|
091 |
listItemView.title.setText((String)listItems.get(position).get( "title" ));
|
092 |
listItemView.info.setText((String) listItems.get(position).get( "info" ));
|
093 |
listItemView.detail.setText( "本菜介绍" );
|
094 |
listItemView.detail.setOnClickListener( new View.OnClickListener() {
|
097 |
public void onClick(View v) {
|
099 |
showDetailInfo(selectID);
|
102 |
listItemView.check.setOnCheckedChangeListener( new CheckBox.OnCheckedChangeListener(){
|
103 |
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked){
|
104 |
checkedChange(selectID);
|
相关推荐
在Android开发中,BaseAdapter是一个基础的适配器类,用于将数据与UI组件(如ListView、GridView等)进行绑定。这个"android baseAdapter的简单封装demo"旨在提供一种方式来减少开发过程中对BaseAdapter的重复编码,...
这个“android demo,baseAdapter的应用”示例将深入讲解BaseAdapter的工作原理及其在实际项目中的应用。 BaseAdapter是Android SDK提供的一种适配器类,它是所有自定义适配器的基础。它的主要职责是将数据源(通常...
BaseAdapter是一个抽象类,它为Adapter提供了基础的实现,常用于自定义数据适配器。如果标准的Adapter类(如ArrayAdapter或CursorAdapter)不能满足特定的需求,开发者可以通过继承BaseAdapter并重写相应的方法来自...
在Android开发中,BaseAdapter是一个基础且至关重要的组件,它为ListView、GridView等视图提供数据绑定的功能。本文将深入探讨BaseAdapter的使用方法以及如何对其进行优化,让你在使用Android Studio开发时能写出...
在Android开发中,`BaseAdapter`是一个至关重要的组件,它为ListView、GridView等视图控件提供了数据适配的功能。...学习`BaseAdapter`,不仅可以提升开发效率,还能帮助你更好地理解Android应用的UI设计和数据管理。
首先,`BaseAdapter`是Android SDK提供的一种抽象类,它是所有自定义适配器的基础。开发者需要继承`BaseAdapter`并实现其方法,以便为特定的数据集合提供视图。主要需要实现的方法有以下几个: 1. `getCount()`: ...
BaseAdapter是Android SDK提供的一种抽象适配器类,它为自定义适配器提供了一个基础模板。开发者可以根据实际需求继承BaseAdapter,重写其中的方法,以实现将自定义数据与视图的适配。BaseAdapter的主要职责是将...
BaseAdapter就Android应用程序中经常用到的基础数据适配器,它的主要用途是将一组数据传到像ListView、Spinner、Gallery及GridView等UI显示组件,它是继承自接口类Adapter BaseAdapter Java代码: public class ...
Android Activity 是 Android 应用的基础组件之一,用于描述应用程序的生命周期。 Activity 可以启动其他 Activity,实现应用程序之间的交互。 六、Intent 七大属性 Android Intent 是 Android 应用中的一个重要...
BaseAdapter是所有自定义Adapter的基础,它是一个抽象类,负责连接数据源和ListView。BaseAdapter提供了四个主要的抽象方法,开发者需要重写这些方法以实现自定义功能: 1. `getCount()`: 这个方法返回列表中的条目...
在Android开发中,`ListActivity`和`BaseAdapter`是两个关键组件,它们共同用于创建显示数据列表的应用界面。理解并熟练使用这两个组件对于构建用户友好的、数据驱动的Android应用至关重要。 `ListActivity`是...
BaseAdapter是Android SDK提供的一种适配器类,它是所有自定义适配器的基础。它的主要职责是作为数据源与UI视图之间的桥梁,将数据转化为视图元素显示在界面上。BaseAdapter的核心方法包括:`getCount()`(返回数据...
BaseAdapter是Android开发中一...总结来说,高度封装的BaseAdapter是Android开发中的一种最佳实践,它通过优化性能、提供便捷的API和扩展性,帮助开发者更高效地管理数据和视图的交互,是Android应用开发中的得力助手。
`BaseAdapter` 是一个基础的适配器类,通常被用来连接数据源与`RecyclerView`,实现数据到视图的绑定。在描述中提到的"baseAdapter",就是一种自定义的适配器,专门用于`RecyclerView`,以简化开发流程。 `...
BaseAdapter是Android开发中用于填充ListView、GridView等控件的一种自定义适配器。它允许开发者根据自己的数据模型创建自定义视图,并将其绑定到列表或网格中。本篇文章将详细解析BaseAdapter的使用,包括其核心...
BaseAdapter是Android SDK提供的一种基础适配器类,它是所有自定义适配器的基类。它的主要职责是将数据集合与视图进行桥接,使得数据可以被可滚动视图显示。通过继承BaseAdapter并重写其必要的方法,我们可以根据...
`BaseAdapter`则是Android中用于适配数据源到各种可滚动视图(如ListView、GridView和Gallery)的基础类。 `Gallery`组件的特性: 1. **水平滚动**:与ListView垂直滚动不同,Gallery允许用户水平滑动查看项目。 2....
Android高手进阶教程之----Android中万能的BaseAdapter(Spinner,ListView,GridView)的使用!.doc Android高手进阶教程之----通过Location获取Address的使用.doc Android基础教程之----Android ProgressBar的使用.doc...
`BaseAdapter`是Android中的基础适配器类,它允许我们创建自定义的适配器,以便在ListView等组件中展示自定义的数据。当我们需要在列表中展示的数据不是默认的数据类型或者需要自定义视图时,就需要使用`BaseAdapter...
在Android开发中,`BaseAdapter` 是一个非常重要的组件,它是连接数据源和视图(ListView、GridView等)的关键桥梁。本篇文章将详细介绍如何自定义一个通用的`BaseAdapter`,以便于在多个不同的列表视图中重用,减少...