`
whao189
  • 浏览: 123209 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

重写listview(或者定义listview)

阅读更多
之前工作当中虽然做android开发但是细想起来UI 部分还真是接触的少了一些,所以接下来的一段时间决定好好补习UI,这不是今天我在看自定义的 listview(以前也有看过但是没有仔细看)。

那么今天呢,我打算比葫芦画瓢 然后添加我自己的理解 看看大家觉得怎么样?是不是也和我有同样的理解呢?

先来简单的看看关于listview的东西。。。。第一:那就是listview了。。这个东西不用说的

第二:很重要的就是这个东西了。。Adapter 适配器。。。是的,那么到底要怎么用呢?

Adapter下面有三个子类 SimpleAdapter SimpleCursorAdapter ArrayAdapter(SimpleCursorAdapter  的父类 CursorAdapter 才是直接继承BaseAdapter的)

那么我们这里提到的自定义Listview用的就是第一个,因为他可扩展性好,你可能会想“难道后面两个就不行了么?” 答案是 肯定的。。。从SimpleCursorAdapter字面上可以看出 “游标适配器” 它主要是用来 包装从数据库查询出来的,而ArrayAdapter则是包装数据 类型的数据的。
稍后你会看到具体的例子。

好吧我们接下来看看具体的例子:
ArrayAdapter

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.Contacts.People;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleCursorAdapter;

public class MainActivity extends Activity {
	private ListView listView;
	private ArrayAdapter arrayAdapter;
	private List<String> list;
	private Cursor    cursor;
	private SimpleCursorAdapter cursorAdapter;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        /****这个东西 是 演示arrayAdapter***/
        listView  = new ListView(this);
        list      = new ArrayList<String>();
        list.add("123");
        list.add("123");
        list.add("123");
        arrayAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,list);
        listView.setAdapter(arrayAdapter);
    }

SimpleCursorAdapter

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.Contacts.People;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleCursorAdapter;

public class MainActivity extends Activity {
	private ListView listView;
	private ArrayAdapter arrayAdapter;
	private List<String> list;
	private Cursor    cursor;
	private SimpleCursorAdapter cursorAdapter;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        listView  =  new ListView(this);
        cursor    = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
        //activity开始管理 cursor  省去了我们手动管理 cursor 
        startManagingCursor(cursor);
        cursorAdapter = new SimpleCursorAdapter(this,android.R.layout.simple_expandable_list_item_2,cursor,new String[]{People.NAME},new int[]{android.R.id.text1});
        listView.setAdapter(cursorAdapter);  
    }  
}




这里对于ArrayAdapter 和SimpleCursorAdapter 不做过多的解释。


SimpleAdapter 是我们的重点,因为大多数情况下 我们的需求以上两个Adapter是满足不了的
这个时候我们就需要重新 自定义自己的 ListView了。。

那自定义自己的ListView最主要的就是重写Adapter。我们先看看SimpleAdapter  的应用
之后在重写自己的。


import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

public class MainListActivity extends [color=red]ListActivity[/color]{

	private SimpleAdapter simpleAdapter;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("title", "G1");
                map.put("info", "google 1");
                map.put("img", R.drawable.icon);
                list.add(map);

		simpleAdapter = new SimpleAdapter(this, list, R.layout.main_list_view, new String[]{"title","info","image"}, new int[]{R.id.title,R.id.info,R.id.img});
		setListAdapter(simpleAdapter);
	}


可以看到它是按照行来显示的,但是通常我们可能在每一个Item中要做单选radio 或者 复选check等等而且还要为这些按钮添加相应的事件,那么这个时候该怎么办呢?

解决的方法就是自定义Adapter了。。。

下面来看看整个过程:

第一步:我们要创建Acitivyt继承 ListActivity

第二步:创建之后我们要定义自己的数据结构(因为这个地方我们传给SimpleAdapter)这个地方的数据结构格式是这样的List<? extends Map<String,?>> 所以呢这个地方我们一点过要首先产生自己的数据!

第三步:就是要继承BaseAdapter重写Adapter了



import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
[color=red]//第一步[/color]
public class MainListActivtiy2 extends ListActivity{

	private List<Map<String,Object>> list;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
[color=darkred]//第二步[/color]
		list = new ArrayList<Map<String,Object>>();
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("titile", "标题");
		map.put("info",   "信息");
		map.put("image",  "图片");
		list.add(map);
		
		MyAdapter  adapter = new MyAdapter(this);
		
		setListAdapter(adapter);
	}
	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		Log.v("MyListView4-click", (String)list.get(position).get("title"));		
	}
	public void showDialog(){
		 new AlertDialog.Builder(this)
		         .setTitle("我的listview")
		         .setMessage("介绍...")
		         .setPositiveButton("确定", new DialogInterface.OnClickListener() {
		             @Override
		             public void onClick(DialogInterface dialog, int which) {}
		         })
		         .show();
	}
[color=red]//第三步[/color]
	private class MyAdapter extends BaseAdapter{
		private LayoutInflater layouInflater;
		public MyAdapter(Context context){
			layouInflater = LayoutInflater.from(context);
		}
//这个地方时最关键的 你返回的数字是 几 那么listview中就会出现多少个数据(ITEM)
		@Override
		public int getCount() {
			return list.size();
		}

		@Override
		public Object getItem(int position) {
			return null;
		}

		@Override
		public long getItemId(int position) {
			return 0;
		}
//这个地方时最关键的
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder holder = null;
			if(convertView == null){
				holder = new ViewHolder();
				convertView = layouInflater.inflate(R.layout.main_list_view2, null);
				holder.img  = (ImageView)convertView.findViewById(R.id.img);
				holder.info = (TextView) convertView.findViewById(R.id.info);
				holder.title= (TextView) convertView.findViewById(R.id.title);
				holder.btn  = (Button) convertView.findViewById(R.id.view_btn);
				convertView.setTag(holder);
			}
			else{
				holder  = (ViewHolder)convertView.getTag();
			}
			holder.img.setBackgroundResource((Integer)list.get(position).get("image"));
			holder.title.setText((String)list.get(position).get("title"));
			holder.info.setText((String)list.get(position).get("info"));
			holder.btn.setOnClickListener(new View.OnClickListener() {
				
				@Override
				public void onClick(View v) {
					showDialog();
				}
			});
			return convertView;
		}
		
		public final class ViewHolder{
			  public ImageView img;
	          public TextView title;
	          public TextView info;
	          public Button   btn;
		} 
	}


这里我说说自己的理解啊。

为什么要这么做
这个地方时最关键的 你返回的数字是 几 那么listview中就会出现多少个数据(ITEM)
		@Override
		public int getCount() {
			return list.size();
		}


因为在Adapter中实例化 convertView之后会先调用getcount 方法 因为Adapter 想要知道 你

要返回多少数据在ListView 中显示如果你返回的是0 那么结果可想而知 listview中没有显示,你返回的是2 那就显示出两个(其实仔细想想你会发现 如果你做分页的话不知道能不能从这个地方入手 或者 做 动态地加载也就是 你滚动到listview底部的时候才继续加载)。。。

我觉得应该可以从这个地方入手的。。。

然后我们说说getView 这个方法,这里面的view 都是通过LayoutInflater 动态实例化的

而且是每实例化一次就要调用一次getView 方法(view 里面的数据就是ViewHolder对象)。

好了看到这里估计你也应该明白自定义 ListView 的 过程了。









分享到:
评论

相关推荐

    SwipeListViewTest:A Android Swipe ListView Demo自定义ListView

    A Android Swipe ListView Demo自定义ListView 搬运自某个网站 ##项目描述 1.Package 中包含新建的类 RowMessage 和 SwipeAdapter 在RowMessage中定义要显示的数据 在SwipeAdapter中重写getview()以确定控件与数据的...

    android下拉刷新ListView的介绍和实现代码

    由此可以看出,在构建这个下拉刷新的组件的时候,只用继承ListView,然后重写onTouchEvent就能实现。还有就是要能在xml布局文件中引用,还需要一个参数为Context,AttributeSet的构造函数。  表面上的功能大概就这些...

    仿微信对话列表滑动删除功能(可自行定义)

    仿微信对话列表滑动删除功能,带详细注释,重写的ListView便于应用

    简单好用的上拉加载下拉刷新 BaseRecyclerViewAdapterHelper

    一个强大并且灵活的 Android RecyclerViewAdapter。 优化Adapter代码(减少百分之70%代码) ...自定义不同的item类型(简单配置、无需重写额外方法) 设置空布局(比Listview的setEmptyView还要好用!)

    安卓模拟新浪微博随便看看(带刷新)

    本项目老师布置的一个作业,重写了ListView控件和BaseAdapter适配器中的方法,添加了头部刷新功能,ListView中的数据中图片、昵称、文本都是在values目录中定义的arrays.xml资源,日期和人气则是通过java API中的...

    《Android自定义组件开发详解》

    封面 1 序 2 捐助说明 5 目 录 7 第一章 View的绘图流程 12 ...10.5.2 列表项能滑出删除按钮的ListView 342 10.5.3 定义布局文件 350 10.5.4 显示ListView 351 10.6练习作业 353 案例代码说明 354

    AspNet MVC 开发技术

    10.2.2 调用重写或隐藏的基类方法 219 10.2.3 嵌套的类型定义 220 10.3 接口的实现 220 10.4 部分类定义 224 10.5 部分方法定义 225 10.6 示例应用程序 227 10.6.1 规划应用程序 227 10.6.2 编写类库 228 10.6.3 ...

    强大的RecyclerAdapter框架

    简单配置、无需重写额外方法。 设置空布局 比Listview的setEmptyView还要好用。 添加拖拽、滑动删除 开启,监听即可,就是这么简单。 树形列表 比ExpandableListView还要强大,支持多级。 自定义ViewHolder 支持...

    Android 开发技巧

    方法一:(重写ListView) 144 方法二: 150 5.6、3D魔方 151 6、ANDROID UI 动画 160 6.1、四种2D动画 160 6.1.1、透明度控制动画效果 alpha 160 6.1.2、旋转动画效果 rotate 161 6.1.3、尺寸伸缩动画效果 scale ...

    Android开发资料合集-World版!

    方法一:(重写ListView) 144 方法二: 150 5.6、3D魔方 151 6、ANDROID UI 动画 160 6.1、四种2D动画 160 6.1.1、透明度控制动画效果 alpha 160 6.1.2、旋转动画效果 rotate 161 6.1.3、尺寸伸缩动画效果 scale ...

    TreeViewDrop_20210520.rar

    该功能接口类可以实现Treeview/ListBox/Listview等元素之间的相互拖拽。代码举个一个实例,实现reeview/ListBox之间元素相互拖拽,并在拖拽过程中通过DragDropAdorner(继承于Adorner)重写OnRender函数实现拖拽的...

    明日科技C#开发入门及项目实战

    实例014 定义循环内部变量并输出变量的值 实例015 定义常量计算圆的周长 实例016 使用“+”编写双重意义的表达式 实例017 使用小括号括起来的表达式 实例018 使用算术运算符开发简单计算器 实例019 使用条件运算符...

    《C#经典编程220例》.(明日科技).【带书签】-共3部分

    实例014 定义循环内部变量并输出变量的值 20 实例015 定义常量计算圆的周长 21 实例016 使用“+”编写双重意义的表达式 22 实例017 使用小括号括起来的表达式 23 .实例018 使用算术运算符开发简单计算器 23 实例019 ...

    疯狂Android讲义源码

     2.4.9 列表视图(ListView和  ListActivity) 95  2.4.10 可展开的列表组件(ExpandableListView) 101  2.4.11 网格视图(GridView)和  图像切换器(ImageSwitcher)  功能和用法 104  2.4.12 画廊视图...

    疯狂Android讲义.part1

    2.4.9 列表视图(ListView和 ListActivity) 95 2.4.10 可展开的列表组件(ExpandableListView) 101 2.4.11 网格视图(GridView)和 图像切换器(ImageSwitcher) 功能和用法 104 2.4.12 画廊视图(Gallery)的...

    net学习笔记及其他代码应用

    1. 简述 private、 protected...因此传递给 switch 和 case 语句的参数应该是 int、 short、 char 或者 byte。long,string 都不能作用于swtich。 47.当一个线程进入一个对象的一个synchronized方法后,其它线程是否可...

    Google Android SDK开发范例大全(PDF高清完整版3)(4-3)

    4.19 在Activity里显示列表列表——ListView的布局 4.20 以动态列表配置选项——ListActivity与Menu整合技巧 4.21 查找程序根目录下所有文件——JavaI/O与ListActivity的结合.. 4.22 加载手机磁盘里的图文件——使用...

    Google Android SDK开发范例大全(PDF完整版4)(4-4)

    4.19 在Activity里显示列表列表——ListView的布局 4.20 以动态列表配置选项——ListActivity与Menu整合技巧 4.21 查找程序根目录下所有文件——JavaI/O与ListActivity的结合.. 4.22 加载手机磁盘里的图文件——使用...

Global site tag (gtag.js) - Google Analytics