界面示例:
界面布局: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
