【问题标题】:Android downloading progressbar whole on listview itemsAndroid在listview项目上整体下载进度条
【发布时间】:2015-07-07 21:55:47
【问题描述】:

我正在编写简单的列表视图作为下载列表,用户可以单击它来下载它。我从互联网下载文件没有任何问题,但是在列表视图项目上可见进度条之后。那是显示整个列表视图,我无法处理不显示整个列表视图而仅在单击的列表视图的要下载的项目上显示进度条。

我的适配器:

public void fillItems(final AdapterMessageContent adapter, final MessagesList item, final int position) {
    stream_url = item.getStream_link().split("/");
    stream_filename = stream_url[stream_url.length - 1];

    File file = new File(G.dir_image + "/" + stream_filename);
    if (item.getMsg_type() != 0) {
        if (!file.exist()) {
            Log.e("", "visible downloader icon");
            UI.imgv_image_item.setImageBitmap(BitmapFactory.decodeFile(G.dir_app + "/" + "thumbs/" + item.getPreview_image_url()));

            /* SET tag to handle this listview item */
            UI.npb_progressbar.setTag(item.getId());

            UI.iv_download_icon.setVisibility(View.VISIBLE);
            UI.iv_download_icon.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    UI.ll_handle_progress_bar.setVisibility(View.VISIBLE);
                    item.setDownload_status(1);
                    G.DOWNLOADLIST.create(new DownloadTaskList(item.getMsg_id(), 0, item.getStream_link(), 0, 0, 0, position));
                    G.context.startService(new Intent(G.currentActivity, ServiceMultiTaskDownloader.class).putExtra("download_item_id", item.getMsg_id()));
                    UI.npb_progressbar.setVisibility(View.VISIBLE);
                    UI.tv_downloding_file_info.setVisibility(View.VISIBLE);
                }
            });
        } if (UI.npb_progressbar.getTag().equals(item.getId())) {
            UI.imgv_image_item.setImageBitmap(BitmapFactory.decodeFile(G.dir_app + "/" + item.getPreview_image_url()));

            /* HIDE icon to disable click by user to download file */
            UI.iv_download_icon.setVisibility(View.INVISIBLE);
        }
    }

}

现在通过这个适配器,我可以通过简单的 BroadCastReceiver 更新行:

private void updateView(int position, int file_size, int downloaded_size, int percent, String stream_filename) {
    View v = UI.lv_message_content.getChildAt(position - UI.lv_message_content.getFirstVisiblePosition());
    UI.lv_message_content.getAdapter().getView(position, v, UI.lv_message_content);
    UI.lv_message_content.invalidateViews();
    if (v == null) return;

    ImageView         imgv_image_item         = (ImageView) v.findViewById(R.id.imgv_image_item);
    NumberProgressBar numberProgressBar       = (NumberProgressBar) v.findViewById(R.id.npb_progressbar);
    TextView          tv_downloding_file_info = (TextView) v.findViewById(R.id.tv_downloding_file_info);

    if (numberProgressBar.getTag() != null && numberProgressBar.getTag().equals(messagesLists.get(position).getId())) {
        numberProgressBar.setProgress(percent);

        tv_downloding_file_info.setVisibility(View.VISIBLE);
        tv_downloding_file_info.setText(UC.convertByteToMB(downloaded_size) + "/" + UC.convertByteToMB(file_size));

        if (percent == 100) {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = 30;
            Bitmap bmp = BitmapFactory.decodeFile(G.dir_image + "/" + stream_filename);
            imgv_image_item.setImageBitmap(bmp);

            tv_downloding_file_info.setVisibility(View.GONE);
            numberProgressBar.setVisibility(View.GONE);
        }
    }
}

不幸的是,当单击UI.iv_download_icon 下载文件时,我的列表视图项目在位置 0 和位置 6 上重复。

【问题讨论】:

  • 你在问什么?
  • @Zharf 不幸的是,当通过单击 UI.iv_download_icon 下载文件时,我在 listview 项目上的进度条在位置 0 和位置 6 上重复。
  • 所以当您开始下载并向下滚动列表时,您会在不应该有的项目上找到另一个进度条?
  • @Zharf 是的先生,我无法处理不显示并正确找到必须显示进度条的项目

标签: android listview android-listview


【解决方案1】:

如果我理解正确并仔细阅读代码,我认为这是对AdaptersListView(或RecyclerView)如何工作的误解。

ListView 和新的RecyclerView 回收它们显示的视图,以最大限度地减少内存占用和视图创建开销。为了使列表中看起来有数百个视图,他们使用Adapters 创建了一些视图(足以填充列表占用的区域),然后更新视图的内容,因为是时候将项目显示给用户。

如果您绕过Adapter 的逻辑并修改属于Adapter 的视图的内容,那么由于发生了这种循环,您将导致列表上或下看似随机的项目发生相同的更改。

解决此问题的方法是在Adapter(或RecyclerView.AdapteronBindViewHolder)的getView 方法中进行视图更新。 Adapter 应该有一个内部数据列表,您可以使用它来决定视图的外观。然后,您可以修改数据并调用notifyDataSetChanged(使用RecyclerView.Adapter 时还有其他选项),这会导致为每个需要更新的项目调用getView(在屏幕上可见)。

故事的寓意:永远不要直接对列表中的视图进行视图更新,而是修改Adapter 中的数据并通知它数据已更改,以便它知道应该进行视图更新以显示-最新数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 2013-11-21
    • 1970-01-01
    • 1970-01-01
    • 2015-11-01
    • 1970-01-01
    • 2016-02-20
    相关资源
    最近更新 更多