`
whao189
  • 浏览: 124652 次
  • 性别: 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 的 过程了。









分享到:
评论

相关推荐

    Android 重写Listview实现左滑删除功能

    本项目"Android 重写Listview实现左滑删除功能"旨在教你如何在ListView中添加滑动删除的交互效果。 首先,我们需要理解ListView的工作原理。ListView通过复用View(也称为ViewHolder模式)来优化性能,减少内存消耗...

    android应用源码Android重写listview实现下拉刷新源码.zip

    因此,开发者需要自定义或者重写ListView来实现这个特性。本教程将深入探讨如何在Android应用中重写ListView,以实现下拉刷新的功能。 首先,我们要理解下拉刷新的基本概念。下拉刷新是指用户在ListView顶部向下...

    listview 自定义+监听用法

    视图的自定义则涉及对ListView中的每个条目进行布局设计,可以通过XML布局文件定义,或者在代码中动态创建。 其次,对于监听用法,ListView提供了多种监听器接口,如: 1. `OnItemClickListener`: 当用户点击...

    listView 嵌套 ListView demo

    2. **自定义Adapter**:你需要创建一个自定义的Adapter,这个Adapter需要继承自`BaseAdapter`或者`ArrayAdapter`,并重写其中的方法,如`getView()`。在这个方法里,你会为每个主列表项创建视图,并在需要的地方插入...

    listview的小demo

    重写其中的四个方法:getCount()返回数据源的大小,getItem(int position)获取指定位置的数据,getItemId(int position)返回对应数据的唯一ID,以及getView(int position, View convertView, ViewGroup parent)方法...

    android中一个简单的LIstView用法例子

    1. **定义数据源**:ListView需要一个数据集来显示内容,这可以是ArrayList、ArrayAdapter或者其他适配器类。例如,你可以创建一个String数组或ArrayList来存储要显示的文本。 2. **创建适配器**:适配器是连接...

    加边框的listview

    对于ListView,我们可以创建一个自定义的布局文件,用于定义每个列表项的外观,包括边框。在res/layout目录下,创建一个新的XML布局文件,例如`list_item.xml`,并定义一个带有边框的ViewGroup,如LinearLayout或...

    WPF ListView控件添加排序功能

    - 如果数据源中的类型不支持默认的比较器,或者需要自定义排序规则,可以在数据源类中实现`IComparable`接口,重写`CompareTo`方法。这样,当你对数据源进行排序时,系统会自动使用这个方法进行比较。 - 另外,也...

    Listview嵌套Listview

    在这个适配器中,你需要重写`getView()`方法,以便为每个父项加载parent_item.xml布局,并在适当的位置插入内层ListView。内层ListView也需要一个自定义Adapter,通常继承自`ArrayAdapter`,用于处理子列表的数据。 ...

    ListView的基本使用带Button

    总结来说,ListView的基本使用包括创建ListView、定义条目布局、创建Adapter并实现数据绑定,以及处理点击事件。在实际应用中,还可以进一步优化性能,比如使用convertView复用条目视图,或者使用更高级的Adapter如...

    Android ListView 下拉刷新、上拉加载

    2. 自定义滚动效果:通过重写ListView的onScroll()和onScrollStateChanged()方法,可以实现自定义的滚动行为。 3. 自定义触摸事件处理:通过覆写onInterceptTouchEvent()和onTouchEvent()方法,可以控制ListView的...

    TabHost中填充自定义ListView

    2. 自定义`ListView`的布局文件:在`res/layout`目录下创建XML布局文件,定义每个列表项的视图结构。这个布局文件会被`Adapter`的`getView()`方法加载并填充数据。 为了将自定义`ListView`添加到`TabHost`的一个`...

    WPF_ListView边框_每条颜色_数据绑定_多选择_字段可拖拽

    这一特性可以通过重写ListView的PreviewMouseLeftButtonDown和MouseMove事件,配合一些坐标计算来实现。在拖放过程中,需要处理列的隐藏、显示和大小变化,确保拖动过程的平滑。 在提供的文件列表中,我们可以看到`...

    listview与viewpager组合

    在ListView中,Header是指位于列表数据之前的一个或多个视图,它可以提供额外的信息或者功能。通常,Header视图可以通过调用ListView的addHeaderView()方法添加。 接下来,我们引入ViewPager。ViewPager允许用户在...

    ListView的选择模式

    `choiceMode`是用来定义ListView的行为,特别是用户进行选择时的行为。它有以下几个可选值: 1. `CHOICE_MODE_NONE`:默认值,不允许用户进行选择。 2. `CHOICE_MODE_SINGLE`:单选模式,用户只能选择一个条目。 3....

    android ListView 网格布局

    要实现网格布局,我们需要使用GridView或者结合使用ListView和GridLayout。由于标题提到的是“ListView的网格视图”,我们将主要讨论使用GridView的情况。GridView是一个二维的列表视图,可以设置每行的列数,从而...

    ListView添加CheckBox复选框

    创建一个继承自`BaseAdapter`的类,例如`MyAdapter`,并重写其中的`getCount()`(返回数据源长度)、`getItem()`(返回指定位置的数据项)、`getItemId()`(返回数据项的唯一ID)以及`getView()`(返回ListView中每...

    ListView动态添加、移除item

    3. Adapter:创建自定义的Adapter,继承自`BaseAdapter`或`ArrayAdapter`,重写`getCount()`,`getItem()`,`getItemId()`以及`getView()`方法。`getView()`是关键,用于生成并设置每个item的视图。 二、动态添加...

    Android ListView扩展(图片+文字)

    3. 数据绑定:在Adapter中,重写`getView()`方法,这个方法会为ListView的每一项返回一个View。在该方法内,使用LayoutInflater实例化布局文件,然后找到ImageView和TextView,将数据绑定到这些视图上。可以使用...

    Android应用源码之listView_listView.zip

    - 在布局文件中添加ListView,通过`&lt;ListView&gt;`标签定义,并为其设置ID。 - 配置ListView的数据源,通常是一个ArrayList或其他类型的集合。 2. **Adapter原理**: - ListView的工作离不开Adapter,它作为...

Global site tag (gtag.js) - Google Analytics