android listview怎么加载自定义布局,还必须是在代码里面写
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android listview怎么加载自定义布局,还必须是在代码里面写相关的知识,希望对你有一定的参考价值。
android listview怎么加载自定义布局,还必须是在代码里面写,通过XML文件我也会,就是写在代码里面不会,希望有高人可以指点迷津,感激不尽
前面总结了如何应用android自带的布局到ListView中去,现在如果想让自己的ListView更生动,只需要将自己定义的布局应用到ListView中,在布局中添加一些生动的元素,比如,图标。
一、为ListView每个item添加一个图标
先看效果:
首先定义一个entry.xml布局文件:
[html] view plaincopyprint?
1<span style="font-size:18px;">
2<?xml version="1.0" encoding="utf-8"?>
3<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
4android:layout_width="fill_parent"
5 android:layout_height="60dp"
6 android:orientation="horizontal" >
7 <!-- 图标 -->
8 <ImageView
9 android:layout_width="48dp"
10android:layout_height="48dp"
11android:src="@drawable/preview"
12android:layout_gravity="center"
13android:layout_marginLeft="10dp"
14 />
15 <!-- 这里引用android自带的布局simple_list_item_1 -->
16<include
17 layout="@android:layout/simple_list_item_1"
18 />
19</LinearLayout>
20
21</span>
然后将此布局文件应用到ListView中去:
1[java] view plaincopyprint?
2<span style="font-size:18px;">
3public class ListViewDemo extends ListActivity
4
5 private List<Map<String,String>> data = new ArrayList<Map<String,String>>();
6@Override
7 public void onCreate(Bundle savedInstanceState)
8 super.onCreate(savedInstanceState);
9 setContentView(R.layout.main);
10 Map<String, String> map1 = new HashMap<String, String>();
11map1.put("姓名", "A君");
12 data.add(map1);
13 Map<String, String> map2 = new HashMap<String, String>();
14 map2.put("姓名", "B君");
15 data.add(map2);
16 setListAdapter(new SimpleAdapter(this,data,R.layout.entry,
17 new String[]"姓名",
18 new int[]android.R.id.text1
19 ));
20
21
22</span>
二、动态设置图标
以上例子,处理的非常简单,全部图标都一样,现在要想动态设置每个item中元素,需要继承Adapter子类,通过重写getView()函数,为每个item都设置不同的风格。
下面创建BaseAdapter的子类MyAdapter:
[java] view plaincopyprint?
1<span style="font-size:18px;">
2private class MyAdapter extends SimpleAdapter
3 //icons存储图标的id
4 private int[] icons = null;
5
6private Context context;
7
8 public MyAdapter(Context context, List<? extends Map<String, ?>> data,
9 int resource, String[] from, int[] to,int[] icons)
10super(context, data, resource, from, to);
11 // TODO Auto-generated constructor stub
12 this.icons = icons;//传入存储图标id的数组
13 this.context = context;
14
15
16 /* (non-Javadoc)
17* 重写getView函数,由于SimpleAdapter能处理TextView,仅仅是不能设置图标
18 */所以,只需要在调用父类的getView函数的基础上,设置上相应的图标即可
19 @Override
20 public View getView(int position, View convertView, ViewGroup parent)
2 1 // TODO Auto-generated method stub
22 ViewHolder holder = null;
23 if(convertView == null)
24 holder = new ViewHolder();
25convertView = super.getView(position, convertView, parent);//调用父类的getView函数,设置TextView
26 holder.imageView = (ImageView)convertView.findViewById(R.id.myimageview);
27 convertView.setTag(holder);
28 else
29 holder = (ViewHolder)convertView.getTag();
30
31//从icons中随机选出一个,并设置作为item的图标
32Random random = new Random();
33 int index = random.nextInt(icons.length);
34 holder.imageView.setImageResource(icons[index]);
35
36 return convertView;
37
38
39private class ViewHolder
40 ImageView imageView;
41
42
43
44</span>
MyAdapter继承自SimpleAdapter,重写getView()函数,使listView中每个item的图标都是随机选择的。对MyAdapter的应用如下:
[html] view plaincopyprint?
1<span style="font-size:18px;">
2//数组存储图标id
3private int[] myicons = R.drawable.preview,R.drawable.preview1,R.drawable.preview2,R.drawable.preview3;
4
5</span>
[html] view plaincopyprint?
1<span style="font-size:18px;">
2setListAdapter(new </span><span style="font-size:18px;color:#FF0000;">MyAdapter</span><span style="font-size:18px;">(this, data, R.layout.entry, new String[]"姓名",
3 new int[]android.R.id.text1,</span><span style="font-size:18px;color:#FF0000;"> myicons</span><span style="font-size:18px;">));//为ListView设置MyAdapter适配器
4
5</span>
上图:
ListView显示数据库的数据-采用自定义布局-向上滑动可以加载更多数据
本案例使用自定义布局实现在ListView中显示数据库的数据(用户名、手机号)的功能,ListView向上滑动可以加载更多数据。
1.user_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView
android:id="@+id/tv_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:text="chj" />
<TextView
android:id="@+id/tv_phone"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="13527168697" />
<Button
android:id="@+id/btn_call"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="拨号" />
<Button
android:id="@+id/btn_sms"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="信息" />
</LinearLayout>
2.在activity_main.xml中添加ListView控件 id=”@+id/lv_users”
3.自定义的adapter UserAdapter.java
package com.example.dbhytc.adapter;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.example.dbhytc.R;
import com.example.dbhytc.SmsActivity;
public class UserAdapter extends BaseAdapter
private Context context;
private List<Map<String, Object>> data;
private ViewHolder viewHolder;
public UserAdapter(Context context, List<Map<String, Object>> data)
this.context = context;
this.data = data;
@Override
public int getCount()
// TODO Auto-generated method stub
return data.size();
@Override
public Object getItem(int position)
// TODO Auto-generated method stub
return data.get(position);
@Override
public long getItemId(int position)
// TODO Auto-generated method stub
return position;
@Override
public View getView(int position, View convertView, ViewGroup parent)
if (convertView == null)
viewHolder = new ViewHolder();
convertView = View.inflate(context, R.layout.user_item, null);
viewHolder.tv_name = (TextView) convertView
.findViewById(R.id.tv_name);
viewHolder.tv_phone = (TextView) convertView
.findViewById(R.id.tv_phone);
viewHolder.btn_call = (Button) convertView
.findViewById(R.id.btn_call);
viewHolder.btn_sms = (Button) convertView
.findViewById(R.id.btn_sms);
convertView.setTag(viewHolder);
else
viewHolder = (ViewHolder) convertView.getTag();
// 赋值
Map map = data.get(position);
viewHolder.tv_name.setText(map.get("name").toString());
final String phone = map.get("phone").toString();
viewHolder.tv_phone.setText(phone);
viewHolder.btn_call.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
Toast.makeText(context, "打电话", 1).show();
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"
+ phone));
context.startActivity(intent);
);
viewHolder.btn_sms.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
Toast.makeText(context, "发信息", 1).show();
// 执行一个意图 打开发短信界面
// 1.定义一个意图
Intent intent = new Intent(context, SmsActivity.class);
// 通过这个意图可以附带数据
intent.putExtra("phone", phone);
// 2.执行意图
context.startActivity(intent);
);
return convertView;
class ViewHolder
public TextView tv_name, tv_phone;
public Button btn_call, btn_sms;
4.HytcSQLiteOpenHelper.java
package com.example.dbhytc.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class HytcSQLiteOpenHelper extends SQLiteOpenHelper
//数据库的名称
private static String name="hytc.db";
//数据库的版本
private static Integer version=2;
/**
* 只需保证 在实例化子类对象时,保证父类对象先实例化
* @param context
*/
public HytcSQLiteOpenHelper(Context context)
super(context, name, null, version);
/**
* 第一次执行的时候创建数据库
*/
@Override
public void onCreate(SQLiteDatabase db)
db.execSQL("CREATE TABLE user (id integer primary key autoincrement, name varchar(20))");
/**
* 当版本号发生变化的时候 触发
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
db.execSQL("alter table user add column phone varchar(11)");
5.UserDao中定义了查询数据data集合的方法getObjects()及得到总页数的方法getPages()
package com.example.dbhytc.dao;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.example.dbhytc.db.HytcSQLiteOpenHelper;
public class UserDao
// 数据库管理操作对象
private HytcSQLiteOpenHelper helper;
private List<Map<String, Object>> data;
private int pagesize = 12;
public UserDao(List<Map<String, Object>> data, Context context)
this.data = data;
helper = new HytcSQLiteOpenHelper(context);
/**
* 查询方法
*/
public void getObjects(Integer nowpage)
// 获取SQLiteDatabase对象
SQLiteDatabase db = helper.getReadableDatabase();
// 计算开始的记录数
int startSize = (nowpage - 1) * pagesize;
Cursor c = db.rawQuery("select id,name,phone from user limit ?,?",
new String[] startSize + "", pagesize + "" );
while (c.moveToNext())
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", c.getString(c.getColumnIndex("name")));
map.put("phone", c.getString(c.getColumnIndex("phone")));
map.put("id", c.getInt(c.getColumnIndex("id")));
data.add(map);
c.close();
db.close();
public int getPages()
int pages = 0;
// 获取SQLiteDatabase对象
SQLiteDatabase db = helper.getReadableDatabase();
// 计算开始的记录数
Cursor c = db.rawQuery("select count(*) as c from user", null);
if (c.moveToNext())
int count = c.getInt(c.getColumnIndex("c"));
//计算总页数
pages = count % pagesize == 0 ? count / pagesize : count / pagesize
+ 1;
c.close();
db.close();
return pages;
6.MainActivity.java
package com.example.dbhytc;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.os.Bundle;
import android.view.ViewTreeObserver.OnScrollChangedListener;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
import com.example.dbhytc.adapter.UserAdapter;
import com.example.dbhytc.dao.UserDao;
public class MainActivity extends Activity implements OnScrollListener
// 声明控件
private ListView lv_users;
private UserDao userDao;
private List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
private int nowpage = 1;
private boolean isLastRow = false;
private UserAdapter adapter;
private int pages;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取控件对象
lv_users = (ListView) findViewById(R.id.lv_users);
// 数据
userDao = new UserDao(data, this);
// 查询出总页数
pages = userDao.getPages();
userDao.getObjects(nowpage);
adapter = new UserAdapter(this, data);
// 设置适配器
lv_users.setAdapter(adapter);
// 注册事件监听 滚动的事件
lv_users.setOnScrollListener(this);
/**
* 当scrollstate改变的时候 都会触发该函数 scrollstate 0 空闲 1滚动 2抛 1 0 1 2 0
*/
@Override
public void onScrollStateChanged(AbsListView view, int scrollState)
// 判断是否是最后一行
if (isLastRow)
// 再判断是否停止滚动
if (scrollState == SCROLL_STATE_IDLE)
// pages = userDao.getPages();
if (nowpage < pages)
// 让当前页加1
nowpage = nowpage + 1;
// 假设往这个集合中添加数据
userDao.getObjects(nowpage);
// 通知变化
adapter.notifyDataSetChanged();
// 改变值
isLastRow = false;
/**
* 当滚动的时候触发的函数 firstVisibleItem:条目可见第一个位置值 visibleItemCount:条目可见的数量
* totalItemCount data集合数量 条目总个数
*/
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount)
// 判断
if ((firstVisibleItem + visibleItemCount) >= totalItemCount)
isLastRow = true;
以上是关于android listview怎么加载自定义布局,还必须是在代码里面写的主要内容,如果未能解决你的问题,请参考以下文章
android ListView 嵌套GridView 子Item点击加载Activity