带有arraylist的listview,android中的简单适配器

Posted

技术标签:

【中文标题】带有arraylist的listview,android中的简单适配器【英文标题】:listview with arraylist,simple adapter in android 【发布时间】:2013-09-08 20:17:26 【问题描述】:

我尝试使用 arraylist 和简单的适配器在 listview 中显示一些东西。 我尝试了类似下面的方法,但在我的结果中显示了数组列表的姓氏。 我有什么问题我无法理解。

final ListView listView = (ListView) findViewById(R.id.mylist);

    ArrayList<HashMap<String, String>> list_of_bookmarks = new ArrayList<HashMap<String, String>>();

        HashMap<String, String> b = new HashMap<String, String>();

        String[] from =  "php_key","c_key","android_key","hacking_key" ;
        String[] name_of_bookmarks =  "php","c","android","hacking" ;

            for(int i=0;i<4;i++)
            
              b.put(from[i],name_of_bookmarks[i]);   
              list_of_bookmarks.add(b);
            

         ;

            int[] to =  R.id.txt1,R.id.txt1,R.id.txt1,R.id.txt1;

            SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), list_of_bookmarks, R.layout.list_layout, from, to);         
            listView.setAdapter(adapter);

我只想在列表视图中显示“php”、“c”、“android”、“hacking”。 什么应该是更有效的方法来做到这一点。我是一个初学者,所以你可以建议我应该遵循的更好的方法

【问题讨论】:

它只显示最后一个值? 最后一个值的 4 倍,例如“hacking,hacking,hacking,hacking” 【参考方案1】:

我给你的建议是创建一个单独的类来扩展适配器(或它的某个子类)

这是一个字符串数组适配器的简单示例。

package ro.gebs.captoom.adapters;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import antistatic.spinnerwheel.adapters.AbstractWheelTextAdapter;

import com.example.captoom.R;

public class LanguagesAdapter extends AbstractWheelTextAdapter 
    // Countries names
    private String languages[];

    public LanguagesAdapter(Context context) 
        super(context, R.layout.lang_item, NO_RESOURCE);
        languages = context.getResources().getStringArray(R.array.lang_array);
        setItemTextResource(R.id.language_txt);
    

    @Override
    public View getItem(int index, View cachedView, ViewGroup parent) 
        View view = super.getItem(index, cachedView, parent);
        return view;
    

    @Override
    public int getItemsCount() 
        return languages.length;
    

    @Override
    protected CharSequence getItemText(int index) 
        return languages[index];
    

而且用法很简单,只要使用方法.setAdapter();

或者另一个使用 arrayAdapter 的例子:

package apc.example;

import java.util.ArrayList;

import utils.BitmapManager;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class PersonAdapter extends ArrayAdapter<Person> 

    Context context;
    int layoutResourceId;
    ArrayList<Person> data = null;

    public PersonAdapter(Context context, int layoutResourceId,
            ArrayList<Person> data) 
        super(context, layoutResourceId, data);
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.data = data;
    

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
        View row = convertView;
        ItemHolder holder = null;

        if (row == null) 
            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);

            holder = new ItemHolder();
            holder.imgIcon = (ImageView) row.findViewById(R.id.icon);
            holder.txtName = (TextView) row.findViewById(R.id.title);
            holder.txtDescription = (TextView) row.findViewById(R.id.desc);

            row.setTag(holder);
         else 
            holder = (ItemHolder) row.getTag();
        

        Person bean = data.get(position);
        holder.txtName.setText(bean.getName());
        holder.txtDescription.setText(bean.getDescription());


        Bitmap b = BitmapFactory.decodeResource(context.getResources(), R.drawable.user);
        BitmapManager.INSTANCE.setPlaceholder(b);
        BitmapManager.INSTANCE.loadBitmap(bean.getUrl(), holder.imgIcon, 80, 80);

        return row;
    

    public static class ItemHolder 
        public ImageView imgIcon;
        TextView txtName;
        TextView txtDescription;
    

    public void updateAdapter(ArrayList<Person> pers)
        this.data = pers;
    

这是一个适配器示例,用于具有更多字段而不是简单字符串的更复杂类。但这可以很容易地修改为ArrayAdapter&lt;String&gt;,然后从那里开始。

无论如何,我认为为列表视图编写自定义适配器始终是最佳实践。

希望这会有所帮助!

【讨论】:

+ 1 用于具有 ViewHolder 模式的自定义适配器!这是一个很有价值的例子。【参考方案2】:

Main.xml

<LinearLayout  

    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_   >


    <ListView
        android:id="@+id/zone_list"
        android:layout_marginBottom="70dp"
        android:background="@drawable/batteryborder"
        android:layout_
        android:layout_ >
    </ListView>

</LinearLayout>

setlanguage.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_>

    <TextView
        android:id="@+id/tvName"
        android:layout_
        android:layout_
        android:textSize="18dp"
        android:gravity="center_vertical" />

</LinearLayout>

在您的活动文件中添加 onCreate()

ListView listView;

String[] from =  "php_key","c_key","android_key","hacking_key" ;

ArrayAdapter arrayAdapter;

listView = (ListView) findViewById(R.id.zone_list); 

