安卓 ListView列表

本文详细介绍了Android中ListView组件的实现原理与应用实践,包括自定义列表适配器ListViewCommonAdapter,列表项数据结构ListIteamData,以及列表Activity主页面ListPage的实现流程。深入解析了如何加载网络数据,动态更新列表视图,并处理列表项的点击事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

界面示例

界面布局:thumbsup_page_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <RelativeLayout
        android:id="@+id/thumbsup_tittle_bg"
        android:layout_width="fill_parent"
        android:layout_height="181px"
        android:background="@drawable/thumbsup_tittle_bg" >
    </RelativeLayout>

    <ImageView
        android:id="@+id/thumbsup_close"
        android:layout_width="36px"
        android:layout_height="36px"
        android:layout_alignParentRight="true"
        android:padding="5dp"
        android:src="@drawable/thumbsup_close" />

    <TextView
        android:id="@+id/thumbsup_tittle_note"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/thumbsup_tittle_bg"
        android:background="#0288d1"
        android:gravity="center"
        android:paddingBottom="10dp"
        android:paddingTop="10dp"
        android:text="thumbsup_tittle_note"
        android:textColor="@android:color/white"
        android:textSize="24sp"
        tools:text="关注粉丝页,获取免费金币" />

    <LinearLayout
        android:id="@+id/thumbsup_list_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/thumbsup_tittle_note"
        android:background="#FFDCDCDC"
        android:orientation="vertical" >
    </LinearLayout>

</RelativeLayout>

列表项布局:thumbsup_list_iteam_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <RelativeLayout
        android:id="@+id/thumbsup_layout_bg"
        android:layout_width="fill_parent"
        android:layout_height="90px"
        android:layout_marginBottom="1dp"
        android:layout_marginLeft="0dp"
        android:layout_marginRight="0dp"
        android:layout_marginTop="1dp"
        android:background="@drawable/thumbsup_list_iteam_bg"
        android:paddingBottom="5dp"
        android:paddingLeft="10dp"
        android:paddingRight="5dp"
        android:paddingTop="5dp">


            <ImageView
                android:id="@+id/thumbsup_iteam_icon"
                android:layout_width="77px"
                android:layout_height="77px"
                android:layout_centerVertical="true"
                android:src="@drawable/thumbsup_list_game_icon"/>

            <ImageView
                android:id="@+id/thumbsup_iteam_button"
                android:layout_width="100px"
                android:layout_height="50px"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:src="@drawable/thumbsup_list_click_button" />
            
            
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="5dp"
                android:layout_toLeftOf="@id/thumbsup_iteam_button"
                android:layout_toRightOf="@id/thumbsup_iteam_icon"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/thumbsup_note1"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="关注Warfare Strike粉丝页"
                    android:textColor="@android:color/black"
                    android:textSize="16sp" />

                <TextView
                    android:id="@+id/thumbsup_note2"
                    android:layout_width="match_parent"
                    android:layout_height="0px"
                    android:text="剩余次数:10"
                    android:textColor="@android:color/black"
                    android:textSize="12sp" />

            </LinearLayout>

    </RelativeLayout>

</RelativeLayout>

 

ListViewCommonAdapter.java 用于生成List列表

package sci.tool;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;


/** ListAdapter.java: 安卓listView内容适配工具类。
 * 让IteamDatas中的数据按照布局layoutName进行显示 ;
 * 
 * (TE为待自定义的数据类,里面保存单个列表项的所有数据信息)
 * 1、继承该类,继承方法 ListViewCommonAdapter(), 通过该接口指定单个列表项的布局文件名、设置所有列表项数据;
 * 2、实现方法,setIteamView(TE iteamData), 设置每个列表项的显示;
 * 3、实现方法,setIteamClick(Context iteamContext, TE iteamData), 设置每个列表项的点击响应;
 * 4、调用 getListView()获取ListView,或者直接显示到ViewGroup中ShowListViewIn(ViewGroup group)
 * 
 * ----- 2018-6-7 下午4:18:10 scimence */
