我有Android设备上运行下面的代码。它的伟大工程和奇妙显示我的列表项。这也是它,只有当它是由一个ArrayAdapter需要下载数据的事实聪明。然而,尽管缩略图的下载发生,整个列表摊位,你不能滚动,直到它完成下载。有没有穿这所以它仍然会滚动愉快,也许显示的下载图像占位符,完成下载,然后显示出什么办法?

我想我只是需要把我的downloadImage类到它自己的线程,以便其从UI分别进行。但如何添加到我的代码,这是谜!

任何帮助,这将是非常理解的。

private class CatalogAdapter extends ArrayAdapter<SingleQueueResult> {

    private ArrayList<SingleQueueResult> items;

    //Must research what this actually does!
    public CatalogAdapter(Context context, int textViewResourceId, ArrayList<SingleQueueResult> items) {
        super(context, textViewResourceId, items);
        this.items = items;

    }

    /** This overrides the getview of the ArrayAdapter. It should send back our new custom rows for the list */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View v = convertView;
        if (v == null) {
            LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.mylists_rows, null);

        }
        final SingleQueueResult result = items.get(position);
        // Sets the text inside the rows as they are scrolled by!
        if (result != null) {

            TextView title = (TextView)v.findViewById(R.id.mylist_title);
            TextView format = (TextView)v.findViewById(R.id.mylist_format);
            title.setText(result.getTitle());
            format.setText(result.getThumbnail());

            // Download Images
            ImageView myImageView = (ImageView)v.findViewById(R.id.mylist_thumbnail);
            downloadImage(result.getThumbnail(), myImageView);

        }

        return v;
    }
}

// This should run in a seperate thread
public void downloadImage(String imageUrl, ImageView myImageView) {

    try {
        url = new URL(imageUrl);
        URLConnection conn = url.openConnection();
        conn.connect();
        InputStream is = conn.getInputStream();
        BufferedInputStream bis = new BufferedInputStream(is);
        Bitmap bm = BitmapFactory.decodeStream(bis);
        bis.close();
        is.close();
        myImageView.setImageBitmap(bm);
    } catch (IOException e) {
        /* Reset to Default image on any error. */
        //this.myImageView.setImageDrawable(getResources().getDrawable(R.drawable.default));
    }
}
有帮助吗?

解决方案

下面是什么,我用我的应用程序的简化版本:

// this lives in Application subclass and is reused
public static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();

// the method itself

    public void attachImage(final String fileUrl, final ImageView view) {
        EXECUTOR.execute(new Runnable() {

            @Override
            public void run() {
                final Drawable image = methodThatGetsTheImage(fileUrl);
                if (image != null) {
                    view.post(new Runnable() {

                        @Override
                        public void run() {
                            view.setImageDrawable(drawable);
                        }
                    });
                }
            }
        });
    }

其他提示

您还可以检查出 CWAC缩略图以一个下拉溶液(尽管它有一点超过开销简单的解决方案上图)。我已经取得了巨大成功几乎任何地方我有一个Web图像下载使用它;基本上你设置一些全局缓存选项,您的应用程序,那么就换你ListAdapter在ThumbnailAdapter与Android的列表:在列表中的imageviews的标识,并在你的适配器的getView方法imageviews调用setTag(IMAGEURL),和它处理的其余部分。

是。您应该避免在UI线程上运行尽可能多的。当您在getView()是你是在UI线程上。为了打破这样做:

new Thread(new Runnable(){

  public void run() {
    // your code here

  }}).start();

然后,当你需要修改视图以某种方式返回到UI线程是这样的:

runOnUiThread(new Runnable(){

  public void run() {
    // your view-modifying code here

  }});

..或使用View.post()机制。

在你的例子会发生什么是该项目将在屏幕上显示的图像可用于显示之前。我建议使用“加载”微调或其他一些占位符,以指示发生了什么用户。

您可以在实践中嵌套这样几次,虽然你会到达一个点,一个简化的设计是为了。匿名类可能是低效的存储器向和发射了大量的线程没有取消机构可以具有其自身的缺点。

您可能会遇到一些困难作为修改视图getView()之后的副作用已退出。有些观点可能需要无效()调用有自己的更改生效。另外注意,如果你正在回收的观点在getView(),你应该确保在时间的观点仍然被用于您所申请的内容是执行视图 - 修改代码。 setTag()/ getTag()是这里有用的存储数据的一些ID,你可以在以后检查,以确保您的看法并没有被回收。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top