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 demo,baseAdapter的应用,
ListView与BaseAdapter的配套使用 理解android 中adapter适配的作用 以及ListView的优化方式
一个简单baseAdapter的封装demo.减少一些不必须要的重复的代码。
android中自定义适配器BaseAdapter
主要介绍了Android BaseAdapter应用方法,结合生成联系人Items的实例形式分析了BaseAdapter的使用技巧,需要的朋友可以参考下
android demo,BaseAdapter传递context的应用,
android BaseAdapter AsyncTask 异步加载
Android中ListView,SQLite,BaseAdapter的结合[参照].pdf
Android-扩展BaseAdapter实现progressBar下载 * 该Demo涉及了BaseAdapter,ProgressBar,Handler,Thread,线程池; * * Android-扩展BaseAdapter实现progressBar下载 * 1.创建listview的xml * 2.创建listview中...
BaseAdapter 是一个我写的adapter的基类,感觉还是比较用,希望大家多提意见
Android必学-BaseAdapter的使用与优化,写出高效、文艺的BaseAdapter, android studio环境
此文件为Eclipse下的android工程,里面介绍了listView的三种适配方式,从实现到优化。
主要介绍了Android中BaseAdapter用法,分析了BaseAdapter的功能、使用方法与相关注意事项,需要的朋友可以参考下
baseadapter
baseAdapter例子 适合新手学习,万能适配器
详细介绍android开发的BaseAdapter使用方法,提供各种代码例子!
主要介绍了Android中BaseAdapter的用法分析与理解,结合一个项目开发中BaseAdapter的使用分析了BaseAdapter的功能、作用及用法理解,需要的朋友可以参考下
Android自定义BaseAdapter,大大的节省代码量