概要
需求:要实现类似于PC硬件检测工具,顺序的对每个硬件进行检查,check没问题就是绿色的√,失败则是红色的×,并显示具体出错的原因。效果如下:

image
实现原理
1.首先是AndroidManifest.xml配置如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
tools:context=".ui.CheckListAcvitity">
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.constraint.ConstraintLayout>
2.ListView的每个Item的布局xml文件:
<?xml version="1.0" encoding="utf-8"?>
<android.widget.LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:orientation="vertical"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/check_tiem_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:textSize="18dp"
android:text="TextView" />
<ProgressBar
android:id="@+id/loading"
style="?android:attr/progressBarStyle"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="10dp"
android:visibility="gone"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true" />
<ImageView
android:id="@+id/error"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="10dp"
android:visibility="gone"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:src="@drawable/error" />
<ImageView
android:id="@+id/pass"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="10dp"
android:visibility="gone"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:src="@drawable/pass"/>
</RelativeLayout>
<TextView
android:id="@+id/desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:text="desc"
android:textColor="@color/warn"
android:padding="10dp"/>
</android.widget.LinearLayout>
3.创建每个检测项的数据Bean类
public class ListItemBean {
private String name;
private int status;
private String desc;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
4.在adapter容器中根据Bean的status字段来更新view的显示和隐藏
public View getView(int position, View convertView, ViewGroup parent) {
CheckItemBase checkItemBase = (CheckItemBase)getItem(position);
View view = LayoutInflater.from(getContext()).inflate(R.layout.check_list_item, null);
TextView name = view.findViewById(R.id.check_tiem_name);
ProgressBar loadingView = view.findViewById(R.id.loading);
ImageView passView = view.findViewById(R.id.pass);
ImageView errorView = view.findViewById(R.id.error);
TextView descView = view.findViewById(R.id.desc);
name.setText(checkItemBase.getName());
switch (checkItemBase.getStatus()) {
case CheckItemBase.WAIT:
loadingView.setVisibility(View.GONE);
passView.setVisibility(View.GONE);
errorView.setVisibility(View.GONE);
break;
case CheckItemBase.LOADING:
loadingView.setVisibility(View.VISIBLE);
passView.setVisibility(View.GONE);
errorView.setVisibility(View.GONE);
break;
case CheckItemBase.PASSED:
loadingView.setVisibility(View.GONE);
passView.setVisibility(View.VISIBLE);
errorView.setVisibility(View.GONE);
break;
case CheckItemBase.ERROR:
loadingView.setVisibility(View.GONE);
passView.setVisibility(View.GONE);
errorView.setVisibility(View.VISIBLE);
break;
}
String desc = checkItemBase.getDesc();
if(desc != null && !desc.isEmpty()){
descView.setText(desc);
descView.setVisibility(View.VISIBLE);
}
return view;
}
5.初始化ListView和adpater,以及Thread
mListView = findViewById(R.id.list_view);
List<ListItemBean> listData = null;//数据源可以根据业务需要来赋值
ArrayAdapter adapter = new CheckListAdapter(this,R.id.list_view,listData);
mListView.setAdapter(adapter);
mCheckThread = new CheckThread(listData.size(),adapter,CheckListAcvitity.this);
mCheckThread.start();
6.CheckThread里面来控制check流程
public void run() {
CriticalTool.initData();
for(int i = 0;i < mCheckNum;i++){
ListItemBean checkItem = (ListItemBean) mAdapter.getItem(i);
checkItem.setStatus(ListItemBean.LOADING);
Util.updateList(mAdapter,mActivity);//更新ListView显示
boolean result = checkItem.check();//这里是一些check等耗时操作
if(result){
checkItem.setStatus(CheckItemBase.PASSED);
}else{
checkItem.setStatus(CheckItemBase.ERROR);
}
Util.updateList(mAdapter,mActivity);//耗时操作完成,状态改变,这里再次更新ListView
}
}
小结
总的来说,其实ListView的玩法很多,基于adapter的数据适配,以及自定义布局item,可以根据业务要求做出各种想过。当然,如果觉得ListView不满足业务需求,也可以重写ListView,比如类似于通讯录,这个可以通过重写ListView来实现。
以上如果有错误,欢迎讨论。