界面示例:
界面布局: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 下载网络数据、图像