如何将imageview的,在列表视图中的一些文字相结合 [英] How to combine an imageview with some text in listview

查看:154
本文介绍了如何将imageview的,在列表视图中的一些文字相结合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到目前为止,我一直在使用一个简单的 ArrayAdapter 显示在的ListView 一些项目。现在,我也想一起在的ListView 文本显示图像。我有一个的AsyncTask 名为 DownloadImageTask 下载图像。该下载是可以正常使用的,但我不知道如何在 ListView控件显示一个图像,以及如何使用 DownloadImageTask 下载图像在的ListView

So far I've been using a simple ArrayAdapter to display some items in a ListView. Now I also want to display images alongside the text in the ListView. I have an AsyncTask called DownloadImageTask to download images. The downloading is working perfectly, but I don't know how to display an image in the ListView and how to use the DownloadImageTask to download the images in the ListView.

这是 DownloadImageTask 我用图像下载到的ImageView

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    ImageView bmImage;

    public DownloadImageTask(ImageView bmImage) {
        this.bmImage = bmImage;
    }

    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap mIcon11 = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mIcon11 = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return mIcon11;
    }

    protected void onPostExecute(Bitmap result) {
        bmImage.setImageBitmap(result);
    }
}

我还定义了一个的ImageView 旁边的的ListView 来把图像下载到布局。

I have also defined an ImageView alongside the ListView to download the images into the layout.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="#000000">

    <ImageView 
        android:id="@+id/image1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <ListView
        android:id="@android:id/list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</RelativeLayout>

我称之为 DownloadImageTask 是这样的:

new DownloadImageTask((ImageView) findViewById(R.id.image1)).execute(url);

我如何使用 DownloadImageTask 下载图片,并在的ListView 旁边的文字显示它们?

How can I use the DownloadImageTask to download images and display them in the ListView alongside the text?

推荐答案

要做到你想做的事,你必须创建一个自定义什么适配器。要下载图片,我建议你使用像 毕加索 库。下载图像,它真的不能得到任何更容易地使用它时,毕加索照顾pretty太多的一切,你只需要调用此下载一个图像到的ImageView

To achieve what you want to do you have to create a custom Adapter. To download the images I suggest you use a library like Picasso. Picasso takes care of pretty much everything when downloading the images and it really can't get any easier to use it, you just need to call this to download an image into an ImageView:

Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);

有已经缓存的图像,也可以在许多方面变换的图像。毕加索是一个非常强大且易于使用的库。

It already caches images and can also transform images in many ways. Picasso is a very powerful yet easy to use library.

首先,我们需要在的ListView ,你的情况,因为你要显示的图像,它需要包含<$文本每行创建布局C $ C>的TextView 和的ImageView

First we need to create a layout for each row in the ListView, in your case since you want to display an image and a text it needs to contain a TextView and an ImageView:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

    <ImageView
            android:id="@+id/imageView"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_margin="10dp"/>

    <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@id/imageView"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:textAlignment="gravity"
            android:gravity="center"/>

</RelativeLayout>

现在,我们需要创建一个容器类 - 所谓视图模型 - 持有其所属的的ListView 的每一行中的数据。你的情况,这个视图模型中包含要显示的文字和网址的图片:

Now we need to create a container class - called view model - to hold the data which belongs in each row of the ListView. In your case this view model contains the text you want to display and the url to the image:

private class ExampleViewModel {
    private String text;
    private String imageUrl;

    private ExampleViewModel(String text, String imageUrl) {
        this.text = text;
        this.imageUrl = imageUrl;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public String getImageUrl() {
        return imageUrl;
    }

    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
    }
}

列表视图使用视图回收。我们可以通过一个名为观点持有者的模式加快的ListView 的性能。基本上,我们保存到查看每一行内引用,并将它连接到该行本身。这样,我们需要调用昂贵的 findViewById()只有一次。这种观点持有者类 - 我喜欢叫他们行 - 还含有一种叫方法绑定()从视图模型的数据绑定到正文每个一行。我们需要在的TextView 的ImageView ,但我们还需要一个上下文毕加索。我也喜欢定义与该行的行中的公共常量相关联的布局。

ListViews use view recycling. We can speed up the performance of the ListView by using a pattern called "view holder". Basically we save a reference to the Views inside each row and attach it to the row itself. That way we need to call the expensive findViewById() only once. This view holder class - I like to call them rows - also contain a method called bind() to bind the data from the view model to the Views in each row. We need a reference to the TextView and ImageView but we also need a Context for Picasso. I also like to define the layout associated with this row as a public constant in the row.

private class ExampleRow {

    // This is a reference to the layout we defined above
    public static final int LAYOUT = R.layout.list_item;

    private final Context context;
    private final TextView textView;
    private final ImageView imageView;

    private ExampleRow(Context context, View convertView) {
        this.context = context;
        this.imageView = (ImageView) convertView.findViewById(R.id.imageView);
        this.textView = (TextView) convertview.findViewById(R.id.textView);
    }

    public void bind(ExampleViewModel exampleViewModel) {
        this.textView.setText(exampleViewModel.getText());
        Picasso.with(this.context).load(exampleViewModel.getImageUrl()).into(this.imageView);
    }
}

