Android在listview项目上整个下载进度条

时间:2015-07-07 10:54:48

标签: android listview android-listview

我将简单列表视图编写为下载列表,用户可以单击该列表进行下载。我没有任何问题从互联网下载服务,但在列表视图项目上的可见进度条后。这显示整个列表视图,我无法处理,不显示整个列表视图,只显示点击列表浏览项目的进度条下载。

我的适配器:

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重复。

1 个答案:

答案 0 :(得分:0)

如果我理解这一点并仔细阅读代码,我认为这是一个误解AdaptersListView(或RecyclerView)工作原理的案例。

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

如果绕过Adapter的逻辑并修改属于Adapter的视图的内容,则会对列表中上下的看似随机的项目进行相同的更改发生回收。

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

故事的道德:永远不要直接查看列表中的视图更新,而是修改Adapter中的数据,并通知它数据已更改,因此它知道应该查看更新以显示最新数据。