Nice programing

Android의 ListView에 이미지 목록을 표시하는 방법은 무엇입니까?

nicepro 2020. 11. 15. 11:45
반응형

Android의 ListView에 이미지 목록을 표시하는 방법은 무엇입니까?


ListView를 사용하여 이미지 목록을 어떻게 표시합니까? 런타임에 이미지를 다운로드하고 있습니다. 총 이미지 수는 고정되어 있지 않습니다.


나는 다음과 같은 것으로 시작할 것입니다 (그리고 내 코드에 문제가 있다면, 물론 어떤 코멘트라도 감사하겠습니다) :

public class ItemsList extends ListActivity {

private ItemsAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.items_list);

    this.adapter = new ItemsAdapter(this, R.layout.items_list_item, ItemManager.getLoadedItems());
    setListAdapter(this.adapter);
}

private class ItemsAdapter extends ArrayAdapter<Item> {

    private Item[] items;

    public ItemsAdapter(Context context, int textViewResourceId, Item[] items) {
        super(context, textViewResourceId, items);
        this.items = items;
    }

    @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.items_list_item, null);
        }

        Item it = items[position];
        if (it != null) {
            ImageView iv = (ImageView) v.findViewById(R.id.list_item_image);
            if (iv != null) {
                iv.setImageDrawable(it.getImage());
            }
        }

        return v;
    }
}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    this.adapter.getItem(position).click(this.getApplicationContext());
}
}

예를 들어, 고유 한 유형의 항목 (사진에 대한 정보 보유) 및 재정의 된 getView()메서드로 ArrayAdapter를 확장하여 목록 내의 항목에 대한보기를 준비합니다. add()목록 끝에 항목을 추가하는 방법도 ArrayAdapter에 있습니다.

R.layout.items_list 간단한 레이아웃 ListView

R.layout.items_list_item 목록의 한 항목을 나타내는 레이아웃입니다.


 package studRecords.one;

 import java.util.List;
 import java.util.Vector;

 import android.app.Activity;
 import android.app.ListActivity;
 import android.content.Context;
 import android.content.Intent;
 import android.net.ParseException;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
 import android.widget.ImageView;
 import android.widget.ListView;
 import android.widget.TextView;



public class studRecords extends ListActivity 
{
static String listName = "";
static String listUsn = "";
static Integer images;
private LayoutInflater layoutx;
private Vector<RowData> listValue;
RowData rd;

static final String[] names = new String[]
{
      "Name (Stud1)", "Name (Stud2)",   
      "Name (Stud3)","Name (Stud4)" 
};

static final String[] usn = new String[]
{
      "1PI08CS016","1PI08CS007","1PI08CS017","1PI08CS047"
};

private Integer[] imgid = 
{
  R.drawable.stud1,R.drawable.stud2,R.drawable.stud3,
  R.drawable.stud4
};

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mainlist);

    layoutx = (LayoutInflater) getSystemService(
    Activity.LAYOUT_INFLATER_SERVICE);
    listValue = new Vector<RowData>();
    for(int i=0;i<names.length;i++)
    {
        try
        {
            rd = new RowData(names[i],usn[i],i);
        } 
        catch (ParseException e) 
        {
            e.printStackTrace();
        }
        listValue.add(rd);
    }


   CustomAdapter adapter = new CustomAdapter(this, R.layout.list,
                                     R.id.detail, listValue);
   setListAdapter(adapter);
   getListView().setTextFilterEnabled(true);
}
   public void onListItemClick(ListView parent, View v, int position,long id)
   {            


       listName = names[position];
       listUsn = usn[position];
       images = imgid[position];




       Intent myIntent = new Intent();
       Intent setClassName = myIntent.setClassName("studRecords.one","studRecords.one.nextList");
       startActivity(myIntent);

   }
   private class RowData
   {

       protected String mNames;
       protected String mUsn;
       protected int mId;
       RowData(String title,String detail,int id){
       mId=id;
       mNames = title;
       mUsn = detail;
    }
       @Override
    public String toString()
       {
               return mNames+" "+mUsn+" "+mId;
       }
  }

              private class CustomAdapter extends ArrayAdapter<RowData> 
          {
      public CustomAdapter(Context context, int resource,
      int textViewResourceId, List<RowData> objects)
      {               
            super(context, resource, textViewResourceId, objects);
      }
      @Override
      public View getView(int position, View convertView, ViewGroup parent)
      {   
           ViewHolder holder = null;
           TextView title = null;
           TextView detail = null;
           ImageView i11=null;
           RowData rowData= getItem(position);
           if(null == convertView)
           {
                convertView = layoutx.inflate(R.layout.list, null);
                holder = new ViewHolder(convertView);
                convertView.setTag(holder);
           }
         holder = (ViewHolder) convertView.getTag();
         i11=holder.getImage();
         i11.setImageResource(imgid[rowData.mId]);
         title = holder.gettitle();
         title.setText(rowData.mNames);
         detail = holder.getdetail();
         detail.setText(rowData.mUsn);                                                     

         return convertView;
      }

        private class ViewHolder 
        {
            private View mRow;
            private TextView title = null;
            private TextView detail = null;
            private ImageView i11=null; 
            public ViewHolder(View row)
            {
                    mRow = row;
            }
            public TextView gettitle()
            {
                 if(null == title)
                 {
                     title = (TextView) mRow.findViewById(R.id.title);
                 }
                 return title;
            }     
            public TextView getdetail()
            {
                if(null == detail)
                {
                    detail = (TextView) mRow.findViewById(R.id.detail);
                }
                return detail;
            }
            public ImageView getImage()
            {
                    if(null == i11)
                    {
                        i11 = (ImageView) mRow.findViewById(R.id.img);
                    }
                    return i11;
            }   
        }
   } 
 }