最后,我们需要一个自定义的适配器来完成这项工作,这真的没什么特别的。唯一有趣的部分是在 getView()。我会评论重要组成部分,如果必要的:

Finally we need a custom Adapter to make this work, it's really nothing special. The only interesting part is in getView(). I will comment important parts if necessary:

public class ExampleAdapter extends BaseAdapter {

    private final List<ExampleViewModel> viewModels;

    private final Context context;
    private final LayoutInflater inflater;

    public ExampleAdapter(Context context) {
        this.context = context;
        this.inflater = LayoutInflater.from(context);
        this.viewModels = new ArrayList<ExampleViewModel>();
    }

    public ExampleAdapter(Context context, List<ExampleViewModel> viewModels) {
        this.context = context;
        this.inflater = LayoutInflater.from(context); 
        this.viewModels = viewModels;
    }

    public List<ExampleViewModel> viewmodels() {
        return this.viewModels;
    }

    @Override
    public int getCount() {
        return this.viewModels.size();
    }

    @Override
    public ExampleViewModel getItem(int position) {
        return this.viewModels.get(position);
    }

    @Override
    public long getItemId(int position) {
        // We only need to implement this if we have multiple rows with a different layout. All your rows use the same layout so we can just return 0.
        return 0;
    }

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

        // We get the view model for this position
        final ExampleViewModel viewModel = getItem(position);

        ExampleRow row;
        // If the convertView is null we need to create it
        if(convertView == null) {
            convertView = this.inflater.inflate(ExampleRow.LAYOUT, parent, false);

            // In that case we also need to create a new row and attach it to the newly created View
            row = new ExampleRow(this.context, convertView);
            convertView.setTag(row);
        }

        // After that we get the row associated with this View and bind the view model to it
        row = (ExampleRow) convertView.getTag();
        row.bind(viewModel);

        return convertView;
    }
}

这就是你需要的一切。这是pretty太大的最佳实践的实施适配器的。它使用额外的性能视图模式持有人,并与的ListView的看法回收完美的作品。它快速,简洁大方,并没有留下余地通过,否则将延缓的ListView 下跌开发商所犯的错误。你有你想要的数据显示(这是所有在 ExampleViewModel )之间的完美分离它是如何显示的(这是在 ExampleRow )。适配器本身不知道任何! - 因为它应该是

And that's everything you need. It's pretty much a best practice implementation of an Adapter. It uses the view holder pattern for extra performance and works perfectly with the view recycling of the ListView. It's fast, concise and easy and leaves little room for errors made by the developer which would otherwise slow the ListView down. You have perfect separation between what data you want to display (that's all in the ExampleViewModel) and how it is displayed (that's in the ExampleRow). The adapter itself doesn't know about either - as it should be!

要使用code以上,我们首先需要创建一个保存数据的视图模型,我们想显示:

To use the code above we first need to create the view models which hold the data we want to display:

ExampleViewModel firstRow = new ExampleViewModel("First Row". "http://http://upload.wikimedia.org/wikipedia/commons/6/6f/Freiburger_Alpen.JPG");    
ExampleViewModel secondRow = new ExampleViewModel("Second Row". "http://blog.caranddriver.com/wp-content/uploads/2013/05/lamborghini_egoista_three_quarter_front_view.jpg");    
ExampleViewModel thirdRow = new ExampleViewModel("Third Row". "http://4.bp.blogspot.com/-vXnf7GjcXmg/UfJZE9rWc2I/AAAAAAAAGRc/x2CIlHM9IAA/s1600/aphoto49721.jpg");

我们需要所有这些行添加到列表

We need to add all those rows into a List:

List<ExampleViewModel> viewModels = new ArrayList<ExampleViewModel>();
viewModels.add(firstRow);
viewModels.add(secondRow);
viewModels.add(thirdRow);

在这之后,我们需要创建一个实例 ExampleAdapter ,并通过在视图模型的列表构造函数。最后,我们只需要设置适配器的ListView

And after that we need to create an instance of the ExampleAdapter and pass the List of view models in the constructor. Finally we just need to set the Adapter to the ListView:

ExampleAdapter adapter = new ExampleAdapter(context, viewModels);
listView.setAdapter(adapter);

您可以修改 ListView控件中显示的项目后来的的ViewModels()的方法 ExampleAdapter !你只需要记住始终调用 notifyDataSetChanged()适配器修改视图模型后:

You can modify the items displayed in the ListView later on with the viewmodels() method of the ExampleAdapter! You just need to remember to always call notifyDataSetChanged() on the Adapter after modifying the view models:

adapter.viewmodels().remove(0); // Remove first view model
adapter.viewmodels().add(someNewViewModel); // Add some new view model

// Always remember to call this method after modifying the viewmodels.
// This will apply the changes to the ListView. 
// If you forget to call this you will get an exception
adapter.notifyDataSetChanged(); 

我希望我可以帮助你,如果你有任何问题随时问!

I hope I could help you and if you have any further questions feel free to ask!

这篇关于如何将imageview的,在列表视图中的一些文字相结合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