public abstract class ListViewCommonAdapter<TE> extends ArrayAdapter<TE>
{
	LayoutInflater layoutInflater;
	int resourceId;
	
	Context context;
	
	/** 根据资源类型、名称,获取资源id */
	public static int getId(Context context, String name, String defType)
	{
		return context.getResources().getIdentifier(name, defType, context.getPackageName());
	}
	
	/** 指定 列表项布局、数据, 构建Adaper.
	 * 
	 * (如:iteam_layout.xml -> listIteam_LayoutName="iteam_layout";
	 * TE[] IteamDatas -> 对应每一个列表项的数据, TE为自定义类包含单个列表项的所有数据;)
	 * */
	public ListViewCommonAdapter(Context context, String listIteam_LayoutName, TE[] IteamDatas)
	{
		super(context, 0, IteamDatas); 				// 调用数组适配器,进行初始化
		
		this.context = context;
		
		this.resourceId = getId(context, listIteam_LayoutName, "layout");	// listView项布局资源id
		layoutInflater = LayoutInflater.from(context);  				// 获取LayoutInflater服务
	}
	
	/** 获取指定postion位置的列表项对应视图,list列表项view生成 */
	@Override
	public View getView(int position, View convertView, ViewGroup parent)
	{
		// 从预定义的xml布局创建新的view视图
		if (convertView == null) convertView = layoutInflater.inflate(resourceId, null);
		
		// 修改视图中的信息
		TE iteam = getItem(position);   			// 获取position个位置的列表项数据
		
		// int textViewId = ResUtil.getId(convertView.getContext(), "ltpay_text", "id");
		// TextView textView = (TextView) convertView.findViewById(textViewId);
		// textView.setText(iteam.Title);
		
		curIteamView = convertView;
		setIteamView(iteam); // 调用虚方法,设置list列表项内容
		curIteamView = null;
		
		return convertView;   								// 返回按给定数据显示视图
	}
	
	/** 临时记录当前操作的ListView项 */
	private View curIteamView = null;
	
	/** 获取list列表项指定id对应的View, 若未指定viewId则获取对应Iteam项对应View */
	public View IteamView(String viewId)
	{
		if (viewId == null || viewId.equals("")) return curIteamView;
		
		int id = getId(curIteamView.getContext(), viewId, "id"); // 获取ListIteam列表项中指定名称的View的id
		View view = curIteamView.findViewById(id); // 根据id获取对应的View
		
		return view;
	}
	
	/** 获取list列表项指定id对应的View, 若未指定viewId则获取对应Iteam项对应View */
	public View IteamView(View iteamView, String viewId)
	{
		int id = getId(iteamView.getContext(), viewId, "id");     // 获取ListIteam列表项中指定名称的View的id
		View view = iteamView.findViewById(id);                              // 根据id获取对应的View
		
		return view;
	}
	
	/** 设置list列表项内容。
	 * 
	 *  TE iteamData为:待显示的单个列表项的对应数据
	 *  列表项的子控件,通过 IteamView(String viewId)获取指定名称的View;
	 *   */
	public abstract void setIteamView(TE iteamData);
	
	// list的事件响应
	OnItemClickListener listenList = new OnItemClickListener()
	{
		@Override
		public void onItemClick(AdapterView<?> arg0, View iteamView, int postion, long arg3)
		{
			curIteamView = iteamView;
			setIteamClick(context, getItem(postion));
			curIteamView = null;
		}
	};
	
	/** 设置list列表项点击响应逻辑。
	 * 
	 * TE iteamData为:待显示的单个列表项的对应数据
	 * iteamContext为:单个列表项的Context
	 * 列表项的子控件,通过 IteamView(String viewId)获取指定名称的View;
	 *  */
	public abstract void setIteamClick(Context iteamContext, TE iteamData);
	
	// ------------
	
