【问题标题】:Generate listview from JSON in android在android中从JSON生成listview
【发布时间】:2012-09-28 14:53:24
【问题描述】:

我对 Android 完全陌生,目前正在尝试从从我的服务器中提取的 JSON 数组生成列表视图,我已经阅读了很多教程但没有运气,有一种独特的方法可以做到这一点。能否请您指出一些好的开始资源。

我已经阅读了this 页面,但是我被以下代码卡住了:

import josecgomez.com.android.dev.webservice.objects.alerts;

给我“”作为没有识别的资源:

public class AlertsAdapter extends ArrayAdapter<alerts>

谢谢,非常感谢您的帮助!

【问题讨论】:

  • 您能否发布一个您希望显示的 JSON 对象的示例?另外,您是否只想在列表中显示名称?

标签: android json listview


【解决方案1】:

JSON & listview 会这样工作..

1.显示项目列表

Android SDK 使用名为 android.app.ListActivity 的超类提供了一种快速显示数据列表的便捷方式。这个 Activity 已经提供了一个 ContentView,配置了 ListView,可以使用并填充数据。

现在需要为 ListView 提供要显示的数据,以及将这些数据映射到行的方法。 ListAdaptor 提供了这种机制,并使用 setListAdaptor 在 ListActivity 的底层 ListView 上进行设置。

Android SDK 提供了适配器(ArrayAdaptor),它知道如何将任意数据数组处理成ListViews(Android SDK 还附带了其他几个ListAdaptors,例如光标适配器,它可以在连接本地数据存储时提供帮助到列表视图)。您还需要为适配器提供可用于将元素呈现到每一行的布局。在下面的示例中,我们使用的是 Android SDK 提供的布局,simple_list_item_1,它是一个单一的文本标签——非常适合放置我们的单个字符串:

String[] elements = {"Line 1", "Line 2"};
setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, elements));

2.自定义每个列表项的外观

为了实现这一点,您必须超越内置布局和 ArrayAdaptor 并实现自己的。

首先创建一个可用于将作者和内容保存为字符串的类 ABC。然后使用一些测试数据创建并填充一个对象,以在自定义列表项中显示:

public class ABC {
    String userId;
    String pwd;
}

/res/layout/list_item.xml 中创建一个布局XML 文件以定义两个TextViews 以在不同的行上显示内容和作者。为了将它们一个接一个地显示,请使用 LinearLayout,配置为垂直渲染其中的每个元素(android:orientation="vertical")

创建 XML 文件后,Android Eclipse 插件会自动将其作为引用添加到生成的 R 文件中。此 R 文件保存在项目的 /gen 文件夹下,充当 XML 元素和 Java 代码之间的桥梁。它允许您的 Java 代码引用在 /res 文件夹下创建的 XML 元素和文件。您刚刚创建的文件现在可以在 Java 代码中引用为 R.layout.list_item,接下来您将在自定义列表适配器中执行此操作。

创建一个名为 ListAdaptor 的私有类(在 Activity 内),它是 ArrayAdaptor 的子类。此类应用于存储正在显示的 ArrayList,并提供一种将对象映射到您在上面的布局中创建的 TextViews 的方法。

此映射覆盖 ListAdaptor,并应返回一个 View 对象,该对象填充了请求位置的数据内容。

自定义abcListAdaptor的完整实现如下:

private class abcListAdaptor extends ArrayAdapter<abc> {  
    private ArrayList<abc> abc;  
    public abcListAdaptor(Context context, int textViewResourceId, ArrayList<abc> items) {  
        super(context, textViewResourceId, items);  
        this.abc = 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.list_item, null);  
        }  

        abc o = abc.get(position);  
        TextView tt = (TextView) v.findViewById(R.id.uid);  
        TextView bt = (TextView) v.findViewById(R.id.pwd);  
        tt.setText(o.userid);  
        bt.setText(o.pwd);  
        return v;  
    }  
}  

现在可以调整 onCreate 方法以使用自定义列表适配器和创建的测试数据,如下所示:

public void onCreate(Bundle savedInstanceState) {  
super.onCreate(savedInstanceState);  
abc a = new abc();  
a.userid = "tech";  
a.pwd = "android";  
ArrayList<abc> items = new ArrayList<abc>();  
items.add(a);  
abcListAdaptor adaptor = new abcListAdaptor(this,R.layout.list_item, items);  
setListAdapter(adaptor);  
}  

3.访问远程服务和解析数据

Android SDK 包含旨在简化对基于 HTTP 的 API 的访问的软件包。 Apache HTTP 类已包含在内,可以在org.apache.http package 下找到。您将使用这些类以及 org.json 类来解析从服务器返回的数据。

我们可以在 Activity 中创建一个私有方法,它发出请求、解析结果并返回对象的ArrayList。下面列出的代码发出请求并查找生成的JSON array,它被迭代以提取每个文本和 from_user 元素。

