之前工作当中虽然做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实现左滑删除功能"旨在教你如何在ListView中添加滑动删除的交互效果。 首先,我们需要理解ListView的工作原理。ListView通过复用View(也称为ViewHolder模式)来优化性能,减少内存消耗...
因此,开发者需要自定义或者重写ListView来实现这个特性。本教程将深入探讨如何在Android应用中重写ListView,以实现下拉刷新的功能。 首先,我们要理解下拉刷新的基本概念。下拉刷新是指用户在ListView顶部向下...
视图的自定义则涉及对ListView中的每个条目进行布局设计,可以通过XML布局文件定义,或者在代码中动态创建。 其次,对于监听用法,ListView提供了多种监听器接口,如: 1. `OnItemClickListener`: 当用户点击...
2. **自定义Adapter**:你需要创建一个自定义的Adapter,这个Adapter需要继承自`BaseAdapter`或者`ArrayAdapter`,并重写其中的方法,如`getView()`。在这个方法里,你会为每个主列表项创建视图,并在需要的地方插入...
重写其中的四个方法:getCount()返回数据源的大小,getItem(int position)获取指定位置的数据,getItemId(int position)返回对应数据的唯一ID,以及getView(int position, View convertView, ViewGroup parent)方法...
1. **定义数据源**:ListView需要一个数据集来显示内容,这可以是ArrayList、ArrayAdapter或者其他适配器类。例如,你可以创建一个String数组或ArrayList来存储要显示的文本。 2. **创建适配器**:适配器是连接...
对于ListView,我们可以创建一个自定义的布局文件,用于定义每个列表项的外观,包括边框。在res/layout目录下,创建一个新的XML布局文件,例如`list_item.xml`,并定义一个带有边框的ViewGroup,如LinearLayout或...
- 如果数据源中的类型不支持默认的比较器,或者需要自定义排序规则,可以在数据源类中实现`IComparable`接口,重写`CompareTo`方法。这样,当你对数据源进行排序时,系统会自动使用这个方法进行比较。 - 另外,也...
在这个适配器中,你需要重写`getView()`方法,以便为每个父项加载parent_item.xml布局,并在适当的位置插入内层ListView。内层ListView也需要一个自定义Adapter,通常继承自`ArrayAdapter`,用于处理子列表的数据。 ...
总结来说,ListView的基本使用包括创建ListView、定义条目布局、创建Adapter并实现数据绑定,以及处理点击事件。在实际应用中,还可以进一步优化性能,比如使用convertView复用条目视图,或者使用更高级的Adapter如...
2. 自定义滚动效果:通过重写ListView的onScroll()和onScrollStateChanged()方法,可以实现自定义的滚动行为。 3. 自定义触摸事件处理:通过覆写onInterceptTouchEvent()和onTouchEvent()方法,可以控制ListView的...
2. 自定义`ListView`的布局文件:在`res/layout`目录下创建XML布局文件,定义每个列表项的视图结构。这个布局文件会被`Adapter`的`getView()`方法加载并填充数据。 为了将自定义`ListView`添加到`TabHost`的一个`...
这一特性可以通过重写ListView的PreviewMouseLeftButtonDown和MouseMove事件,配合一些坐标计算来实现。在拖放过程中,需要处理列的隐藏、显示和大小变化,确保拖动过程的平滑。 在提供的文件列表中,我们可以看到`...
在ListView中,Header是指位于列表数据之前的一个或多个视图,它可以提供额外的信息或者功能。通常,Header视图可以通过调用ListView的addHeaderView()方法添加。 接下来,我们引入ViewPager。ViewPager允许用户在...
`choiceMode`是用来定义ListView的行为,特别是用户进行选择时的行为。它有以下几个可选值: 1. `CHOICE_MODE_NONE`:默认值,不允许用户进行选择。 2. `CHOICE_MODE_SINGLE`:单选模式,用户只能选择一个条目。 3....
要实现网格布局,我们需要使用GridView或者结合使用ListView和GridLayout。由于标题提到的是“ListView的网格视图”,我们将主要讨论使用GridView的情况。GridView是一个二维的列表视图,可以设置每行的列数,从而...
创建一个继承自`BaseAdapter`的类,例如`MyAdapter`,并重写其中的`getCount()`(返回数据源长度)、`getItem()`(返回指定位置的数据项)、`getItemId()`(返回数据项的唯一ID)以及`getView()`(返回ListView中每...
3. Adapter:创建自定义的Adapter,继承自`BaseAdapter`或`ArrayAdapter`,重写`getCount()`,`getItem()`,`getItemId()`以及`getView()`方法。`getView()`是关键,用于生成并设置每个item的视图。 二、动态添加...
3. 数据绑定:在Adapter中,重写`getView()`方法,这个方法会为ListView的每一项返回一个View。在该方法内,使用LayoutInflater实例化布局文件,然后找到ImageView和TextView,将数据绑定到这些视图上。可以使用...
- 在布局文件中添加ListView,通过`<ListView>`标签定义,并为其设置ID。 - 配置ListView的数据源,通常是一个ArrayList或其他类型的集合。 2. **Adapter原理**: - ListView的工作离不开Adapter,它作为...