ArrayAdapter文本和图像

7
在我的活动中,我实现了一个列表,其中包含一些文件的名称。每个列表项都引用了一个布局,在该布局中,我想显示图像的名称和图像缩略图。我可以使用ArrayAdapter来显示名称,但我不知道如何插入图像缩略图。所有引用的图像都存储在SD卡中,我有它们的路径。以下是单个行布局:
<?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>

活动的布局

<?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>

以及活动代码固有适配器。

    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){

...................            
           } 

    }); 

我试图使用这个,但是它不能正常工作。

    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);

搜索“自定义数组适配器”。 - Timuçin
你能提供缺失的部分吗?在getView()方法中获取/显示图像的文本/名称... - Kody
4个回答

15
您需要实现一个自定义的数组适配器,并在适配器中指定ImageView和TextView的布局/ID。类似以下内容:
  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;
    }
}  

然后:

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();
}  

参考扩展其他适配器,包括ListView及其自定义实现:
例如: http://theopentutorials.com/tutorials/android/listview/android-custom-listview-with-image-and-text-using-arrayadapter/


RowItem是您单独创建的另一个类吗?它包含什么内容,用于操作行项目的代码?我只是不确定它们如何配合。 - Azurespot
1
行项目将是与适配器和列表项相关的另一个模型。 - Pararth

6

您并不一定需要自定义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}));

我正在尝试使用这个技巧,但是它不起作用。我只看到被一条线包围的空记录。我发布了我的实现。 - TWONEKSONE

1
首先:您需要将ArrayAdapter更改为BaseAdapter,因为BaseAdapter在视图方面更加灵活。尝试使用此代码并查看其工作原理:
这是我如何从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());

            }
        }
    }

这是我正在使用的适配器。它是一个基础适配器,目前我只获取图像。如果您想要,还可以添加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;
        }
    }

这个方法适用于位图。如果您想调整图像大小等内容。

    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;

    }
}

最后一部分:两种布局。
一种:用于项目的布局。
<?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>

第二步:主布局。(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>

希望这能提供一些帮助.. :)

事实是我无法从ID引用我的图像,因为我需要使用来自SD卡的图像。 - TWONEKSONE
所以在从SD卡获取图像后,我猜您正在查询图像,因此在获得查询结果后,请将结果存储在数组列表中,然后可以在基本适配器适配器中添加一个更多的数组列表,并对MainActivity进行更改。 - mike20132013
只有一个问题。我应该使用哪种方法来从路径设置我的图像? - TWONEKSONE
你正在使用光标获取图像吗? 你只需要查询数据库来获取图像。 现在根据您想要提取的图像,路径将不同。過一會兒我可以發佈完整的答案。 - mike20132013
不,我没有使用游标。这些图片存储在SD卡中,我可以通过文件路径mnt/sd_card/....../images.jpg进行引用。 - TWONEKSONE
显示剩余3条评论

0

我使用这个类解决了它

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);
}



}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接