	/** 生成listView */
	public ListView getListView()
	{
		ListView list = new ListView(context);				// 创建listView
		list.setDivider(new ColorDrawable(Color.GRAY));  	// 设置分割线颜色
		list.setDividerHeight(1);							// 设置分割线尺寸
		
		list.setAdapter(this);					// 为列表添加显示数据
		list.setOnItemClickListener(this.listenList);
		
		return list;
	}
	
	/** 生成listView, 并显示在ViewGroup中 */
	public void ShowListViewIn(ViewGroup group)
	{
		ListView list = this.getListView();    // 生成listView
		list.setDividerHeight(0);                // 设置分割线尺寸
		
		// 在content中显示ListView信息
		group.removeAllViews();
		group.addView(list);                    // 添加listView为显示内容页
	}
}

定义列表项数据类(根据列表项自定义):

ListIteamData.java


package sci.demo.androidlistview;

import org.json.JSONArray;
import org.json.JSONObject;

import sci.tool.WebTool;
import android.graphics.drawable.Drawable;
import android.util.Log;


/** ListIteamData.java: 定义该结构用于表示列表项的数据结构 ----- 2018-10-25 下午8:20:46 scimence */
public class ListIteamData
{
	public String iconUrl, btnUrl1, btnUrl2, note;		// 图标url地址、按钮url、灰色按钮url、文本说明信息
	
	Drawable icon, btn1, btn2;							// 图标图像、按钮图像、灰色按钮图像
	public boolean isClicked = false;					// 其他信息,记录列表项是否已点击
	
	ListIteamData()
	{}
	
	// public ListIteamData(String... data)
	// {
	// this.iconUrl = data[0];
	// this.btnUrl1 = data[1];
	// this.note1 = data[2];
	// this.note2 = data[3];
	// }
	
