【问题标题】:How to populate listview with data from different json如何使用来自不同 json 的数据填充列表视图
【发布时间】:2018-06-28 08:07:40
【问题描述】:

我正在开发一个应用程序,在该应用程序中我需要从两个不同的 json 检索数据,并且我必须在 android 中填充一个列表视图。在第一个 Json 中,我有一个对象数组,我有一个 id 对象和一个需要检索该对象数据的 url。

我该怎么做?我可以检索对象并使用该对象填充列表视图,但我不知道如何获取单个对象的数据并将其显示在同一行中。

列表视图应该是这样的:

这是 Json1:

[
    {
        "id": "S1",
        "url": "MyUrl1"
    },
    {
        "id": "S2",
        "url": "MyUrl2"
    },
    {
        "id": "S3",
        "url": "MyUrl3"
    }
]

每个对象都不同。这是 Json2:

{
    "id": "S1",
    "temp": "20.03",
    "time": "28 June 2018, 9:12:13"
}

所以,我可以检索 id 并在 listView 中显示所有 id 对象,但我无法为每个对象检索“temp”和“time”值。

这是我的代码:

适配器

public class SensorAdapter extends BaseAdapter{
ArrayList<String> id= new ArrayList<String>();
ArrayList<String> labelno_array = new ArrayList<String>();
Context context;
LayoutInflater inflater;


public SensorAdapter2(Context c, ArrayList<String> label_array)
{
    context = c;
    id= label_array;
   // temp=temp_array;
   // time=time_array;
    //labelno_array = no_array;
    inflater = LayoutInflater.from(context);
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return id.size();
}

@Override
public Object getItem(int position) {
    // TODO Auto-generated method stub
    return position;
}

@Override
public long getItemId(int position)
{
    // TODO Auto-generated method stub
    return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
    View v = convertView;
    Holder holder;
    // TODO Auto-generated method stub
    if (v == null) {
        v = inflater.inflate(R.layout.columns_sensor, null);
        holder = new Holder();
        holder.tv_labelname = (TextView)v.findViewById(R.id.idsensor);

        v.setTag(holder);
    } else {
        holder = (Holder) v.getTag();
    }


    holder.tv_labelname.setText(id.get(position));

    return v;
}
public class Holder
{
    TextView tv_labelname,tv_labelno, tv_temp, tv_time;
}

这是我检索传感器数量的代码:

代码

 class RetrieveFeedTask2 extends AsyncTask<Void, Void, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }



    protected String doInBackground(Void... urls) {
        String API_URL = "MyUrl";

        try {
            URL url = new URL(API_URL);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            try {
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                StringBuilder stringBuilder = new StringBuilder();
                String line;
                while ((line = bufferedReader.readLine()) != null) {
                    stringBuilder.append(line).append("\n");
                }
                bufferedReader.close();
                return stringBuilder.toString();
            }
            finally{
                urlConnection.disconnect();
            }
        }
        catch(Exception e) {
            Log.e("ERROR", e.getMessage(), e);
            return null;
        }
    }

    protected void onPostExecute(String response) {
        if(response == null) {
            response = "THERE WAS AN ERROR";
        }
        //            progressBar.setVisibility(View.GONE);
        Log.i("INFO", response);

        try
        {

            JSONArray array=new JSONArray(response);

            for(int i = 0; i < array.length(); i++)
            {
                JSONObject obj = array.getJSONObject(i);

                String mysenso=obj.getString("id");
                String myurl=obj.getString("url");
                //partire nuova chiamata con l'url.
                label_no.add(myurl);
                label_name.add(mysenso);


            }


        }
        catch (JSONException e)
        {
            e.printStackTrace();
        }
        SensorAdapter2 adapter = new SensorAdapter2(Principale.this, label_name);
        listView.setAdapter(adapter);


    }

}

那么,如何在对象 url 处连接并更新同一行中该对象的数据?

【问题讨论】:

  • 您是否熟悉数据类以及如何使用它们?

标签: android json listview urlretrieve


【解决方案1】:

首先,像这样创建两个POJO

First.java

public class First {
    String id,url;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

Second.java

public class Second{
    String id,temp,time;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTemp() {
        return temp;
    }

    public void setTemp(String temp) {
        this.temp = temp;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }
}

然后在你的异步任务中 类 RetrieveFeedTask2 扩展 AsyncTask {

@Override
protected void onPreExecute() {
    super.onPreExecute();
}



protected String doInBackground(Void... urls) {
    String API_URL = "MyUrl";

    try {
        URL url = new URL(API_URL);
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
            StringBuilder stringBuilder = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                stringBuilder.append(line).append("\n");
            }
            bufferedReader.close();
            return stringBuilder.toString();
        }
        finally{
            urlConnection.disconnect();
        }
    }
    catch(Exception e) {
        Log.e("ERROR", e.getMessage(), e);
        return null;
    }
}

