ListView和三种Adapter

来源:互联网 发布:酷彩 菜谱 知乎 编辑:程序博客网 时间:2024/05/17 02:14

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>();@Overrideprotected 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);// Adapteradapter = 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>>();@Overrideprotected 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);// Adapteradapter = 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;}@Overridepublic int getCount() {return allValues.size();}@Overridepublic Object getItem(int position) {return allValues.get(position);}@Overridepublic long getItemId(int position) {return position;}/** * 返回某一行的界面内容 convertView是为了提高性能准备的重用的行组件, 如果当前行之前没有建立过,则该值为null,需要自行建立. * 如果之前已经建立了足够的行组件,则这里convertView有内容,只需要将里面的数据修改了即可. */@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// 判断是否需要建立当前行的组件if (convertView == null) {// 建立新的组件, 需要动态读取xml自动建立组件convertView = LayoutInflater.from(ctx).inflate(R.layout.my_adapter_item, null);}// 设置组件中的数据// 分别取得要设置数据的TextViewTextView 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 };@Overrideprotected 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);// Adapteradapter = 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));}// 设置组件中的数据// 分别取得要设置数据的TextViewTextView imgText = (TextView) convertView.findViewById(R.id.line_img);// 设置图片组件的高度imgText.getLayoutParams().height = Globals.SCREEN_HEIGHT / 9;
2、ListView常用事件

常用的监听有以下几种:

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

list.setOnItemClickListener(new OnItemClickListener() {@Overridepublic 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() {@Overridepublic 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() {@Overridepublic 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("惯性滚动状态......------");}}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {System.out.println("当前的显示项: " + firstVisibleItem + " + "+ visibleItemCount + " --> " + totalItemCount+ "  ------ ");}});































0 0