【Android基础】(6)布局和ListView控件

文章地址:http://blog.csdn.net/scarthr/article/details/41959679


一 Android布局

五大布局:LinearLayout、RelativeLayout、FrameLayout、AbsoluteLayout、TableLayout,个人认为后面两个布局基本可以用前面的布局组合来实现,所以只是用前面的3个布局基本可以买足一切怪异、另类的布局了。
从Android2.2开始,新增了MATCH_PARENT,其值和FILL_PARENT值一样都是-1。WRAP_CONTENT是-2。


二 ListView控件

要使用ListView就离不开Adapter,一个ListView要配置一个Adapter,才能正常显示数据。

1. ArrayAdapter

要使用系统自带的列表项的话,如下:

		ListView listView = (ListView) findViewById(R.id.lv);
		ArrayAdapter adapter = new ArrayAdapter<String>(this,
				android.R.layout.simple_list_item_1);
		adapter.add("第一项");
		adapter.add("第二项");
		adapter.add("第三项");
		listView.setAdapter(adapter);
要使用自己创建的列表项,先创建一个item_cell.xml:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

</TextView>
修改上述代码如下:

		ListView listView = (ListView) findViewById(R.id.lv);
		ArrayAdapter adapter = new ArrayAdapter<String>(this,
				R.layout.item_cell);
		adapter.add("第一项");
		adapter.add("第二项");
		adapter.add("第三项");
		listView.setAdapter(adapter);
如果希望在ArrayAdapter中,存的不仅仅是String,存对象改怎么办呢?

新建User类:

package com.thr.testandroid;

public class User {

	private String name;
	private int age;

	public User(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + "]";
	}
}
注意要复写User的toString()方法,不然一会ListView中会显示的数据不是姓名而是一连串对象的地址名。

再次修改代码:
		ListView listView = (ListView)findViewById(R.id.lv);
		ArrayAdapter adapter = new ArrayAdapter<User>(this, R.layout.item_cell);
		adapter.add(new User("夏明", 12);
		adapter.add(new User("王亮", 14);
		listView.setAdapter(adapter);

要为ListView监听单击事件加入:

		listView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				User user = adapter.getItem(position);
				Toast.makeText(
						MainActivity.this,
						String.format("姓名: %s, 年龄: %s", user.getName(),
								user.getAge()), Toast.LENGTH_SHORT).show();
			}
		});

2. BaseAdapter

创建MyAdapter继承BaseAdapter:
package com.thr.testandroid;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class MyAdapter extends BaseAdapter {

	private Context context;

	private String[] stringArray = new String[] { "1", "2", "3", "4", "5", "6",
			"7", "8", "9", "10" };

	public MyAdapter(Context context) {
		this.context = context;
	}

	@Override
	public int getCount() {
		return stringArray.length;
	}

	@Override
	public String getItem(int position) {
		return stringArray[position];
	}

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

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		TextView tv = new TextView(context);
		tv.setText(getItem(position));
		return tv;
	}
}
然后设置好我们创建的MyAdapter:
		MyAdapter adapter = new MyAdapter(this);
		listView.setAdapter(adapter);
Done。
getCount是取得所有数据的数量,getItem(int position)用来取得指定的某一条数据,getItemId(int position)用来取得当前position位置数据的Id,getView(int position, View convertView, ViewGroup parent)是当前显示出来的那一条View,只要屏幕显示出来一条数据,getView就会执行一次。
此时有一个问题,如果这个条目如果很大很大,成千上万甚至更大那么,每次都要new TextView吗?那岂不是太浪费内存了,那么优化ListView的机制就出来了。
我们更改上面getView方法:
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		TextView tv;
		if (convertView != null) {
			tv = (TextView) convertView;
		} else {
			tv = new TextView(context);
		}
		tv.setText(getItem(position));
		return tv;
	}
这样在convertView不为空的时候就会剩下很多资源。

下来我们实现一个稍微复杂一点的ListView,带图标和文字的ListView。
首先新建item_listview.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>
创建ItemData类:
package com.thr.testandroid;

public class ItemData {

	private int imageId;
	private String name;

	public ItemData(int imageId, String name) {
		super();
		this.imageId = imageId;
		this.name = name;
	}

	public int getImageId() {
		return imageId;
	}

	public void setImageId(int imageId) {
		this.imageId = imageId;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}
创建ItemAdapter继承BaseAdapter:
package com.thr.testandroid;

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 ItemAdapter extends BaseAdapter {

	private Context context;
	private List<ItemData> itemList;

	public ItemAdapter(Context context) {
		this.context = context;
		itemList.add(new ItemData(R.drawable.ic_launcher, "张三"));
		itemList.add(new ItemData(R.drawable.ic_launcher, "李四"));
		itemList.add(new ItemData(R.drawable.ic_launcher, "王五"));
	}

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

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

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

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder;
		ItemData data = itemList.get(position);
		if (convertView == null) {
			holder = new ViewHolder();
			convertView = LayoutInflater.from(context).inflate(
					R.layout.item_listview, null);
			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}
		ImageView iv = (ImageView) convertView.findViewById(R.id.iv);
		TextView tv = (TextView) convertView.findViewById(R.id.tv);

		iv.setImageResource(data.getImageId());
		tv.setText(data.getName());
		
		return convertView;
	}

	class ViewHolder {
		ImageView iv;
		TextView tv;
	}
}
这里我们创建了ViewHolder类,这是一个类持有者,他用来保存我们在getView中已经创建好的convertView,用setTag()保存好标签,在再次需要使用的时候调用getTag()便可以得到我们需要的convertView,这样既节省了内存,也使得效率更高。
在需要使用ItemAdapter的地方调用:
		ItemAdapter adapter = new ItemAdapter(this);
		listView.setAdapter(adapter);
在ItemAdapter的构造方法中可以修改为带数据集合参数的方法,我这里是为了方便直接写在ItemAdapter内部了。

还有一中方法可以快速创建ListView,我们可以创建一个继承自ListActivity的类MyListActivity:
package com.thr.testandroid;

import android.app.ListActivity;
import android.os.Bundle;

public class MyListActivity extends ListActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setListAdapter(new ItemAdapter(this));
	}
}
这样子就行了,是不是非常方便快捷呢?连Activity的布局都不用设置。
如果需要对Activity布局做调整,则创建activity_listview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="按钮" />

</LinearLayout>
在Activity中增加:
		setContentView(R.layout.item_listview);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值