android - 水平进度条不更新列表项内

时间:2012-08-27 13:32:06

标签: android android-asynctask progress-bar

我是android编程的新手,现在我遇到了有线的东西,我创建了一个listActivity,列表项的布局如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@color/white"
    android:gravity="center_vertical"
    android:orientation="vertical"
    android:paddingBottom="10dp"
    android:paddingTop="15dp" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@color/transparent" >

        <ImageView
            android:id="@+id/offlineItemIcon"
            android:layout_width="44dp"
            android:layout_height="44dp"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="5dp"
            android:layout_marginTop="5dp"
            android:scaleType="fitXY"
            android:src="@drawable/user_avatar" />

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/offlineItemTitle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingTop="5dp"
                android:text="卷001 2012-08-23 3.0M"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="@color/lightdark"
                android:textSize="18sp" />

            <ProgressBar
                android:id="@+id/offlineLoadingbar"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="fill_parent"
                android:layout_height="5dp"
                android:layout_marginRight="20dp"
                android:layout_marginTop="15dp"
                android:max="100"
                android:progress="10" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center" >

            <Button
                android:id="@+id/buttonOfflineItemDownload"
                android:layout_width="60dp"
                android:layout_height="44dp"
                android:background="@drawable/xml_button_loadmore"
                android:text="download"
                android:textColor="@color/lightwhite"
                android:textSize="18sp" />
        </LinearLayout>
    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:background="@color/commentDate" >
    </LinearLayout>

</LinearLayout>

我创建了一个类来包装这个布局的内容,这个 -

public class OfflineItemView extends LinearLayout {

    Context _context = null;

    public Button buttonDownload = null;
    public ProgressBar loadingProgress = null;
    public TextView title = null;
    public ImageView icon = null;

    public String url = null;
    public String filename = null;

    public OfflineItemView(Context context) {
        super(context);
        _context = context;
        init();
    }

    public OfflineItemView(Context context, AttributeSet attrs) {
        super(context, attrs);
        _context = context;
        init();
    }

    protected void init() {
        LayoutInflater inflater = (LayoutInflater) _context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.module_offline_item, this);

        buttonDownload = (Button) findViewById(R.id.buttonOfflineItemDownload);
        buttonDownload.setTag("download");

        loadingProgress = (ProgressBar) findViewById(R.id.offlineLoadingbar);
        loadingProgress.setMax(100);
        loadingProgress.setProgress(0);

        title = (TextView) findViewById(R.id.offlineItemTitle);
        icon = (ImageView) findViewById(R.id.offlineItemIcon);
    }

    public void setTitle(String message) {
        if (message != null) {
            title.setText(message);
        } else {
            title.setText("");
        }
    }

    public void setImageBitmap(Bitmap bitmap) {

        if (bitmap != null) {
            icon.setImageBitmap(bitmap);
        }
    }

    public void setListener(View.OnClickListener listener) {
        this.buttonDownload.setOnClickListener(listener);
    }

    public void setProgress (int i)
    {
        android.util.Log.v ("item", i + "");
        loadingProgress.setProgress(i);
        android.util.Log.v ("item", "current : " + loadingProgress.getProgress());
    }

}

列表工作得很好,它显示所有项目没有问题,列表项的屏幕截图是 -

enter image description here

当用户单击该按钮时,它将调用AsyncTask类来下载文件以及显示项目的进度,下载类 -

public void downloadOffline(String url, String path,
        OfflineItemView progress) {

    DownloadOfflineAsync downloader = new DownloadOfflineAsync(progress);
    downloader.execute(url, path);
}

class DownloadOfflineAsync extends AsyncTask<String, String, String> {

    private final WeakReference<OfflineItemView> progressbarReference;

    public DownloadOfflineAsync(OfflineItemView progress) {
        progressbarReference = new WeakReference<OfflineItemView>(progress);
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... aurl) {
        int count;

        try {

            URL url = new URL(aurl[0]);
            URLConnection conexion = url.openConnection();
            conexion.connect();

            int lenghtOfFile = conexion.getContentLength();
            android.util.Log.v("downloadFile", "Lenght of file: "
                    + lenghtOfFile + ":" + aurl[1]);

            InputStream input = new BufferedInputStream(url.openStream());
            OutputStream output = new FileOutputStream(aurl[1]);

            try {
                byte data[] = new byte[1024];

                long total = 0;

                while ((count = input.read(data)) != -1) {
                    total += count;
                    publishProgress(""
                            + (int) ((total * 100) / lenghtOfFile));
                    output.write(data, 0, count);
                }


            } finally {

                if (output != null) {
                    output.flush();
                    output.close();
                }

                if (input != null) {

                    input.close();
                }
            }
        } catch (Exception e) {

            e.printStackTrace();

        }
        return null;

    }

