You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android开发:实现ListView行随服务器关闭状态动态变色

嘿,我来帮你搞定这个ListView行背景动态更新的问题!这其实核心就是让数据状态和UI联动,只要状态变化时通知适配器刷新对应行就行。我给你一步步拆解实现方案:

第一步:先给服务器数据加状态属性

首先得有个数据模型类,把每个服务器的IP和当前状态绑定在一起,这样状态变了我们能精准定位到对应行。比如:

public class ServerItem {
    public static final int STATUS_WAITING = 0;   // 等待处理
    public static final int STATUS_PROCESSING = 1;// 正在关闭
    public static final int STATUS_COMPLETED = 2; // 关闭完成

    private String ip;
    private int status;

    public ServerItem(String ip) {
        this.ip = ip;
        this.status = STATUS_WAITING; // 默认初始状态
    }

    // Getter和Setter方法
    public String getIp() { return ip; }
    public int getStatus() { return status; }
    public void setStatus(int status) { this.status = status; }
}

第二步:改造自定义ArrayAdapter

你的Adapter已经能在getView里设颜色了,现在结合ViewHolder模式优化性能,并且根据ServerItem的状态动态切换背景:

public class ServerAdapter extends ArrayAdapter<ServerItem> {
    private Context mContext;
    private List<ServerItem> mServerList;

    public ServerAdapter(Context context, List<ServerItem> serverList) {
        super(context, 0, serverList);
        mContext = context;
        mServerList = serverList;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;

        // 复用View,避免重复创建
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext)
                    .inflate(android.R.layout.simple_list_item_1, parent, false);
            holder = new ViewHolder();
            holder.ipText = convertView.findViewById(android.R.id.text1);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        ServerItem currentServer = mServerList.get(position);
        holder.ipText.setText(currentServer.getIp());

        // 根据状态设置背景色
        switch (currentServer.getStatus()) {
            case ServerItem.STATUS_PROCESSING:
                convertView.setBackgroundColor(Color.GREEN);
                break;
            case ServerItem.STATUS_COMPLETED:
                convertView.setBackgroundColor(Color.RED);
                break;
            default:
                convertView.setBackgroundColor(Color.TRANSPARENT); // 初始默认背景
                break;
        }

        return convertView;
    }

    // ViewHolder类,缓存控件引用
    static class ViewHolder {
        TextView ipText;
    }
}

第三步:后台任务中更新状态并通知UI

关键来了:后台执行关闭操作时,要先更新对应ServerItem的状态,然后在主线程通知适配器刷新该行(UI操作必须在主线程哦)。这里用AsyncTask举例子(如果是Kotlin的话用Coroutine更简洁):

private void startBatchShutdown(List<ServerItem> serverList, ServerAdapter adapter) {
    new AsyncTask<Void, Integer, Void>() {
        @Override
        protected Void doInBackground(Void... voids) {
            for (int i = 0; i < serverList.size(); i++) {
                ServerItem server = serverList.get(i);
                
                // 第一步:标记为正在处理,通知UI刷新
                publishProgress(i, ServerItem.STATUS_PROCESSING);
                
                // 执行你的服务器关闭逻辑(替换成你实际的代码)
                boolean isShutdownSuccess = shutdownServer(server.getIp());
                
                // 第二步:标记为处理完成,再次通知UI刷新
                publishProgress(i, ServerItem.STATUS_COMPLETED);
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            int position = values[0];
            int newStatus = values[1];
            
            // 更新数据状态
            serverList.get(position).setStatus(newStatus);
            // 只刷新对应行,比notifyDataSetChanged()更高效
            adapter.notifyItemChanged(position);
            // 如果你的Android版本较低不支持notifyItemChanged,就用adapter.notifyDataSetChanged();
        }
    }.execute();
}

// 模拟你的关闭服务器方法
private boolean shutdownServer(String ip) {
    try {
        // 这里写实际的关闭逻辑:比如Socket连接、发送关机命令等
        Thread.sleep(1000); // 模拟耗时操作
        return true;
    } catch (InterruptedException e) {
        e.printStackTrace();
        return false;
    }
}

第四步:初始化ListView和启动任务

在你的Activity/Fragment里完成初始化:

// 初始化服务器列表
List<ServerItem> serverList = new ArrayList<>();
serverList.add(new ServerItem("192.168.1.100"));
serverList.add(new ServerItem("192.168.1.101"));
// 添加更多服务器...

// 设置适配器
ServerAdapter adapter = new ServerAdapter(this, serverList);
ListView listView = findViewById(R.id.your_listview_id);
listView.setAdapter(adapter);

// 启动批量关闭任务
startBatchShutdown(serverList, adapter);

小提示

  • 用notifyItemChanged(position)代替全局的notifyDataSetChanged(),这样只会刷新状态变化的那一行,性能更好。
  • 如果用Kotlin开发,推荐用Coroutine替代AsyncTask,代码更简洁且避免内存泄漏问题。

内容的提问来源于stack exchange,提问作者Bernd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:45:13