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>  

上图:

参考技术A 您好,代码里面实现其实也差不多,你既然会通过XML文件设置,那么应该会使用BaseAdapter吧?BaseAdapter中的getView方法,返回的那个View,就是你listview中每一个item所对应的布局的View,若是还有不明白,请留下邮箱,我可以写一个demo发给你..本回答被提问者采纳 参考技术B 在adapter的getview里面加载便是了

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自定义控件--下拉刷新的实现

Android之自定义LoadingViewHelper

android ListView 嵌套GridView 子Item点击加载Activity

自定义ListView的RelativeLayout中的Android布局居中

android如何改变listview的每行高度

在 Android 中以编程方式创建带有自定义列表项的 ListView - 没有 xml 列表项布局