当前位置: 首页 > 知识库问答 >
问题:

如何通过另一个类将按钮的文本更新为列表视图,而不修改列表上其他按钮的文本?

段干博涉
2023-03-14

如何通过另一个类将按钮的文本更新为列表视图,而不修改列表上其他按钮的文本?

前任:

项目1[下载]

项目2[下载…60%]

项目3[下载…40%]

第4项[下载]

实际上,这很有效,但是滚动列表视图,其他按钮也会更改你的值。我需要创建一个可供下载的媒体列表,但是当我单击下载按钮时,下载开始,百分比更新,但其他按钮也更改了你的文本。。。

我想通过我的类下载器更新listView项目的文本“downloadBt”按钮,在它们上取得进展:下载...30%

最好的形式是什么?

解决方案:

创建List的新实例:

private static class ViewHolder {
    protected ImageView cover;
    protected TextView issueNumber;
    protected TextView details;
    protected Button downloadBt;
    protected Button moreBt;
    protected View convertView;  <<<
    protected ViewGroup parent; <<<
}

@ Override public View getView(int position,View convertView,View group parent){ View holder View holder;list.get(位置)。setListPosition(位置);

    if (convertView == null) {
        LayoutInflater inflater = context.getLayoutInflater();
        convertView = inflater.inflate(R.layout.list_item_list_issue, null);

        viewHolder = new ViewHolder();
        viewHolder.cover = (ImageView) convertView.findViewById(R.id.issue_list_item_cover);
        viewHolder.issueNumber = (TextView) convertView.findViewById(R.id.issue_list_item_number);
        viewHolder.details = (TextView) convertView.findViewById(R.id.issue_list_item_details);
        viewHolder.downloadBt = (Button) convertView.findViewById(R.id.list_item_issue_download);
        viewHolder.moreBt = (Button) convertView.findViewById(R.id.list_item_issue_more);
        viewHolder.parent = parent;
        viewHolder.convertView = convertView;

        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }

    viewHolder.issueNumber.setText(list.get(position).getIssue());
    viewHolder.downloadBt.setText(list.get(position).getDownloadStatus());

    try{
        vList.remove(position);
    }catch(Exception e){
        e.printStackTrace();
    }
    vList.add(position, viewHolder);
    return convertView;
}

在我的下载器类中,发送位置和适配器实例。我已经在我的适配器类中创建了一个方法刷新:

   public void refresh(int position){
        if((listView.getFirstVisiblePosition() <= position)&&(position <= listView.getLastVisiblePosition()))
            getView(position, vList.get(position).convertView, vList.get(position).parent);
    }

并且此操作仅更新列表视图中的选定项。

共有2个答案

张毅
2023-03-14

问题是您正在尝试更新按钮本身,您应该更新由适配器包装的项目并调用主线程adapter.notifyDataSetChanged();以刷新您的列表视图(触发对getView的其他调用以获取可见位置)。因此,您的ComicDownloader应该接受一个漫画对象和对适配器本身的引用。SunDeep是对的,转换视图(与其中的按钮一起)会被重用(这是正常的和需要的行为),您不应该依赖它。

此行:viewHolder.downloadBt.setText(list.get(position))。获取下载状态())应该在返回convertView之前调用,而不仅仅是在convertView为null时,这样做可以确保返回的视图根据请求的位置是最新的,无论是重用的还是新创建的。

编辑:

在DownloadListener实现中,IssueListAdapter.this。通知数据集已更改() 。目前,它是直接从run()调用调用的,在后台执行。因为这个听众已经知道哪个漫画被更新了,所以你可以为你所有的漫画设置一个单独的按钮。此外,由于你的ComicDownloader是最终版本,它将与“创建”它的第一个位置相关,这意味着当你开始下载时,你的按钮将正确更新,但后面下载的漫画可能不是你认为的。要解决这个问题,我建议在单击按钮时创建一个ComicDownloader(您也可以共享一个clickListener实例,并为按下的按钮检索当前漫画-为按钮设置与当前位置相关的标签是正确的方法)。