    protected void onProgressUpdate(String... progress) {
        if (progressbarReference != null) {
            OfflineItemView p = progressbarReference.get();

            //android.util.Log.v ("offline.download", progress[0]);
            p.setProgress(Integer.parseInt(progress[0]));
        }
    }

    @Override
    protected void onPostExecute(String unused) {

        OfflineItemView p = null;

        if (progressbarReference != null) {
            p = progressbarReference.get();
            p.buttonDownload.setTag("browser");
            p.buttonDownload.setText("browse");
            p.requestLayout();
        }

    }
}

它工作正常,文件被下载,进度被通知onProgressUpdate,项目类的加载进度条工作正常,进度设置正确(在logcat上打印,一切正确),但是问题是进度条永远不会更新其指标,所以即使进度从0更新到100越来越多,进度条不会改变任何东西来显示其UI的进度,所以任何能给我一些建议的人都会受到赞赏。

PS:

我将下载功能移动到getView(),似乎它工作得很好,进度条正在更新,但是在按钮事件处理程序不起作用,所以看来它是列表视图问题,如何解决这个问题,但是?

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

        rowView = new OfflineItemView(_context);
        JSONObject item = getItem(position);

        try {
            if (item != null) {
                String t = item.getString(Offline.TAG_NAME) + " "
                        + item.getString(Offline.TAG_DATE) + " "
                        + item.getString(Offline.TAG_SIZE);

                rowView.setTitle(t);

                if (listener == null) {
                    listener = new ItemButtonOnClickListener();
                }

                if (item.optBoolean("dir_exists")) {
                    rowView.buttonDownload.setText("browse");
                    rowView.buttonDownload.setTag("browser");
                }

                rowView.setListener(listener);
                rowView.url = item.getString(Offline.TAG_URL);
                rowView.filename = item.getString(Offline.TAG_FILENAME);

                String imageUrl = item.optString(Offline.TAG_ICON);

                if (imageUrl == null || imageUrl.trim().equals("")) {

                } else {

                    String name = item.optString(Offline.TAG_UNZIP_NAME) + "o";
                    if (name != null) {
                        if (DiskCache.getInstance().fileExists("user_" + name,
                                "user")) {
                            android.util.Log.v("offline", name + ":exists");
                            Bitmap bitmap = DiskCache.getInstance().get(
                                    "user_" + name, "user");
                            if (bitmap != null) {
                                rowView.setImageBitmap(bitmap);
                            }
                        } else {

                            // FileDownloader.getInstance().download(imageUrl,
                            // image, name);
                        }

                    }
                }


            }
        }

        catch (Exception e) {
            e.printStackTrace();
        }

        return rowView;

    }

1 个答案:

答案 0 :(得分:0)

你正以一种奇怪的方式接近这一点。你说你是Android的新手,我无法从你的评论帖中看出你当前的破碎状态是什么。但是,我可以告诉您,您没有关注ListView最佳做法,并且当您向下滚动列表时可能会遇到一些奇怪的问题。

您应该使用您提供的convertView参数。 convertView为空,或者您之前从View返回的getView。由于您只返回OfflineItemView,如果convertView != null它将成为OfflineItemView的实例,您可以重复使用它以避免在绘制时创建一个全新的实例的开销每次显示新项目时。

基本上:

View rowView;
if(convertView == null){
     rowView = convertView;
} else {
     rowView = new OfflineItemView(item);
}

请小心使用这样的逻辑,因为下次重新使用视图时,标签仍会出现在最后一个占用它的项目中:

            if (item.optBoolean("dir_exists")) {
                rowView.buttonDownload.setText("browse");
                rowView.buttonDownload.setTag("browser");
            }

I.E。,您可能需要else条款来说明rowView.buttonDownload.setText("");,并在dir_exists为假的情况下使标记无效。

此外,(假设您的意思是使用ImageDownloader中已注释的getView代码),如果您的图片缓存中不存在该图片,则可能会产生多次下载如果在实际下载图像之前多次调用getView,则为同一图像。

如果您可以编辑您的问题以准确说明现在的问题,我可以优化此答案以帮助您进一步。