ArrayList<abc> getDetail= new ArrayList<abc>();  
    try {  
        HttpClient hc = new DefaultHttpClient();  
        HttpGet get = new  
        HttpGet("<a href="http://your URL"></a>");  
        HttpResponse rp = hc.execute(get);  

        if(rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {  
            String result = EntityUtils.toString(rp.getEntity());  
            JSONObject root = new JSONObject(result);  
            JSONArray sessions = root.getJSONArray("results");  

            for (int i = 0; i < sessions.length(); i++) {  
                JSONObject session = sessions.getJSONObject(i);  
                abc a = new abc();  
                a.uid = session.getString("user");  
                a.pwd = session.getString("password");  
                getDetail.add(a);  
            }  
        }  
    } 

    catch (Exception e) {  
        Log.e("Activity", "Error loading JSON", e);  
    }  

现在在 onCreate 方法中构造自定义列表适配器时,将之前使用的虚拟数据替换为调用 load 方法。

abcListAdaptor adaptor = new abcListAdaptor(this,R.layout.list_item, load());  

4.创建响应式用户界面

当前状态的代码可能会导致出现应用程序无响应 (ANR) 对话框,提示用户退出您的应用程序。这可能是由于在 onCreate 等方法中执行远程数据请求的长期工作。

不应在主应用程序线程(驱动用户界面事件循环)上执行长时间运行的任务。它们应该被派生到子线程中来执行工作。

虽然Java的Thread类可以用于这个任务,但是有一个复杂的地方是一旦长时间运行的任务完成后,它通常想要改变用户界面来报告结果(即显示一个列表从请求中加载)。

用户界面元素只能从主线程更改其状态,因为 Android UI 工具包不是线程安全的,因此后台线程需要向主线程发送消息以操作 UI。

值得庆幸的是,Android SDK 提供了一个方便的类 AsyncTask,它为异步任务与 UI 线程安全交互提供了一种简单的机制。这是通过继承 AsyncTask 并重写 doInBackground 方法来执行长时间运行的任务,然后重写 onPostExecute 来执行 UI 上的任何操作来实现的。

当 AsyncTask 创建(它必须在 UI 线程上创建)并执行时,doInBackground 方法在后台线程上被调用。完成后,将在主 UI 线程上调用 onPostExecute 方法。

要在您的应用程序中使用它,您需要在 Activity 中实现一个名为 MyTask 的私有类(如自定义适配器类),它是 AsyncTask 的子类。您可以使用之前加载方法的内容覆盖 doInBackground 方法。

您无需返回 ArrayList,而是在 Activity 中维护一个实例变量,以便可以在私有类之间共享数据。然后在 onPostExecute 中,您可以使用数据设置列表适配器,就像之前在 onCreate 中所做的那样。 onCreate 方法现在只需创建 MyTask 对象并调用 execute 方法。

listView

最佳网站thisthis

--

问候

技术结束

【讨论】:

    【解决方案2】:

    您需要将 JSON 对象的重要元素存储到您自己创建的新对象中。

    假设您的 JSON 对象为您提供包含姓名、日期和电话号码的键,您需要一个包含此类信息的对象。

    您的列表视图将采用您的新类型的数组适配器,列表视图的每个单元格将包含填充有您的对象信息的 UI 元素(例如文本视图)

    这至少是一个 3 步过程,您需要单独解决每个步骤的解决方案

    【讨论】:

      【解决方案3】:

      在您的活动中尝试此代码首先将 json 数据解析为字符串数组 然后在您的活动的 xml 中设置您的 Listview 适配器

      try
         {
      
         JSONArray jArray = new JSONArray(result);
         JSONObject jObj=new JSONObject ();
         String[] data=new String[jArray.length()]
      
             for(int i=0;i<jArray.length();i++)
             {
                jObj= jArray.getJSONObject(i);
                data[i]=json_data.getString("value");
      
             }
      
             GameAdapter adapter = new GameAdapter(this, R.layout.listview_item_row, data);
             listView1 = (ListView)findViewById(R.id.listView1);
             listView1.setAdapter(adapter);
      }
      catch(Exception e)
      {
      }
      

      【讨论】:

      • 如果这段代码对你没有帮助,我会发布完整的代码,如果你的问题没有解决,请告诉我
      【解决方案4】:

      我在这个话题上找到了一个很好的resource。现在我有我的 Json 数据列表。强烈推荐给所有新手。谢谢你们的帮助。

      【讨论】:

      • 我看不出 Ashwani 上面的回答不起作用的原因。就这么简单。
      • 你得到了非常合格的答案,选择你自己的答案作为正确答案不太礼貌......
      【解决方案5】:

      我建议您按照以下步骤操作:

      1. 从网络获取数据并存储
      2. 将存储的数据传递给适配器
      3. 将适配器设置到您的列表中

      在第一步中,我建议您使用AsyncTask 类获取数据,该类允许执行后台操作并在 UI 线程上发布结果,而无需操作线程和/或处理程序。其次,你必须根据你得到的 JSON 结构来解析你的内容。最后,将您的数据传递给适配器以填充您的列表。

      【讨论】:

        猜你喜欢
        • 2019-04-22
        • 1970-01-01
        • 2017-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-03
        相关资源
        最近更新 更多