//mainlist.xml

     <?xml version="1.0" encoding="utf-8"?>
             <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:orientation="horizontal"
                 android:layout_width="fill_parent"
                 android:layout_height="fill_parent"
             >
             <ListView
                 android:id="@android:id/list"
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
              />
             </LinearLayout>

다음은 다른 이미지가있는 간단한 ListView입니다. 먼저 다양한 종류의 이미지를 복사하여 프로젝트의 res / drawable-hdpi에 붙여 넣어야합니다. 이미지는 (.png) 파일 형식이어야합니다. 그런 다음이 코드를 복사하십시오.

main.xml에서

<?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="fill_parent"
   android:orientation="vertical" >

  <TextView
      android:id="@+id/textview"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content" />

 <ListView
     android:id="@+id/listview"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content" />

listview_layout.xml을 만들고이 코드를 붙여 넣습니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

   <ImageView
      android:id="@+id/flag"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:contentDescription="@string/hello"
      android:paddingTop="10dp"
      android:paddingRight="10dp"
      android:paddingBottom="10dp" />

   <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="vertical" >

     <TextView
        android:id="@+id/txt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="15dp"
        android:text="TextView1" />

    <TextView
        android:id="@+id/cur"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="10dp"
        android:text="TextView2" />
   </LinearLayout>

당신의 활동에서

package com.test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class SimpleListImageActivity extends Activity {

    // Array of strings storing country names
    String[] countries = new String[] {
        "India",
        "Pakistan",
        "Sri Lanka",
        "China",
        "Bangladesh",
        "Nepal",
        "Afghanistan",
        "North Korea",
        "South Korea",
        "Japan"
    };

    // Array of integers points to images stored in /res/drawable-hdpi/

   //here you have to give image name which you already pasted it in /res/drawable-hdpi/

     int[] flags = new int[]{
        R.drawable.image1,
        R.drawable.image2,   
        R.drawable.image3,
        R.drawable.image4,
        R.drawable.image5,
        R.drawable.image6,
        R.drawable.image7,
        R.drawable.image8,
        R.drawable.image9,
        R.drawable.image10,
    };

    // Array of strings to store currencies
    String[] currency = new String[]{
        "Indian Rupee",
        "Pakistani Rupee",
        "Sri Lankan Rupee",
        "Renminbi",
        "Bangladeshi Taka",
        "Nepalese Rupee",
        "Afghani",
        "North Korean Won",
        "South Korean Won",
        "Japanese Yen"
    };

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Each row in the list stores country name, currency and flag
        List<HashMap<String,String>> aList = new ArrayList<HashMap<String,String>>();

        for(int i=0;i<10;i++){
            HashMap<String, String> hm = new HashMap<String,String>();
            hm.put("txt", "Country : " + countries[i]);
            hm.put("cur","Currency : " + currency[i]);
            hm.put("flag", Integer.toString(flags[i]) );
            aList.add(hm);
        }

        // Keys used in Hashmap
        String[] from = { "flag","txt","cur" };

        // Ids of views in listview_layout
        int[] to = { R.id.flag,R.id.txt,R.id.cur};

        // Instantiating an adapter to store each items
        // R.layout.listview_layout defines the layout of each item
        SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), aList, R.layout.listview_layout, from, to);

        // Getting a reference to listview of main.xml layout file
        ListView listView = ( ListView ) findViewById(R.id.listview);

        // Setting the adapter to the listView
        listView.setAdapter(adapter);
    }
}

이것은 전체 코드입니다. 필요에 따라 변경할 수 있습니다. 의견을 환영합니다.


6 년이 지났지 만 여전히 일부 검색에서 1 위를 차지했습니다. 그 이후로 상황이 많이 바뀌 었습니다. 이제 사실상의 표준은 Volley 와 NetworkImageView 를 사용 하여 무거운 작업을 처리하는 것입니다.

이미 Apaters, Loaders 및 ListFragments를 올바르게 설정했다고 가정하고이 공식 Google 자습서 에서는 NetworkImageView를 사용하여 이미지를로드하는 방법을 설명합니다. 이미지는 백그라운드 스레드에 자동으로로드되고 뷰는 UI 스레드에서 업데이트됩니다. 캐싱도 지원합니다.


