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
'Nice programing' 카테고리의 다른 글
함수 포인터의 역 참조는 어떻게 발생합니까? (0) | 2020.11.15 |
---|---|
iPhone / iOS : 우편 번호 용 HTML 5 키보드 제시 (0) | 2020.11.15 |
MATCH AGAINST 또는 LIKE 중 어떤 SQL 쿼리가 더 낫습니까? (0) | 2020.11.15 |
JSON 구조 문서화를위한 구문 (0) | 2020.11.15 |
AngularJS를 사용한 인증, REST Api WS를 사용한 세션 관리 및 보안 문제 (0) | 2020.11.15 |