2

我是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());
    }

}

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

在此处输入图像描述

当用户单击按钮时,它将调用 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;

    }
4

1 回答 1

0

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

您应该使用convertView给定的参数。 convertView是 null,或者是View您之前从 . 返回的getView。由于您只返回OfflineItemViews,如果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");
            }

IE,您可能需要一个else子句来说明rowView.buttonDownload.setText("");并在错误的情况下使标签无效dir_exists

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

如果您可以编辑您的问题以准确澄清现在的问题,我可以完善此答案以进一步帮助您。

于 2012-08-27T14:37:47.080 回答