如何将JSONArray填充到ListActivity的ListView中

时间:2010-09-14 11:59:38

标签: android listview

这是一个答案的帖子,我真的找不到一个好的解决方案。我搜索了很多,我找不到任何体面的东西。我不知道我使用的方法是否是最好的方法,但它有效,我觉得这是一个相当干净的解决方案。

这里要做一些假设。

  1. 你知道JSONArray是什么,并且已经以某种方式用一些数据填充了JSONArray。
  2. {"result":
        [
          {"ACTIVE":"1","ID":"1","MAX_POPULATION":"1000","NAME":"Server 1","URL":"http://local.orbitaldomination.com/"},
          {"ACTIVE":"1","ID":"2","MAX_POPULATION":"1000","NAME":"Server 2","URL":"http://server2.orbitaldomination.com/"}
        ]
    }
    

    这是我的JSON代码,填充到我的JSONArray中。

    1. 您已经创建了一个ListView,其中包含一个ListView元素,并且您已经创建了一个布局。如果您需要有关如何操作的更多信息,可以参考Creating Lists Using the ListActivity
    2. 好的,这就是真正的魔力所在......

          public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          // Pretty much ignore this .. it won't have anything to do with the example.
          // Your setContentView should be your layout with your list element.
          setContentView(R.layout.server_selection);
      
          //psuedo code 
          //JArrayServers = JSONArray that has my data in it.
      
          //Create a blank ( for lack of better term ) ArrayAdapter
          ArrayAdapter<String> servers = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);
      
          //Loop though my JSONArray
          for(Integer i=0; i< jArrayServers.length(); i++){
              try{
                  //Get My JSONObject and grab the String Value that I want.
                  String obj = jArrayServers.getJSONObject(i).getString("NAME");
      
                  //Add the string to the list
                  servers.add(obj);
              }catch(JSONException e){
      
              }
          }
          //Add my Adapter via the setListAdapter function.
          setListAdapter(servers);
      
          //Display the listView
          ListView lv = getListView();
          lv.setTextFilterEnabled(true);
      }
      

      我正在创建一个空白的ArrayAdapter。然后我循环通过数组获取我的字符串并在我移动时将其插入适配器。最后,在循环结束时,我通过setListAdapter()函数插入适配器。

      我认为很简单,但是从一个菜鸟那里进行了大量研究以得出这个。我相信你们所有的专家都会有更好的方法。如果你这样做,请将它贴在易于找到的地方!

2 个答案:

答案 0 :(得分:8)

实现此目的的最佳方法实际上是滚动自己的扩展BaseAdapter的自定义适配器。我在这个问题上挣扎了一天,试图避免对JSONArray进行无意义的迭代,只是为了填充一个数组并在“普通”的ArrayAdapter中使用它。我的情况与你的情况非常相似,我想填充一个微调器而不是ListView的差异很小。尽管如此,我会发布我找到的解决方案,因为它可能对您或其他人有所帮助。

在您的活动课程中:

public void initSpinner(JSONArray jsonArray)
{
     Spinner spinner = new Spinner(this);
     JSONArrayAdapter jsonArrayAdapter = new JSONArrayAdapter(this, countries, "Name");
     spinner.setAdapter(jsonArrayAdapter);
}

注意:我传递的字符串“name”有一个参数,我的适配器只是我希望在我的json数据中查找的键,在你的情况下,它可能是你正在寻找的任何键。

接下来,您需要滚动自己的微调器列表项,包含在RelativeLayout中。我在名为spinner_item.xml的文件中执行了此操作:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dip" >

<TextView
    android:id="@+id/spinnerListItemName"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_centerVertical="true"
    android:textColor="#000000"
    android:textSize="16dip" />

<RadioButton
    android:id="@+id/spinnerRadioButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_alignParentRight="true"
    android:paddingRight="6dip"
    android:focusable="false"
    android:clickable="false" />

<TextView
    android:id="@+id/spinnerListItemID"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="invisible" />

</RelativeLayout>

注意:我只是使用带有id spinnerListItemID的文本视图,因为我想存储我选择模拟RadioButtonGroup行为的最后一个按钮的id,很可能有更好的方法来完成这项任务,这就是我当时认为更适合的方式。

最后,最重要的是,您需要创建JsonArrayAdapter类:

public class JSONArrayAdapter extends BaseAdapter implements OnTouchListener
{

private ViewGroup group;
private JSONArray items;
private String key;
private Context context;
private String selectedItemID;
private int selectedItemPosition;

public JSONArrayAdapter(Context ctx, JSONArray array, String k)
{
    super();
    this.items = array;
    this.context = ctx;
    this.key = k;
    this.selectedItemPosition = -1;
}

public int getCount()
{
    return items.length();
}

public Object getItem(int position)
{
    return position;
}

public long getItemId(int position)
{
    return position;
}

public View getView(int position, View convertView, ViewGroup parent)
{
    View view = convertView;
    group = parent;

    if (view == null)
    {
        LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = vi.inflate(R.layout.spinner_item, null);
        view.setOnTouchListener(this);
    }

    String itemText = null;
    String itemID = null;

    try
    {
        JSONObject jsonObject = items.getJSONObject(position);
        itemText = jsonObject.getString(key);
        itemID = jsonObject.getString("ID");
    }
    catch (JSONException e)
    {

    }

    if (itemText != null)
    {
        TextView name = (TextView) view.findViewById(R.id.spinnerListItemName);
        TextView id = (TextView) view.findViewById(R.id.spinnerListItemID);
        RadioButton button = (RadioButton) view.findViewById(R.id.spinnerRadioButton);

        if (name != null)
            name.setText(itemText);

        if (id != null)
        {
            id.setText(itemID);
            id.setHint(position + "");
        }

        if (id.getText().toString().equals(selectedItemID))
        {
            button.setSelected(true);
            button.setChecked(true);
        }
        else
        {
            button.setSelected(false);
            button.setChecked(false);
        }
    }

    if (selectedItemPosition == -1 && position == 0)
        this.setFirstChosen(view);

    return view;
}

private void setFirstChosen(View view)
{
    RadioButton button = (RadioButton) view.findViewById(R.id.spinnerRadioButton);
    button.setSelected(true);
    button.setChecked(true);

    selectedItemID = ((TextView) view.findViewById(R.id.spinnerListItemID)).getText().toString();
    selectedItemPosition = Integer.parseInt(((TextView) view.findViewById(R.id.spinnerListItemID)).getHint().toString());
}

public boolean onTouch(View v, MotionEvent event)
{
    RadioButton button = (RadioButton) v.findViewById(R.id.spinnerRadioButton);

    if (selectedItemPosition != -1)
    {
        View previousView = group.getChildAt(selectedItemPosition);
        if (previousView != null)
        {
            RadioButton previous = (RadioButton) previousView.findViewById(R.id.spinnerRadioButton);
            previous.setSelected(false);
            previous.setChecked(false);
        }
    }

    button.setSelected(true);
    button.setChecked(true);
    selectedItemID = ((TextView) v.findViewById(R.id.spinnerListItemID)).getText().toString();
    selectedItemPosition = Integer.parseInt(((TextView) v.findViewById(R.id.spinnerListItemID)).getHint().toString());

    return false;
}

}

你有它,对我来说就像一个魅力,我知道在线找到这个主题的信息是痛苦的:)

答案 1 :(得分:1)

另一种方法是创建自己的适配器类,扩展BaseAdapter。例如,如果每个ListView行需要多个数据,这将非常有用。