	// 从Json对象创建
	public ListIteamData(JSONObject obj)
	{
		try
		{
			this.iconUrl = obj.optString("iconUrl", "");
			this.btnUrl1 = obj.optString("btnUrl1", "");
			this.btnUrl2 = obj.optString("btnUrl2", "");
			this.note = obj.optString("note", "");
			
			// 下载图像资源
			icon = WebTool.GetDrawable(iconUrl);
			btn1 = WebTool.GetDrawable(btnUrl1);
			btn2 = WebTool.GetDrawable(btnUrl2);
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	// ---------------------------------
	
	// 从Json数组解析数据
	public static ListIteamData[] ToArray(JSONArray data)
	{
		ListIteamData[] Array = new ListIteamData[data.length()];
		
		for (int i = 0; i < data.length(); i++)
		{
			try
			{
				JSONObject obj = data.getJSONObject(i);
				Array[i] = new ListIteamData(obj);
			}
			catch (Exception ex)
			{
				ex.printStackTrace();
				Log.e("thumbsupPage.java", "数据ListIteamData解析异常!");
			}
		}
		return Array;
	}
}

ListAdapter.java 用于生成ListView


package sci.demo.androidlistview;

import sci.tool.ListViewCommonAdapter;
import android.content.Context;
import android.widget.ImageView;
import android.widget.TextView;


/** ListAdapter.java: ----- 2018-10-25 下午8:32:21 scimence */
public class ListAdapter extends ListViewCommonAdapter<ListIteamData>
{
	/** 1、继承方法 ListViewCommonAdapter(), 通过该接口指定单个列表项的布局文件名、设置所有列表项数据;
	 * 
	 * @param context
	 * @param listIteam_LayoutName 布局文件名
	 * @param IteamDatas 所有列表项数据 */
	public ListAdapter(Context context, String listIteam_LayoutName, ListIteamData[] IteamDatas)
	{
		super(context, listIteam_LayoutName, IteamDatas);
	}
	
	/** 2、setIteamView(TE iteamData), 设置每个列表项的显示;
	 * 
	 * @param iteamData 将显示的列表项的对应数据 */
	@Override
	public void setIteamView(ListIteamData iteamData)
	{
		// TODO 根据列表项数据iteamData,设置列表项的显示
		// View view = IteamView("name"); //获取列表项中,指定名称的view
		
		// 游戏Icon
		ImageView Icon = (ImageView) IteamView("thumbsup_iteam_icon");
		// Icon.setImageDrawable(iteamData.icon);
		Icon.setImageDrawable(iteamData.icon);
		
		// 按钮
		ImageView button = (ImageView) IteamView("thumbsup_iteam_button");
		button.setImageDrawable(!iteamData.isClicked ? iteamData.btn1 : iteamData.btn2);
		
		// 说明信息
		TextView note1 = (TextView) IteamView("thumbsup_note1");
		note1.setText(iteamData.note);
	}
	
	/** 3、setIteamClick(Context iteamContext, TE iteamData), 设置每个列表项的点击响应;
	 * 
	 * @param iteamContext 列表项对应的context
	 * @param iteamData 待设置点击逻辑的列表项的对应数据 */
	@Override
	public void setIteamClick(Context iteamContext, ListIteamData iteamData)
	{
		// TODO 根据列表项数据iteamData,设置列表项的点击处理逻辑
		// View view = IteamView("name"); //获取列表项中,指定名称的view
		
		if (!iteamData.isClicked)
		{
			iteamData.isClicked = true;
			
			// 设置按钮为已点击对应的图像
			ImageView button = (ImageView) IteamView("thumbsup_iteam_button");
			button.setImageDrawable(iteamData.btn2);
			
			// 执行按钮点击对应逻辑
			// ...
			
		}
	}
	
}

ListPage.java 列表Activity主页面


package sci.demo.androidlistview;

import org.json.JSONArray;
import org.json.JSONObject;

import sci.tool.ActivityComponent;
import sci.tool.ThreadTool;
import sci.tool.WebTool;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.Toast;


/** list列表页主界面  ---- 2018-10-25 下午8:32:21 scimence*/
public class ListPage extends ActivityComponent
{
	@Override
	public void Init(Bundle savedInstanceState)
	{
		// 设置Activity页面布局
		setContentView("list_view_page");
		
		ThreadTool.getMainHandler().postDelayed(new Runnable()
		{
			@Override
			public void run()
			{
				// 获取网络数据, 列表项数据信息获取
				String dataUrl = "https://raw.githubusercontent.com/scimence/AndroidListview/master/files/listData";
				JSONObject webData = WebTool.GetJSONObject(dataUrl);
				
				if (webData != null)
				{
					// 设置标题栏背景图
					Drawable tittlePic = WebTool.GetDrawable(webData.optString("tittlePic"));
					if(tittlePic != null) ImageView("thumbsup_tittle_bg").setImageDrawable(tittlePic);
					
					// 设置标题栏显示信息
					TextView("thumbsup_tittle_note").setText(webData.optString("title"));
					
					// 生成列表项显示到ViewGroup中
					{
						JSONArray data = webData.optJSONArray("listData");		// 数据根据列表项所需数据,自行定义
						
						ListIteamData[] datas = ListIteamData.ToArray(data); 	// 从JSON数据中解析列表信息
						ListAdapter adapter = new ListAdapter(ListPage.this, "list_iteam_layout", datas/* , call */);
						
						LinearLayout content = LinearLayout("thumbsup_list_content");	// 获取页面的LinerLayout作为显示列表的ViewGroup
						adapter.ShowListViewIn(content);	// 显示列表
					}
				}
			}
		}, 1000);	// 在主线程中,延时进行列表信息的载入
	}
	
	
	
	/* 设置View点击响应事件 */
	@Override
	public void Click(String viewId)
	{
		String text = "点击了View -> " + viewId;
		Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
		
		// TODO View点击响应逻辑
	}
	
}

ActivityComponent.java 为 Activity的子类,简化Activity的使用

ThreadTool.java 线程辅助操作类,用于在主线程、非主线程中 执行逻辑

WebTool.java 下载网络数据、图像

 

AndroidListView源码.zip

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值