ListView和三种Adapter

1、ListView 

ListView主要用来进行数据列表,支持动态加入数据,支持自动滚屏。

如果想为ListView加入数据,也要使用Adapter来完成,根据不同的情况,需要加入以下几种Adapter

1)  ArrayAdapter:每行显示一条文本数据,可以使用这种Adapter。

2)  SimpleAdapter:每行显示多条文本数据,可以使用这种Adapter完成。

3)  自定义Adapter:行中存在要显示的图片,使用这种Adapter

1.1、ArrayAdapter

使用时与Spinner类似,直接通过ArrayAdapter就可以将数据显示到界面中。

public class MainActivity extends Activity {

	private ListView list;
	private ArrayAdapter<String> adapter;

	private List<String> allValues = new ArrayList<String>();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// 设置默认使用的布局文件
		setContentView(R.layout.activity_main);

		// 初始化一些数据,假设是查询出来的
		for (int i = 0; i < 50; i++) {
			allValues.add("新添加的数据 " + i);
		}

		// 取得组件
		list = (ListView) findViewById(R.id.list);

		// Adapter
		adapter = new ArrayAdapter<String>(this,
				android.R.layout.simple_list_item_1, allValues);

		list.setAdapter(adapter);

	}
}
1.2、SimpleAdapter

在使用这种一行多条数据的Adapter时,首先需要先完成布局的设置,这里的布局指的是每一行的布局样式。

在layout目录下,建立一个布局文件。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="5"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/line_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="#20b2aa"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/line_time"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="#aaaaaa"
            android:textSize="10sp" />

        <TextView
            android:id="@+id/line_area"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="#aaaaaa"
            android:textSize="10sp" />
    </LinearLayout>

    <TextView
        android:id="@+id/line_price"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textColor="#ff6600"
        android:textSize="12sp" />

</LinearLayout>

然后可以在Java程序中建立Adapter并加入数据。

之前数据是用List<String>保存的,现在要改为List<Map<String,Object>>格式,每一行通过Map设置多条数据

public class MainActivity extends Activity {

	private ListView list;
	private SimpleAdapter adapter;

	private List<Map<String, Object>> allValues = new ArrayList<Map<String, Object>>();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// 设置默认使用的布局文件
		setContentView(R.layout.activity_main);

		// 初始化一些数据,假设是查询出来的
		for (int i = 0; i < 50; i++) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("title", "商品名称 " + i);
			map.put("time", "全新  " + i + " 小时前发布");
			map.put("area", "江苏 南通");
			map.put("price", i * 20 + "元");

			allValues.add(map);
		}

		// 取得组件
		list = (ListView) findViewById(R.id.list);

		// Adapter
		adapter = new SimpleAdapter(this, allValues, R.layout.my_simple_item,
				new String[] { "title", "time", "area", "price" }, new int[] {
						R.id.line_title, R.id.line_time, R.id.line_area,
						R.id.line_price });

		list.setAdapter(adapter);

	}
}
1.3、自定义Adapter

如果行中出现要显示的图片,必须要通过自定义Adapter 来完成

使用这个Adapter同样也要先完成界面的行的设计

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/listbg"
    android:orientation="horizontal"
    android:paddingBottom="5dp"
    android:paddingLeft="5dp"
    android:paddingRight="5dp"
    android:paddingTop="5dp" >

    <TextView
        android:id="@+id/line_img"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="4"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/line_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="#000000"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/line_time"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="#bbbbbb"
            android:textSize="10sp" />
    </LinearLayout>

    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="0.75" />

</LinearLayout>

自己建立一个Adapter类,并继承BaseAdapter类,同时覆写里面的方法,动态创建每一行的组件。

public class GameAdapter extends BaseAdapter {

	private Context ctx;

	private List<Map<String, Object>> allValues;

	public GameAdapter(Context ctx, List<Map<String, Object>> allValues) {
		this.ctx = ctx;
		this.allValues = allValues;
	}

	@Override
	public int getCount() {
		return allValues.size();
	}

	@Override
	public Object getItem(int position) {
		return allValues.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	/**
	 * 返回某一行的界面内容 convertView是为了提高性能准备的重用的行组件, 如果当前行之前没有建立过,则该值为null,需要自行建立.
	 * 如果之前已经建立了足够的行组件,则这里convertView有内容,只需要将里面的数据修改了即可.
	 */
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// 判断是否需要建立当前行的组件
		if (convertView == null) {
			// 建立新的组件, 需要动态读取xml自动建立组件
			convertView = LayoutInflater.from(ctx).inflate(
					R.layout.my_adapter_item, null);
		}

		// 设置组件中的数据
		// 分别取得要设置数据的TextView
		TextView imgText = (TextView) convertView.findViewById(R.id.line_img);
		TextView titleText = (TextView) convertView
				.findViewById(R.id.line_title);
		TextView timeText = (TextView) convertView.findViewById(R.id.line_time);

		// 设置数据
		Map<String, Object> map = allValues.get(position);
		titleText.setText(map.get("title").toString());
		timeText.setText(map.get("time").toString());

		// 设置图片
		imgText.setBackgroundResource((Integer) map.get("img"));

		return convertView;
	}

}