在您的ComicDownloader类中,执行器服务应该是静态的(下载器之间共享一个池)。

严修德
2023-03-14

!!更新!!

从日志中可以清楚地看到,您正在尝试从UI线程以外的其他线程更新按钮。UI对象/视图应仅从UI线程更新,UI线程不应用于长时间运行的操作。这些是你应该知道的基本知识。我强烈建议你仔细阅读文档和/或视频,以便更好地理解。

解决方案是使用Asyncask而不是Runnable,并且Asyncask有一个在UI线程上运行的方法进步更新()。或者,您可以将Runnable作为活动中的子类,并使用方法runOnUiThread()来更新视图。

当您将线程池和列表视图中的对象相关联时,我还注意到了它们的问题,这意味着,如果有10个convertView对象,您将有10个线程池和50个线程。这将降低性能,您实际上只使用了这个池中的一个线程。你需要加强基础知识,并重新审视解决方案。

在列表视图中,项目对象被重用,这是Adaptergetview()方法中的转换视图参数。因此,当转换视图null时,您第一次创建项目视图对象,当您滚动浏览时,相同的对象被重新使用,而不是创建一个新对象,因为这节省了CPU周期(从而节省了电池),避免了垃圾回收机制和创建新对象。换句话说,如果您有一个包含100个项目的列表,并且屏幕上只能容纳10个项目,那么即使您滚动浏览所有100个项目,也只会创建10个对象,因为当屏幕响应滚动时,同样的10个对象会被重新使用。子视图也是如此(即按钮也是如此)。

从您的代码中,我看到您正在下载线程中使用Button对象按钮对象也被重用。检查这是否可能是问题所在。

如果您还没有,请查看此视频。

 类似资料:
  • 我正在制作一个有评论和描述的帖子的应用程序。每个帖子上有三个按钮。1描述2评论,第三个是喜欢按钮。我在自定义适配器的getview方法中设置了一个按钮点击侦听器。当我点击描述按钮时,该帖子的描述应该显示在按钮下。但是当我点击描述按钮时,其他一些列表视图项目的描述也显示出来。我只想显示被点击描述按钮的帖子的描述。这是我的代码: getview代码: XML代码:

  • 所以假设我有一个“开”和一个“关”按钮。当我按下打开按钮时,我希望打开按钮隐藏自己,关闭按钮显示出来,反之亦然。 一个人怎么能这么做?

  • 我有两个类和一个文本文件数据库,第一个类中的,我们将其称为自动设置为数据库中的数字。现在,在中,我有一个小的和一个文本字段,当然还有一个按钮,我在文本字段中的值会覆盖数据库中的值,但问题出在这里。第一个类中的标签在运行时不会更新,但如果我重新启动它,它会显示我想要的值。 如何在程序运行时更新它?我尝试在另一个类的中更改标签,但它每次都给我一个。 我怎么解决这个? 我希望这让我更容易理解我的问题。这

  • 就像标题一样,如果我按下列表视图中的按钮,我希望将按钮的位置发送到另一个活动 我不知道你想检查我做了什么。 我把按钮按下时的方法,这个方法在list适配器里面

  • 在install4j中,我如何将屏幕中的“Next”按钮的文本更改为“install”,就在安装屏幕之前?

  • 我正在为一个网格窗格分配几个按钮。每个按钮都有一个数字作为其文本。我创建了一个arrayList numbers并向其添加数字。我使用集合来洗牌数字(我希望每次运行程序时在每个按钮中都有一个随机数)。然后我使用这个ArrayList向每个按钮文本添加一个数字。 我希望每个按钮都有不同的编号。但是,现在1列中的每个按钮都有相同的编号。 任何关于如何修复此问题的建议都将非常感谢(按钮的文本随机分配)。