Android ArrayAdapter 文本和图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21833181/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ArrayAdapter text and image
提问by TWONEKSONE
In my activity I implement a list which contains the names of some files. Every list's item refers to a layout in which I'd like to show the name of the images and a thumbnail of the image referenced. Ican show the the name using an ArrayAdapter but i don't know hot to insert the image thumbnail. All the image referenced stay in sd_card and i have the path of they. Here is the single row layout:
在我的活动中,我实现了一个包含某些文件名称的列表。每个列表的项目都指一个布局,我想在其中显示图像的名称和引用图像的缩略图。我可以使用 ArrayAdapter 显示名称,但我不知道如何插入图像缩略图。所有引用的图像都保留在 sd_card 中,我有它们的路径。这是单行布局:
<?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="50dp"
android:orientation="horizontal" >
<ImageView
android:id="@+id/imageView"
android:layout_width="36dp"
android:layout_height="wrap_content"
android:src="@drawable/btn_nav_background_default" />
<TextView
android:id="@+id/titoloTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
and the layout of the activity
以及活动的布局
<?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="vertical" >
<Button
android:id="@+id/creaButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Crea una nuova realtà aumentata" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Ar già create"
android:textAppearance="?android:attr/textAppearanceLarge" />
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
and the activity code inherent adapter.
和活动代码固有的适配器。
ArrayAdapter<?> arrayAdapter = new ArrayAdapter<String>(this,R.layout.row,R.id.titoloTv,targetName);
listView.setAdapter(arrayAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapter, final View componente, int pos, long id){
...................
}
});
I'm trying using this but doesn't work properly.
我正在尝试使用它,但无法正常工作。
String tempTarget;
List<Map<String,Object>> data = new ArrayList<Map<String,Object>>();
for(int i = 0; i<ARelements.size();i++){
Element ar = arIterator.next();
Map<String,Object> map = new HashMap<String,Object>(2);
tempTarget = ar.getAttributeValue("TARGET");
thumbnailBitmap = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(tempTarget), THUMBSIZE, THUMBSIZE);
map.put("thumbnail", thumbnailBitmap);
map.put("titolo", tempTarget);
data.add(map);
}
arIterator= null;
SimpleAdapter simpleAdapter = new SimpleAdapter(this,data,R.layout.row,new String[] {"thumbnail","titolo"},new int[] {R.id.imageView, R.id.titoloTv});
listView.setAdapter(simpleAdapter);
回答by Pararth
You need to implement a custom array adapter and specify that imageview and textview layout/id(s) in the adapter.
您需要实现自定义数组适配器并在适配器中指定 imageview 和 textview 布局/id。
Something like:
就像是:
public class CustomListViewAdapter extends ArrayAdapter<RowItem> {
Context context;
public CustomListViewAdapter(Context context, int resourceId, //resourceId=your layout
List<RowItem> items) {
super(context, resourceId, items);
this.context = context;
}
/*private view holder class*/
private class ViewHolder {
ImageView imageView;
TextView txtTitle;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
RowItem rowItem = getItem(position);
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, null);
holder = new ViewHolder();
holder.txtTitle = (TextView) convertView.findViewById(R.id.title);
holder.imageView = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
} else
holder = (ViewHolder) convertView.getTag();
holder.txtTitle.setText(rowItem.getTitle());
holder.imageView.setImageResource(rowItem.getImageId());
return convertView;
}
}
And then:
进而:
listView = (ListView) findViewById(R.id.list);
CustomListViewAdapter adapter = new CustomListViewAdapter(this,
R.layout.list_item, rowItems);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Toast toast = Toast.makeText(getApplicationContext(),
"Item " + (position + 1) + ": " + rowItems.get(position),
Toast.LENGTH_SHORT);
toast.show();
}
Refer Extending other Adapters too, for ListView(s) and their custom implementation:
Eg.
http://theopentutorials.com/tutorials/android/listview/android-custom-listview-with-image-and-text-using-arrayadapter/
对于 ListView(s) 及其自定义实现,请参阅扩展其他适配器:
例如。
http://theopentutorials.com/tutorials/android/listview/android-custom-listview-with-image-and-text-using-arrayadapter/
回答by Nickel
You don't necessarily need a custom ArrayAdapter, a SimpleAdapter will do the trick for a thumbnail/text combo. You can store the path to the thumbnail and the text you want in a HashMap array, and then apply it using a SimpleAdapter. For example, if you had 5 thumbnails + text and arrays of each:
您不一定需要自定义 ArrayAdapter,SimpleAdapter 可以实现缩略图/文本组合。您可以将缩略图的路径和所需的文本存储在 HashMap 数组中,然后使用 SimpleAdapter 应用它。例如,如果您有 5 个缩略图 + 文本和每个的数组:
List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
for (int i = 0; i < 5; i++) {
Map<String, Object> datum = new HashMap<String, Object>(2);
datum.put("thumbnail", thumbnail[i]);
datum.put("name", text[i]);
data.add(datum);
}
YourListViewId.setAdapter(new SimpleAdapter(this, data, R.layout.yoursinglerowlayout, new String[] {"thumbnail","name"}, new int[] {R.id.imageView, R.id.titoloTv}));
回答by mike20132013
First: You will have to change your ArrayAdapter to BaseAdapter because BaseAdapter gives you more flexibility with the views. Try to use this code and see how it works:
首先:您必须将 ArrayAdapter 更改为 BaseAdapter,因为 BaseAdapter 为您提供了更大的视图灵活性。尝试使用此代码,看看它是如何工作的:
Here's how I am getting images from sd card and populating it in a listview
这是我从 SD 卡获取图像并将其填充到列表视图中的方法
public class GetSdCardContent extends Activity {
public static Cursor cursor;
private int columnIndex;
private File file;
private String SD_CARD_ROOT;
ArrayList<String> f = new ArrayList<String>();
File[] listFile;
ImageAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sdcard_layout);
getSdcardImages();
ListView lv1 = (ListView) findViewById(R.id.sdlistView1);
adapter = new ImageAdapter();
lv1.setAdapter(adapter);
}
public void getSdcardImages() {
File file = new File(
android.os.Environment.getExternalStorageDirectory().getPath(),
"Pictures");
if (file.isDirectory()) {
listFile = file.listFiles();
for (int i = 0; i < listFile.length; i++) {
f.add(listFile[i].getAbsolutePath());
Log.i("FILES:"+"---", f.toString());
}
}
}
This is the adapter I am using. It's a base adapter and I am getting only images for now. You can also add your TextView if you want to.
这是我正在使用的适配器。这是一个基本适配器,我现在只得到图像。如果需要,您还可以添加 TextView。
public class ImageAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public ImageAdapter() {
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return f.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.custom_listview_items,
null);
holder.imageview = (ImageView) convertView
.findViewById(R.id.customimageView1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Bitmap myBitmap = BitmapFactory.decodeFile(f.get(position));
try {
holder.imageview.setImageBitmap(getResizedBitmap(myBitmap, 300, 300));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return convertView;
}
}
This method is for bitmap. If you want to resize your image and stuff.
此方法用于位图。如果您想调整图像和内容的大小。
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
// "RECREATE" THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
class ViewHolder {
ImageView imageview;
}
}
Last part: Two layouts.
最后一部分:两种布局。
One: layout for items.
一:物品的布局。
<?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="vertical" >
<ImageView
android:id="@+id/customimageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/bluebutton" />
</LinearLayout>
Second: Main Layout. (ListView)
第二:主要布局。(列表显示)
<?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="vertical" >
<ListView
android:id="@+id/sdlistView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
Hope this gives some help..:)
希望这能提供一些帮助..:)
回答by TWONEKSONE
I've solved it using this class
我已经使用这个类解决了它
public class ExtendedSimpleAdapter extends SimpleAdapter{
List<HashMap<String, Object>> map;
String[] from;
int layout;
int[] to;
Context context;
LayoutInflater mInflater;
public ExtendedSimpleAdapter(Context context, List<HashMap<String, Object>> data,
int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
layout = resource;
map = data;
this.from = from;
this.to = to;
this.context = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return this.createViewFromResource(position, convertView, parent, layout);
}
private View createViewFromResource(int position, View convertView,
ViewGroup parent, int resource) {
View v;
if (convertView == null) {
v = mInflater.inflate(resource, parent, false);
} else {
v = convertView;
}
this.bindView(position, v);
return v;
}
private void bindView(int position, View view) {
final Map dataSet = map.get(position);
if (dataSet == null) {
return;
}
final ViewBinder binder = super.getViewBinder();
final int count = to.length;
for (int i = 0; i < count; i++) {
final View v = view.findViewById(to[i]);
if (v != null) {
final Object data = dataSet.get(from[i]);
String text = data == null ? "" : data.toString();
if (text == null) {
text = "";
}
boolean bound = false;
if (binder != null) {
bound = binder.setViewValue(v, data, text);
}
if (!bound) {
if (v instanceof Checkable) {
if (data instanceof Boolean) {
((Checkable) v).setChecked((Boolean) data);
} else if (v instanceof TextView) {
// Note: keep the instanceof TextView check at the bottom of these
// ifs since a lot of views are TextViews (e.g. CheckBoxes).
setViewText((TextView) v, text);
} else {
throw new IllegalStateException(v.getClass().getName() +
" should be bound to a Boolean, not a " +
(data == null ? "<unknown type>" : data.getClass()));
}
} else if (v instanceof TextView) {
// Note: keep the instanceof TextView check at the bottom of these
// ifs since a lot of views are TextViews (e.g. CheckBoxes).
setViewText((TextView) v, text);
} else if (v instanceof ImageView) {
if (data instanceof Integer) {
setViewImage((ImageView) v, (Integer) data);
} else if (data instanceof Bitmap){
setViewImage((ImageView) v, (Bitmap)data);
} else {
setViewImage((ImageView) v, text);
}
} else {
throw new IllegalStateException(v.getClass().getName() + " is not a " +
" view that can be bounds by this SimpleAdapter");
}
}
}
}
}
private void setViewImage(ImageView v, Bitmap bmp){
v.setImageBitmap(bmp);
}
}