protected void onPostExecute(String response) {
    if(response == null) {
        response = "THERE WAS AN ERROR";
    }
    //            progressBar.setVisibility(View.GONE);
    Log.i("INFO", response);
     ArrayList<First> firstList = new ArrayList<>();
    try
    {

        JSONArray array=new JSONArray(response);

        for(int i = 0; i < array.length(); i++)
        {
            JSONObject obj = array.getJSONObject(i);

            String mysenso=obj.getString("id");
            String myurl=obj.getString("url");
            First first = new First();
            first.setId(mysenso);
            first.setUrl(myurl);
            firstList.add(first);

        }


    }
    catch (JSONException e)
    {
        e.printStackTrace();
    }
    SensorAdapter2 adapter = new SensorAdapter2(Principale.this, firstList);
    listView.setAdapter(adapter);


}

}

然后在你的适配器中

public class SensorAdapter extends BaseAdapter{
ArrayList<FirstList> firstList;

Context context;
LayoutInflater inflater;


public SensorAdapter2(Context c, ArrayList<FirstList> firstList)
{
    context = c;
    this.firstList=firstList;
   // temp=temp_array;
   // time=time_array;
    //labelno_array = no_array;
    inflater = LayoutInflater.from(context);
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return firstList.size();
}

@Override
public Object getItem(int position) {
    // TODO Auto-generated method stub
    return position;
}

@Override
public long getItemId(int position)
{
    // TODO Auto-generated method stub
    return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
    View v = convertView;
    Holder holder;
    // TODO Auto-generated method stub
    if (v == null) {
        v = inflater.inflate(R.layout.columns_sensor, null);
        holder = new Holder();
        holder.tv_labelname = (TextView)v.findViewById(R.id.idsensor);

        v.setTag(holder);
    } else {
        holder = (Holder) v.getTag();
    }


    holder.tv_labelname.setText(firstList.get(position).getId());

    return v;
}
public class Holder
{
    TextView tv_labelname,tv_labelno, tv_temp, tv_time;
}

这样你的第一部分就设置好了。现在您需要获取单击项目的值,然后需要从那里获取 url,然后将该 url 传递给另一个 asyntask 并在 Second.java 类中设置其值并从那里显示它。 要获取单击的项目,您需要在您查找列表视图的类中使用以下代码。

listView.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
        String url = (String) listView.getItemAtPosition(position);
        Toast.makeText(this,"You selected : " + url,Toast.LENGTH_SHORT).show();         
//here you will get the url and then now send it to another asynctask and parse it and set the value to Second.java and start another activity or fragment to display data from Second.java


    }
});

【讨论】:

    【解决方案2】:

    如果我在你的场景中,我会先检索数据(如果数据很小),然后再担心显示它们。

    如果数据很大,我会尝试检索额外的信息,同时尝试查看它

    那么让我们继续吧。

    提示:我假设您已经知道如何获取数据(基于“类 RetrieveFeedTask2” - 尽管您可能应该在返回之前断开连接)

    一般情况:

    在所有情况下您都需要
    1. 上课说

    class MyObject {
       String id,time,temp,url;
    }
    

    2。一种获取您的第一个 JSON 并将其存储在列表中的方法,例如

    public List&#60;MyObject&#62; fetchThenParseIntoList() {
       . . .
    }
    

    现在您将使用它来获取您的第一个 JSON 并将其解析为一个列表

    List&#60;MyObject&#62; myObjects = fetchThenParseIntoList()
    

    所以,现在您将拥有一个“MyObject”对象列表,其中仅包含 Id 和 url

    3. 可以给定对象以获取对象的额外信息的线程。说

    class ExtraInfoThread extends Thread {
        private MyObject myObject;
        public ExtraInfoThread(final MyObject myObject) {
            this.myObject = myObject
        }
    
        @Override
        public void run() {
            . . .
        }
    }
    

    案例 1:小数据(说少于 1000 个对象)

    循环每个对象并获取额外信息

    for(MyObject myObject: myObjects) {
        new ExtraInfoThread(myObject).start()
    }
    

    现在你有了一个包含所有数据的对象,你可以随意显示它

    案例 2:大数据

    仅在您尝试显示时调用线程以获取额外信息

    public View getView() {
      new ExtraInfoThread(myObject).start()
      . . .
    }
    

    如果您可以实现 JSON 的视图和获取,那么您肯定会实现您正在寻找的东西

    【讨论】:

      猜你喜欢
      • 2019-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多