Android中有许多的适配器,这些适配器的作用往往是用于提供填充数据的,一般如下拉选框Spinner,列表ListView和九宫格GridView都需要用到适配器来填充数据。尽管每一个都有其自己的适配器,但是在使用中,由于其自身的适配器比较麻烦,通常都会使用BaseAdapter这一通用的神器来进行数据填充。
在这里解释下为什么BaseAdapter是通用的:BaseAdapter实现了ListAdapter和SpinnerAdapter的接口,而GridView的适配器是实现了ListAdapter接口,所以说BaseAdapter对他们三者来说是通用的。
在BaseAdapter中,主要有以下几个方法,要来实现:
private class BaseAdapter{
@Override
public int getCount() {
// TODO Auto-generated method stub
return 0;
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
return null;
}
}
下面通过实例来加强理解:
先上一张效果图
上面是一个Spinner,中间是一个GridView,下面是一个ListView
首先给出Layout文件
主布局文件,主要是放置了三个控件,GridView设置为4列的
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" tools:context=".MainActivity">
<Spinner
android:id="@+id/spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"></Spinner>
<GridView
android:id="@+id/gridview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:numColumns="4"></GridView>
<ListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"></ListView>
</LinearLayout>
图标布局文件,由上面一个图标,下面文字来构成
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<ImageView
android:id="@+id/item_icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="16dp"
android:src="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="15sp"/>
</LinearLayout>
最后直接上代码
package com.baseadapterdemo;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import java.util.zip.Inflater;
public class MainActivity extends Activity {
//声明的三个实例变量
private Spinner mSpinner;
private GridView mGridView;
private ListView mListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化设置
initView();
}
/**
* 初始化及设置适配器
*/
private void initView() {
mSpinner= (Spinner) findViewById(R.id.spinner);
mSpinner.setAdapter(new DemoAdapter());
mGridView= (GridView) findViewById(R.id.gridview);
mGridView.setAdapter(new DemoAdapter());
mListView= (ListView) findViewById(R.id.listview);
mListView.setAdapter(new DemoAdapter());
}
/**
* 定义自己的适配器,继承自BaseAdapter
* 注意继承的方法的使用
*/
static class DemoAdapter extends BaseAdapter{
private String[] data = new String[] {
"足球", "篮球", "体操", "游泳",
"羽毛球", "排球", "田径", "射击",
};
@Override
public int getCount() {
//返回数据项个数,这里一共有8个
return data.length;
}
@Override
public Object getItem(int position) {
return data[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// position就是位置从0开始,convertView
//是Spinner,ListView中每一项要显示的view
//通常return 的view也就是convertView
//parent就是父窗体了,也就是Spinner,ListView,GridView了.
if(convertView==null){
//设置convertView布局格式为item_bundle
convertView= LayoutInflater.from(parent.getContext()).inflate(R.layout.item_bundle,parent,false);
//实例化bean,从convertView中获取
//(即从item_bundle中获取)
ViewBean vb=new ViewBean();
vb.icon= (ImageView) convertView.findViewById(R.id.item_icon);
vb.name= (TextView)convertView.findViewById(R.id.item_name);
convertView.setTag(vb);
}
ViewBean vb= (ViewBean) convertView.getTag();
//重新改变名称
vb.name.setText(data[position]);
//vb.icon.setImageResource(......);类似这样可以改变图标,找不到那么多图T_T
return convertView;
}
/**
* 利用bean来存储信息,图标和文字
*/
static class ViewBean{
ImageView icon;
TextView name;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
这里ViewBean一般的话都是的ViewHolder,用法基本一致。这么用的话可以利用都ListView等等的缓存机制还有不用重复使用findViewById,可以提高运行效率。
嗯?排版好像不是太好看。大家主要看一下继承BaseAdapter那一部分,比较精华。
没关系,Android Studio源码在这,大家可以去下载。