ListView是Android开发中经常会用到的控件。
一般来讲,ListView配合Adapter一起使用,官方给出了多种Adapter(ArrayAdapter、SimpleAdapter等,都是BaseAdapter的子类,ListView总结之Adapter)供开发者使用。使用BaseAdapter和ListViewHolder来处理ListView的各种事件与响应,比较灵活,代码也会比较简洁独立。
代码结构:
- MainActivity Activity
- MyListViewAdapter 继承自BaseAdapter
- ListViewHolder 处理每一条Item的所有事件与响应
- ListBean 一个简单的数据结构,网络开发中方便获取Json数据
Layout
- activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <ListView android:id="@+id/listview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> </RelativeLayout>
- item_listview.xml
item布局,将是ListView中每一条布局的样式,一个好的界面,就需要在这里下功夫了。我这里只是抛砖而已,毫无设计,只讲原理。<span style="font-size: 18px;"><?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" > <TextView android:id="@+id/item_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" /> <Button android:id="@+id/item_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" /> </LinearLayout></span><span style="font-size: 18px; background-color: rgb(240, 240, 240);"> </span>
MainActivity.java
MainActivity中仅仅处理界面资源的装载,和数据源的获取,不做其他的处理。
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
public class MainActivity extends Activity {
private ListView listview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initComponet();
}
/**
* 初始化所有需要的组件
* @Title: initComponet
* @param
* @return void
*/
private void initComponet() {
listview = (ListView) findViewById(R.id.listview);
//声明Adapter,同时装载数据
listview.setAdapter(new MyListViewAdapter(this, getListBeans()));
}
/**
* 构建临时数据
* 依项目要求,获取数据源方式有多种
*/
private List<ListBean> getListBeans() {
List<ListBean> beans = new ArrayList<ListBean>();
ListBean bean1 = new ListBean();
ListBean bean2 = new ListBean();
ListBean bean3 = new ListBean();
bean1.setBtnText("btn1");
bean1.setTextViewStr("tv1");
bean2.setBtnText("btn2");
bean2.setTextViewStr("tv2");
bean3.setBtnText("btn3");
bean3.setTextViewStr("tv3");
beans.add(bean1);
beans.add(bean2);
beans.add(bean3);
return beans;
}
}
MyListViewAdapter.java
MyListViewAdapter继承自BaseAdapter
getCount();
getItem(int position);
getItemId(int position);
getView(int position, View convertView, ViewGroup parent);
这四个方法是必须要复写的。
数据的传递放在Adapter的构造函数中,Adapter在声明并初始化后就能完成数据的传递工作
package com.arobot.listviewholder;
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
public class MyListViewAdapter extends BaseAdapter {
private Context context;
private List<ListBean> listBean;
/**
* Adapter的构造函数,Context和数据源在声明该Adapter时就要传递进来
* <p>Title: </p>
* <p>Description: </p>
* @param context
* @param list 数据源
*/
public MyListViewAdapter(Context context, List<ListBean> list) {
this.context = context;
this.listBean = list;
}
/**
* 数据长度
*/
@Override
public int getCount() {
return listBean.size();
}
@Override
public Object getItem(int position) {
return listBean.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//获得MainActivity 的 LayoutInflater
LayoutInflater inflater = LayoutInflater.from(context);
//声明一个ViewHolder
ListViewHolder listViewHolder;
if (convertView == null) {
//convertView为null时,重新获取一遍资源
convertView = inflater.inflate(R.layout.item_listiew, null);
//实例化一次ViewHolder
listViewHolder = new ListViewHolder(context, convertView);
//将ViewHolder与convertView绑定,下次使用时无须再次实例化
convertView.setTag(listViewHolder);
} else {
//在convertView不为空时,直接获取绑定的ViewHolder
listViewHolder = (ListViewHolder) convertView.getTag();
}
//将所在position设置为id
listBean.get(position).setId(position);
//装载对应的数据源,下面有两种方式都可以获取到正确的数据
listViewHolder.setBean((ListBean) getItem(position));
//listViewHolder.setBean(listBean.get(position));
return convertView;
}
}
ListViewHolder.java
每一条item中的数据响应,点击事件响应都在Holder中处理。
package com.arobot.listviewholder;
import android.content.Context;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class ListViewHolder {
/*以下为该holder的基本构成元素*/
private TextView textView;
private Button btn;
/*====================*/
private Context context;
private View view;
private ListBean bean;
/**
* ViewHolder的构造函数
* <p>Title: </p>
* <p>Description: </p>
* @param context
* @param view
*/
public ListViewHolder(Context context, View view) {
this.context = context;
this.view = view;
init();
}
private void init() {
textView = (TextView) view.findViewById(R.id.item_tv);
btn = (Button) view.findViewById(R.id.item_btn);
}
/**
* @param bean 要设置的 bean
*/
public void setBean(ListBean bean) {
this.bean = bean;
deployData();
}
/**
* 部署数据到对应的控件
* @Title: deployData
* @param
* @return void
*/
private void deployData() {
textView.setText(bean.getTextViewStr());
btn.setText(bean.getBtnText());
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, bean.getId() + "", Toast.LENGTH_LONG).show();
}
});
}
}