arrayAdapter = new ArrayAdapter<>(this,R.layout.setlanguage, R.id.tvName, from);

listView.setAdapter(arrayAdapter);

【讨论】:

这不是 SimpleAdapter。【参考方案3】:

您在 int[] 对象中重复使用相同的视图。

int[] to = R.id.txt1,R.id.txt1,R.id.txt1,R.id.txt1;

看起来它将它们都视为同一个对象,因此每次添加新项目时都会更改以前的项目。

为了使用SimpleAdapter,您需要在 XML 中定义具有不同 ID 的每个视图。

int[] to = R.id.txt1,R.id.txt2,R.id.txt3,R.id.txt4;

SimpleAdapter 就其内部复杂性而言可能更简单,但实际使用肯定不会更简单。使用ArrayAdapter,您可以将项目列表传递给它并让它自动生成视图。只要您不耗尽内存,它可以是您需要的任何大小。 (见下例)

一旦您开始使用自定义适配器,我强烈建议您观看Romain Guy & Adam Powell's I/O talk。学习时需要吸收很多内容,但他们很好地解释了ListViews 的工作原理。

//List of Items
String[] name_of_bookmarks =  "php","c","android","hacking" ;

//Create your List object for the ArrayAdapter
//and make it the same size as name_of_books
List<String> listBookmarks = new ArrayList<String>(Array.getLength(name_of_bookmarks));

//Add name_of_bookmarks contents to listBookmarks
Collections.addAll(listBookmarks, name_of_books);

//Create an ArrayAdapter passing it the Context, a generic list item and your list
//An alternative to "this" would be "getApplicationContext()" from your main activity
//or "getActivity()" from a fragment. "getBaseContext()" is not recommended.
ArrayAdapter arrayAdapter = new ArrayAdapter(this, R.layout.list_item_text, listBookmarks);

//Set the adapter to your ListView
final ListView listView = (ListView) findViewById(R.id.mylist);
listView.setAdapter(arrayAdapter);

【讨论】:

那我该怎么办?? @乔恩 对每个使用不同的文本视图。 如果您知道需要多少,您可以将它们添加到布局的 XML 中。动态生成它们会给您带来更大的灵活性,但会使事情变得相当复杂。 我只想在列表视图中显示 "php","c","android","hacking"。如果它有 200 个项目,那么是否可以创建 200 个文本视图?? 我不相信 SimpleAdapter 是这样的【参考方案4】:

试试这个

  public class MyFragment extends ListFragment

    String[] from =  "php_key","c_key","android_key","hacking_key" ;
    String[] name_of_bookmarks =  "php","c","android","hacking" ;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) 

        List<HashMap<String, String>> list= new ArrayList<HashMap<String,String>>();

        for (int i = 0; i < name_of_bookmarks.length; i++) 

            HashMap<String, String> map= new HashMap<String, String>();
            map.put("key",  name_of_bookmarks[i]);
            list.add(map);
        
        String[] from =  "key" ;

        int[] to =  R.id.txt;

        SimpleAdapter adapter = new SimpleAdapter(getActivity().getBaseContext(), list, R.layout.list_layout, from, to);
        setListAdapter(adapter);

        return super.onCreateView(inflater, container, savedInstanceState);
    


【讨论】:

text1 是布局中的文本视图,因此我可以在文本视图中显示名称 我为什么要把另一个 textview 作为 R.id.txt2 我只想在列表视图中显示 "php","c","android","hacking"。就是这样【参考方案5】:

无论你面对什么问题,我都是这个问题的真正面对者,称为“列表” 查看显示数组数据的最后位置..."

问题是由哈希映射产生的

final ListView listView = (ListView) findViewById(R.id.mylist);

ArrayList<HashMap<String, String>> list_of_bookmarks = new ArrayList<HashMap<String, String>>();

    String[] from =  "php_key","c_key","android_key","hacking_key" ;
    String[] name_of_bookmarks =  "php","c","android","hacking" ;

        for(int i=0;i<4;i++)
         
          HashMap<String, String> b = new HashMap<String, String>();
          b.put(from[i],name_of_bookmarks[i]);   
          list_of_bookmarks.add(b);
        

     ;

        int[] to =  R.id.txt1,R.id.txt1,R.id.txt1,R.id.txt1;

        SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), list_of_bookmarks, R.layout.list_layout, from, to);         
        listView.setAdapter(adapter);

如果您有任何疑问,请尝试这个,然后再问我任何问题 只需在 For 循环中声明您的哈希图 ...

在每次创建的 For 循环变量“b”中使用哈希映射,并将其视为不同的对象。然后简单地用数组列表显示不同的Hash Map对象。

您正在使用相同的对象来存储哈希映射的值,并且该变量被同名覆盖,这就是您面临问题的原因 谢谢...

【讨论】:

以上是关于带有arraylist的listview,android中的简单适配器的主要内容,如果未能解决你的问题,请参考以下文章

使用带有自定义 baseadapter 的 arraylist 错误地删除列表视图项位置

Android ListView 和带有 ViewHolder 的自定义适配器

带有过滤器 Android 的自定义 Listview 适配器

Android ListView 标头

为啥我没有从 ArrayList 获取 ListView 数据?

使用 ListView 从另一个 Activity 打印 ArrayList