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

求助:如何实现点击ListView Item时显示30秒平滑进度条

实现ListView Item点击后显示30秒平滑进度条的方案

针对你的需求,我整理了一套可行的实现思路,结合你现有代码一步步修改:

1. 给列表项布局添加进度条

首先打开你的Resource.Layout.List布局文件,添加一个水平进度条,默认隐藏:

<!-- 放在现有布局的合适位置,比如TextView下方 -->
<ProgressBar
    android:id="@+id/itemProgressBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:visibility="gone"
    style="@android:style/Widget.ProgressBar.Horizontal"/>

2. 在ListAdapter中维护进度状态

因为ListView会复用View,不能直接把进度存在View里,得给适配器加两个集合跟踪每个Item的状态:

public class ListAdapter : ArrayAdapter {
    // 记录每个位置的进度值,初始为0
    private List<int> _progressList;
    // 记录哪个位置正在加载,防止重复点击
    private HashSet<int> _loadingPositions = new HashSet<int>();
    private List<GeraeteModel> Geraetelist; // 假设你的数据模型是这个类型
    private Context _context;

    public ListAdapter(Context context, int resource, List<GeraeteModel> objects, string serverIp) : base(context, resource, objects) {
        Geraetelist = objects;
        _context = context;
        // 初始化进度列表,每个Item初始进度0
        _progressList = new List<int>(Enumerable.Repeat(0, objects.Count));
    }

    // 启动指定位置的进度加载
    public async Task StartProgress(int position) {
        if (_loadingPositions.Contains(position)) return;
        _loadingPositions.Add(position);
        // 进度从0到100,耗时30秒,每100ms更新一次保证平滑
        int totalSteps = 300; // 30秒 = 300*100ms
        int step = 100 / totalSteps;
        for (int i = 0; i <= totalSteps; i++) {
            int currentProgress = i * step;
            _progressList[position] = currentProgress;
            // 刷新列表更新进度
            NotifyDataSetChanged();
            await Task.Delay(100);
        }
        // 加载完成后重置状态,隐藏进度条
        _progressList[position] = 0;
        _loadingPositions.Remove(position);
        NotifyDataSetChanged();
    }

    public override View GetView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        if (v == null) {
            LayoutInflater inflater = (LayoutInflater)_context.GetSystemService(Context.LayoutInflaterService);
            v = inflater.Inflate(Resource.Layout.List, parent, false);
        }

        // 你的原有代码...
        v.FindViewById<ImageView>(Resource.Id.typeImageView).SetImageResource(Resource.Drawable.Icon);
        v.FindViewById<TextView>(Resource.Id.numberTextView).Text = Geraetelist[position].geraeteplatz;
        v.FindViewById<TextView>(Resource.Id.descriptionTextView).Text = Geraetelist[position].geraeteinformation;
        ImageView iv = v.FindViewById<ImageView>(Resource.Id.bspImageView);
        iv.SetImageResource(Geraetelist[position].bespielt == "N" ? Resource.Drawable.greenPoint : Resource.Drawable.redPoint);

        // 新增:处理进度条的显示和进度更新
        ProgressBar progressBar = v.FindViewById<ProgressBar>(Resource.Id.itemProgressBar);
        if (_loadingPositions.Contains(position)) {
            progressBar.Visibility = ViewStates.Visible;
            progressBar.Progress = _progressList[position];
        } else {
            progressBar.Visibility = ViewStates.Gone;
            progressBar.Progress = 0;
        }

        return v;
    }
}

3. 修改Activity中的Item点击事件

在TableActivity的OnItemClick方法里,调用适配器的StartProgress方法启动对应位置的进度条:

private async void OnItemClick(object sender, AdapterView.ItemClickEventArgs e) {
    var geraete = geraeteliste.CurrentGeraeteliste[e.Position];
    if (geraete.bespielt == "J") return;
    
    // 这里保留你的其他业务逻辑...
    
    // 启动对应位置的进度条
    if (adapter is ListAdapter listAdapter) {
        await listAdapter.StartProgress(e.Position);
    }
}

关键注意点

  • ListView复用问题:必须用集合跟踪每个Item的进度和加载状态,不能直接依赖View的状态,否则滚动时进度条会错乱。
  • 防止重复点击:用HashSet记录正在加载的位置,避免同一个Item被多次点击触发多个进度任务。
  • 平滑度控制:通过每100ms更新一次进度,保证进度条的平滑动画效果,你也可以根据需求调整更新间隔。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:40:24