나는 잘 제공되는“BatchImageDownloader”라고 부르는 솔루션을 생각 해냈다. 다음은 사용 방법에 대한 간략한 요약입니다.

  • 드로어 블 개체의 캐시 역할을하는 전역 HashMap (이상적으로는 Application 개체에 있음)을 유지합니다.

  • 목록 어댑터의 getView () 메서드에서 캐시의 드로어 블을 사용하여 목록 항목에 ImageView를 채우십시오.

  • ListView 어댑터를 전달하여 BatchImageDownloader 인스턴스를 만듭니다.

  • 가져 오거나 표시해야하는 각 이미지에 대해 addUrl ()을 호출합니다.

  • 완료되면 execute ()를 호출하십시오. 이렇게하면 모든 이미지를 가져 오는 AsyncTask가 발생하고 각 이미지를 가져 와서 캐시에 추가하면 ListView를 새로 고칩니다 (notifyDataSetChanged ()를 호출하여).

이 접근 방식에는 다음과 같은 장점이 있습니다.

  • 각 이미지 / 뷰에 대해 별도의 스레드가 아닌 단일 작업자 스레드를 사용하여 모든 이미지를 가져옵니다.
  • 이미지를 가져 오면 해당 이미지를 사용하는 모든 목록 항목이 즉시 업데이트됩니다.
  • 코드는 목록 항목의 이미지보기에 직접 액세스하지 않습니다. 대신 목록 어댑터에서 notifyDataSetChanged ()를 호출하여 목록보기 새로 고침을 트리거하고 getView () 구현은 단순히 캐시에서 드로어 블을 가져와 표시합니다. 이렇게하면 ListView에서 사용되는 재활용 된 View 개체와 관련된 문제를 방지 할 수 있습니다.

다음은 BatchImageDownloader의 소스 코드입니다.

package com.mobrite.androidutils;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.widget.BaseAdapter;

public class BatchImageDownloader extends AsyncTask<Void, Void, Void> {

    List<String> imgUrls = new ArrayList<String>();
    BaseAdapter adapter;
    HashMap<String, Drawable> imageCache;

    public BatchImageDownloader(BaseAdapter adapter,
            HashMap<String, Drawable> imageCache) {
        this.adapter = adapter;
        this.imageCache = imageCache;
    }

    public void addUrl(String url) {
        imgUrls.add(url);
    }

    @Override
    protected Void doInBackground(Void... params) {
        for (String url : imgUrls) {
            if (!imageCache.containsKey(url)) {
                Drawable bm = downloadImage(url);
                if (null != bm) {
                    imageCache.put(url, bm);
                    publishProgress();
                }
            }
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        adapter.notifyDataSetChanged();
    }

    @Override
    protected void onPostExecute(Void result) {
        adapter.notifyDataSetChanged();
    }

    public Drawable downloadImage(String url) {

        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet request = new HttpGet(url);
        try {
            HttpResponse response = httpClient.execute(request);
            InputStream stream = response.getEntity().getContent();
            Drawable drawable = Drawable.createFromStream(stream, "src");
            return drawable;
        } catch (ClientProtocolException e) {
            e.printStackTrace();
            return null;
        } catch (IllegalStateException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }

    }

}

To get the data from the database, you'd use a SimpleCursorAdapter.

I think you can directly bind the SimpleCursorAdapter to a ListView - if not, you can create a custom adapter class that extends SimpleCursorAdapter with a custom ViewBinder that overrides setViewValue.

Look at the Notepad tutorial to see how to use a SimpleCursorAdapter.


File name should match the layout id which in this example is : items_list_item.xml in the layout folder of your application

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

<ImageView android:id="@+id/R.id.list_item_image"
  android:layout_width="100dip"
  android:layout_height="wrap_content" />  
</LinearLayout>

We need to implement two layouts. One to hold listview and another to hold row item of listview. Implement your own custom adapter. Idea is to include one textview and one imageview.

public View getView(int position, View convertView, ViewGroup parent) {
 // TODO Auto-generated method stub
 LayoutInflater inflater = (LayoutInflater) context
 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 View single_row = inflater.inflate(R.layout.list_row, null,
 true);
 TextView textView = (TextView) single_row.findViewById(R.id.textView);
 ImageView imageView = (ImageView) single_row.findViewById(R.id.imageView);
 textView.setText(color_names[position]);
 imageView.setImageResource(image_id[position]);
 return single_row; 
 }

Next we implement functionality in main activity to include images and text data dynamically during runtime. You can pass dynamically created text array and image id array to the constructor of custom adapter.

Customlistadapter adapter = new Customlistadapter(this, image_id, text_name);

참고URL : https://stackoverflow.com/questions/459729/how-to-display-a-list-of-images-in-a-listview-in-android

반응형