作者Y78 (Y78)
看板AndroidDev
标题[分享] 简单易学 自订ListView
时间Thu Dec 27 11:32:57 2012
最近在研究如何自订一个ListView
版上givemepass大大的这篇文章已经讲得不错了
#1DbiQ5jJ (AndroidDev) [ptt.cc] [分享] BaseAdapter 自定ListView
建议大家可以先看过这篇
至於这篇的话就分享一下最近使用的心得跟方法
如果哪里有讲错的话还请大家帮忙指正一下
先来看看看完这篇文章之後可以做出的效果
----
【HBO电影台】
狙击陌生人
20:00
禁运品
22:00
杀客同萌
23:55
【东森洋片台】
哈利波特2
17:35
飞机上有蛇
20:00
冲出封锁线
23:15
----
程式截图:
http://ppt.cc/YaGO
首先,有一个重点知道以後自订ListView就不再那麽神秘
那就是List的每一列可以看成都是一个view
所以第一步就是就是决定每一列到底要长什麽样子
以我想要达成的效果来说
我的item需要有两个TextView
一个放电影名称或是电影台的名称
另外一个则放时间
所以建立一个 list_item.xml 来达成这个layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="
http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/title" />
</RelativeLayout>
上面的id叫做title 下面的则叫做time
接着,你要决定你的每一个item需要哪些资料
为了以後的方便,我们要自己建一个class来放这些资料
以这篇为例子
我要传入的资料有:电影台名称 电影标题 电影时间
其实我的case比较特殊啦
因为可以很明显看到每个list item长的并不是很相同
所以我加了一个type的参数
type 0 = 这个item是电影 颜色是白色
type 1 = 这个item是电影台
type 2 = 这个item是电影 颜色是黄色
所以我的参数有 type , title(电影or电影台名称),time(电影时间)
class叫做Movie.class 内容很简单的长这样
public class Movie {
private int type;
private String name;
private String time;
public Movie(int type,String name,String time) {
this.type = type;
this.name = name;
this.time = time;
}
public int getType(){
return type;
}
public void setType(int type){
this.type = type;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public String getTime(){
return time;
}
public void setTime(String time){
this.time = time;
}
}
再来先回到需要ListView的地方
假设ListView的id叫做ListView01好了
我们先宣告三个东西
private ListView listV;
List<Movie> movie_list = new ArrayList<Movie>();
private MyAdapter adapter;
MyAdapter是什麽呢? 是我们等一下会讲到的东西
接着
listV=(ListView)findViewById(R.id.ListView01);
movie_list就是你要传入的东西
以本篇为例 就是
movie_list.add(new Movie(1,"HBO电影台",""));
movie_list.add(new Movie(0,"绿光战警","7:00"));
movie_list.add(new Movie(2,"钢铁人","9:00"));
movie_list.add(new Movie(0,"蝙蝠侠:开战时刻","11:00"));
movie_list.add(new Movie(1,"卫视电影台",""));
movie_list.add(new Movie(0,"海角七号","7:00"));
movie_list.add(new Movie(2,"阵头","9:00"));
movie_list.add(new Movie(0,"星空","11:00"));
这样movie_list就是你想要的资料了
而且因为是把自订的class放进去
所以很适合重复利用
例如说你今天想呈现的是一组联络人资料(姓名 手机 地址...)
你就依照上面的步骤自订一个class Userinfo
然後改成 user_list.add(new Userinfo(...));就好了
接着设定一下adapter
adapter = new MyAdapter(Main.this,movie_list);
^^^^你的activity的class
listV.setAdapter(adapter);
这样就只剩下最後一个部份了
那就是MyAdapter这个class
最一开始长这样
public class MyAdapter extends BaseAdapter{
}
接下来我们一步一步加进几个必要的东西进来
首先我们需要
private LayoutInflater myInflater;
private List<Movie> movies;
然後我们在MyAdapter建立的时候顺便传入两个东西
public MyAdapter(Context context,List<Movie> movie){
myInflater = LayoutInflater.from(context);
this.movies = movie;
}
movies就是你传入的整个list
也就是你想要建立的东西
接着我们再加入几个method 程式码应该不难理解我就不多做说明
@Override
public int getCount() {
return movies.size();
}
@Override
public Object getItem(int arg0) {
return movies.get(arg0);
}
@Override
public long getItemId(int position) {
return movies.indexOf(getItem(position));
}
最後重点就是getView了
在这之前我们先宣告一下inner class
private class ViewHolder {
TextView txtTitle;
TextView txtTime;
public ViewHolder(TextView txtTitle, TextView txtTime){
this.txtTitle = txtTitle;
this.txtTime = txtTime;
}
}
方便我们之後设定每一列的资料
getView一开始长这样
@Override
public View getView(int position, View convertView, ViewGroup parent) {
}
接着我们一步一步添加东西
ViewHolder holder = null;
if(convertView==null){
convertView = myInflater.inflate(R.layout.list_item, null);
holder = new ViewHolder(
(TextView) convertView.findViewById(R.id.title),
(TextView) convertView.findViewById(R.id.time)
);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
有关tag的功用 请参考这篇
http://www.cnblogs.com/qingblog/archive/2012/07/03/2575145.html
接着先取得现在要做的的资料
Movie movie = (Movie)getItem(position);
然後开始设定
//标题的颜色
int color_title[] = {Color.WHITE,Color.WHITE,Color.YELLOW};
//时间的颜色
int color_time[] = {Color.WHITE,Color.WHITE,Color.YELLOW};
//背景的颜色
int color_back[] = {Color.BLACK,Color.BLUE,Color.BLACK};
//时间是否显示
int time_vis[] = {View.VISIBLE,View.GONE,View.VISIBLE};
int type_num = movie.getType();
holder.txtTitle.setText(movie.getName());
holder.txtTitle.setTextColor(color_title[type_num]);
holder.txtTitle.setBackgroundColor(color_back[type_num]);
holder.txtTime.setText(movie.getTime());
holder.txtTime.setTextColor(color_time[type_num]);
holder.txtTime.setVisibility(time_vis[type_num]);
因为我的list并不是每一个item都长一样所以才需要这样设定
像是如果type是1 代表只需要显示一个电影台名称而已
就要把背景设成蓝色 时间也不需要显示所以设成View.GONE
如果你的每个item都长一样就不需要那麽大费周章了
最後记得 return convertView;
完整程式码在这里: MyAdapter.java
http://pastebin.com/GxBfpdCB
如此一来就大功告成了 顺利显示出我们想要的结果
使用自订class的好处就是当我们以後有不同需求的时候
就像一个范本可以自己随意修改
这篇也提供了一个固定的建立自订ListView的流程
1.建一个list_item.xml 在res/layout下 看你每一列想要长怎样
2.写一个[ ].java 里面说明你的资料结构为何
(例:Movie.java
http://pastebin.com/DWDx3EqW )
3.写一个MyAdapter.java
其实程式的结构无须修改
只要一些细节需要调整而已
这篇的作法基本上是参考
http://tinyurl.com/clen3tn
步骤清晰易懂也有附上完整的code
ListView有个很方便的功能叫做setTextFilterEnabled
可以很方便的做到搜寻的功能
但是自从我们自订ListView的内容以後
显然这个方法不能直接套用 所以要自己override一些东西
下一篇将延续这一篇的作法,说明如何针对自订的ListView做搜寻
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.135.198.74
1F:推 ian90911:推 12/27 13:23
2F:推 givemepass:讲的很详细 感谢你的分享 12/27 13:39
3F:推 givemepass:其实我做过一个专案也是节目表 其中有一个问题 12/27 13:43
4F:→ givemepass:就是当片名太长的时候 会变跑马灯模式 12/27 13:43
5F:→ givemepass:也是在MyAdapter里面做调整就好 12/27 13:44
6F:推 pkmilk:推~ 12/29 13:28