在Activity中使用自定义的Adapter

public class MainActivity extends Activity {

	private ListView list;
	private GameAdapter adapter;

	private List<Map<String, Object>> allValues = new ArrayList<Map<String, Object>>();

	// 所有图片的数组
	private int[] allImgs = { R.drawable.close_dir, R.drawable.image_file,
			R.drawable.mp3_file, R.drawable.mp4_file, R.drawable.open_dir,
			R.drawable.txt_file };

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// 设置默认使用的布局文件
		setContentView(R.layout.activity_main);

		Random r = new Random();
		// 初始化一些数据,假设是查询出来的
		for (int i = 0; i < 50; i++) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("title", "游戏名称 " + i);
			map.put("time", "2014-3-25 动作");
			map.put("img", allImgs[r.nextInt(allImgs.length)]);

			allValues.add(map);
		}

		// 取得组件
		list = (ListView) findViewById(R.id.list);

		// Adapter
		adapter = new GameAdapter(this, allValues);

		list.setAdapter(adapter);

	}
}
建立一个Globals类,在里面计算总屏幕宽度和高度。根据总屏幕高度,来动态改变数据的行高。

public class Globals {

public static int SCREEN_WIDTH;
public static int SCREEN_HEIGHT;

public static void init(Activity a) {
// 初始化屏幕的宽度和高度
SCREEN_WIDTH = a.getWindowManager().getDefaultDisplay().getWidth();
SCREEN_HEIGHT = a.getWindowManager().getDefaultDisplay().getHeight();
}

}

在Activity中调用这个初始化操作。

protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		Globals.init(this);

修改Adapter中的getView方法,设置行的高度。

public View getView(int position, View convertView, ViewGroup parent) {
		// 判断是否需要建立当前行的组件
		if (convertView == null) {
			// 建立新的组件, 需要动态读取xml自动建立组件
			convertView = LayoutInflater.from(ctx).inflate(
					R.layout.my_adapter_item, null);
			// 设置高度
			convertView.setLayoutParams(new LayoutParams(
					LayoutParams.MATCH_PARENT, Globals.SCREEN_HEIGHT / 9));
		}

		// 设置组件中的数据
		// 分别取得要设置数据的TextView
		TextView imgText = (TextView) convertView.findViewById(R.id.line_img);

		// 设置图片组件的高度
		imgText.getLayoutParams().height = Globals.SCREEN_HEIGHT / 9;
2、ListView常用事件

常用的监听有以下几种:

1)  点击某一项的监听:OnItemClickListener

list.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				// arg2表示当前点的行号,根据这个值,可以取得当前行的数据
				Map<String, Object> map = allValues.get(arg2);
				Toast.makeText(MainActivity.this,
						"当前所点击的是: " + map.get("title"), Toast.LENGTH_SHORT)
						.show();
			}
		});

2)  长按事件:OnItemLongClickListener

list.setOnItemLongClickListener(new OnItemLongClickListener() {
			@Override
			public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				
				Toast.makeText(MainActivity.this,
						"删除: " + arg2, Toast.LENGTH_SHORT)
						.show();
				
				return false;
			}
		});

3)  滑动事件:OnScrollListener

可以监听屏幕的滑动状态和滑动位置。

list.setOnScrollListener(new OnScrollListener() {
			@Override
			public void onScrollStateChanged(AbsListView view, int scrollState) {
				if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
					System.out.println("当前是空闲状态........ ------- ");
				} else if (scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
					System.out.println("触屏滚动状态......------");
				} else if (scrollState == OnScrollListener.SCROLL_STATE_FLING) {
					System.out.println("惯性滚动状态......------");
				}
			}

			@Override
			public void onScroll(AbsListView view, int firstVisibleItem,
					int visibleItemCount, int totalItemCount) {
				System.out.println("当前的显示项: " + firstVisibleItem + " + "
						+ visibleItemCount + " --> " + totalItemCount
						+ "  ------ ");
			}
		});































Adapter的一种写法 package com.xxkjx.jiusanqi; import java.util.List; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; public class NewsListViewAdapter extends BaseAdapter { List<News> list; LayoutInflater inflater; Context context; public NewsListViewAdapter(List<News> list, Context context) { super(); this.list = list; this.context = context; inflater = LayoutInflater.from(context); } @Override public int getCount() { // TODO Auto-generated method stub return list.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return list.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub ViewHolder viewHolder = null; if (convertView == null) { convertView = inflater.inflate(R.layout.activity_news_list_item, null); viewHolder = new ViewHolder(); viewHolder.title = (TextView) convertView .findViewById(R.id.tv_news_title); viewHolder.publish = (TextView) convertView .findViewById(R.id.tv_news_publish); viewHolder.brief = (TextView) convertView .findViewById(R.id.tv_news_brief); viewHolder.image = (ImageView) convertView .findViewById(R.id.img_news); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } viewHolder.title.setText(list.get(position).getTitle()); viewHolder.publish.setText(list.get(position).getPubblish()); viewHolder.brief.setText(list.get(position).getBrief()); viewHolder.image.setImageResource(list.get(position).getImg()); return convertView; } class ViewHolder { TextView title; TextView publish; TextView brief; ImageView image; } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值