【问题标题】:ListView displaying same dataListView 显示相同的数据
【发布时间】:2015-12-28 00:52:33
【问题描述】:

我有一个大型 JSON 数组。我正在从 JSON 数组读取数据并将其存储在列表视图中,但列表视图重复相同的数据。

即来自 JSON 的最后一个数据,而不是显示所有数据。

这是我的代码。

public class HistoryActivity extends AppCompatActivity {
private Toolbar toolbar;
String strServerResponse = null;
ProgressDialog nDialog;
Pojo pojo;
ArrayList<Pojo> history;
HistoryAdapter myAdapter;
ListView list;
public String date, inTime, outTime, inLat, inLong;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_history);
    toolbar = (Toolbar) findViewById(R.id.app_bar);
    toolbar.setTitle("History");
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    list = (ListView) findViewById(R.id.historyList);
    history = new ArrayList<Pojo>();
    new NetCheck().execute();

}

private class NetCheck extends AsyncTask<Void, Void, Void> {


    @Override
    protected void onPostExecute(Void result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);

        nDialog.dismiss();
        // TODO Auto-generated method stub
        myAdapter = new HistoryAdapter(HistoryActivity.this, history);
        list.setAdapter(myAdapter);
    }

    @Override
    protected Void doInBackground(Void... params) {
        // TODO Auto-generated method stub

        try {

            HttpClient httpClient = new DefaultHttpClient();

            HttpPost httpRequest = new HttpPost(

                    "http://myurl");
            httpRequest.setHeader("Content-Type", "application/json");
            SharedPreferences mmm = getSharedPreferences(
                    "MyPref", MODE_PRIVATE);

            String logempid = mmm.getString("id", null);

            JSONObject json = new JSONObject();

            json.put("empid", logempid);

            Log.e("JSON Object", json.toString());

            StringEntity se = new StringEntity(json.toString());

            se.setContentEncoding("UTF-8");
            se.setContentType("application/json");

            httpRequest.setEntity(se);
            HttpResponse httpRes = httpClient.execute(httpRequest);

            java.io.InputStream inputStream = httpRes.getEntity()
                    .getContent();
            InputStreamReader inputStreamReader = new InputStreamReader(
                    inputStream);

            BufferedReader reader = new BufferedReader(inputStreamReader);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            inputStream.close();
            strServerResponse = sb.toString();
            Log.e("Server Response", "" + strServerResponse.toString());

            if (strServerResponse != null) {
                try {

                    JSONArray arr = new JSONArray(strServerResponse);

                    for (int k = 0; k < arr.length(); k++) {

                        JSONObject jsonObj1 = arr.getJSONObject(k);

                        pojo = new Pojo();
                        date = jsonObj1.optString("login_date");
                        inTime = jsonObj1.optString("login_time");
                        outTime = jsonObj1.optString("logout_time");

                        Log.e("login time from server",""+inTime);
                        Log.e("login out from server",""+outTime);
                        Log.e("login date from server",""+date);
                        pojo.setDate(date);
                        pojo.setLoginTime(inTime);
                        pojo.setLogoutTime(outTime);

                        JSONArray subArrayLat = jsonObj1.getJSONArray("lati_long");
                        for (int i = 0; i < subArrayLat.length(); i++) {
                            String lat = subArrayLat.getJSONObject(i).getString("Latitude").toString();
                            String loong = subArrayLat.getJSONObject(i).getString("Longitude").toString();
                            Log.e("jsonarray lat", "" + lat);
                            Log.e("jsonarray longg", "" + loong);
                            pojo.setLat(lat);
                            pojo.setLong(loong);
                        }

                        history.add(pojo);
                    }

                } catch (JSONException e) {
                    e.printStackTrace();
               }
      }

这是适配器。

 public class HistoryAdapter extends BaseAdapter {
private Context activity;
TextView tv_date;
TextView tv_loginTime;
TextView tv_logoutTime;
TextView tv_details;
Pojo pojo;
ArrayList<Pojo> list;
private ArrayList<Pojo> arraylist = null;
public static LayoutInflater inflater;
private Context context;

public HistoryAdapter(Context context) {
    this.context = context;
}


public HistoryAdapter(Context a, ArrayList<Pojo> history) {
    // TODO Auto-generated constructor stub
    activity = a;
    list = history;
    inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    this.arraylist = new ArrayList<Pojo>();
    this.arraylist.addAll(list);

}

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

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

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    View v = convertView;


    v = inflater.inflate(R.layout.history_item, parent, false);
    pojo = list.get(position);
    tv_date = (TextView) v.findViewById(R.id.historyDate);
    tv_loginTime = (TextView) v.findViewById(R.id.historyLoginTime);
    tv_logoutTime = (TextView) v.findViewById(R.id.historyLogoutTime);
    tv_details = (TextView) v.findViewById(R.id.historyDetails);

    tv_date.setText(pojo.getDate());
    tv_loginTime.setText(pojo.getLoginTime());
    tv_logoutTime.setText(pojo.getLogoutTime());
    final String lat = pojo.getLat().toString();
    String longg = pojo.getLong().toString();
    Log.e("adapter latitude", "" + lat);
    Log.e("adapter longitude", "" + longg);
    tv_details.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent i = new Intent(context, MapActivity.class);
            i.putExtra("lat", "" + lat);
            i.putExtra("longg", "+longg");
            context.startActivity(i);
        }
    });

    return v;

}

 }

这是 JSON 数据

[
  {
    "login_time": "10:30:28",
    "logout_time": "10:31:47",
    "login_date": "2015- 09-30",
    "lati_long": [
      {
        "date_time": "2015:09:30  11:14:53",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:15:01",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:15:15",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:14:53",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:15:01",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:15:15",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:15:52",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:17:16",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      }
    ]
  },
  {
    "login_time": "10:42:56",
    "logout_time": "10:44:41",
    "login_date": "2015-09-30",
    "lati_long": [
      {
        "date_time": "2015:09:30 11:14:53",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:15:01",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:15:15",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:14:53",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:15:01",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:15:15",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:15:52",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:17:16",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:14:53",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:15:01",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:15:15",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:14:53",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:15:01",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:15:15",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:15:52",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      },
      {
        "date_time": "2015:09:30 11:17:16",
        "Latitude": "21.121776",
        "Longitude": "79.047563"
      }
    ]
  }
]

这里有什么问题吗?请帮帮我。

【问题讨论】:

  • 尝试创建 Pojo pojo;内循环
  • @Rajesh 它在循环内
  • 尝试在 onCreate 方法中设置适配器
  • put final Pojo pojo = list.get(position);在 getview 本地并检查
  • 你可以添加示例 Json 数据和 listView 的示例图片吗?

标签: android json android-listview baseadapter


【解决方案1】:

您已声明您的 CustomObject Pojo's 变量是全局变量。将其声明为局部变量

for (int k = 0; k < arr.length(); k++) {

         JSONObject jsonObj1 = arr.getJSONObject(k);
         Pojo pojo = new Pojo();
         date = jsonObj1.optString("login_date");
         inTime = jsonObj1.optString("login_time");
         outTime = jsonObj1.optString("logout_time");

         Log.e("login time from server",""+inTime);
         Log.e("login out from server",""+outTime);
         Log.e("login date from server",""+date);
         pojo.setDate(date);
         pojo.setLoginTime(inTime);
         pojo.setLogoutTime(outTime);

         JSONArray subArrayLat = jsonObj1.getJSONArray("lati_long");
         for (int i = 0; i < subArrayLat.length(); i++) {
                 String lat = subArrayLat.getJSONObject(i).getString("Latitude").toString();
                 String loong = subArrayLat.getJSONObject(i).getString("Longitude").toString();
                 Log.e("jsonarray lat", "" + lat);
                 Log.e("jsonarray longg", "" + loong);
                 pojo.setLat(lat);
                 pojo.setLong(loong);
          }

         history.add(pojo);
}

【讨论】:

    【解决方案2】:
    pojo = new Pojo();
    

    应该像Pojo pojo = new Pojo();这样在for循环中声明

    【讨论】:

      【解决方案3】:

      首先在myAdapter = new HistoryAdapter(HistoryActivity.this, history);这一行检查历史记录是否有正确的数据(不一样等)。

      其次,编辑你的适配器的getView函数

      替换这个:

      View v = convertView;
      v = inflater.inflate(R.layout.history_item, parent, false);
      

      到这里:

      View v = convertView;
      if(convertView == null) {
         v = inflater.inflate(R.layout.history_item, parent, false);
      }
      

      统一更新: 替换这个:

       inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
      

      到这里:

      inflater = LayoutInflater.from(a);
      

      请回复结果

      【讨论】:

      • 如何查看history是否有数据?
      • 您可以使用断点并在 Watches 窗口中查看变量值。
      【解决方案4】:

      我发现了你的问题。

      初始/外部JSONArray只有1 JSONObject如下图

      [
        { // object 1 start
          "login_time": "10:30:28",
          "logout_time": "10:31:47",
          "login_date": "2015- 09-30",
          "lati_long": [
            {
              "date_time": "2015:09:30  11:14:53",
              "Latitude": "21.121776",
              "Longitude": "79.047563"
            },
            {
              "date_time": "2015:09:30 11:15:01",
              "Latitude": "21.121776",
              "Longitude": "79.047563"
            },
            {
              "date_time": "2015:09:30 11:15:15",
              "Latitude": "21.121776",
              "Longitude": "79.047563"
            },
            {
              "date_time": "2015:09:30 11:14:53",
              "Latitude": "21.121776",
              "Longitude": "79.047563"
            },
            {
              "date_time": "2015:09:30 11:15:01",
              "Latitude": "21.121776",
              "Longitude": "79.047563"
            },
            {
              "date_time": "2015:09:30 11:15:15",
              "Latitude": "21.121776",
              "Longitude": "79.047563"
            },
            {
              "date_time": "2015:09:30 11:15:52",
              "Latitude": "21.121776",
              "Longitude": "79.047563"
            },
            {
              "date_time": "2015:09:30 11:17:16",
              "Latitude": "21.121776",
              "Longitude": "79.047563"
            }
          ]
        } // object 1 end
      ]
      

      因此,您的外部 for 循环 for (int k = 0; k &lt; arr.length(); k++) { 仅被调用一次,因此您的列表视图中仅提供 1 项。

      下面还评论了您只看到最新的 long 和 lat 值的原因

      for (int i = 0; i < subArrayLat.length(); i++) {
          String lat = subArrayLat.getJSONObject(i).getString("Latitude").toString();
          String loong = subArrayLat.getJSONObject(i).getString("Longitude").toString();
          Log.e("jsonarray lat", "" + lat);
          Log.e("jsonarray longg", "" + loong);
      
          // These two are called everytime but set the same pojo field
          // The result is that at the end of the loop, only the last set value is retained
          pojo.setLat(lat);
          pojo.setLong(loong);
      }
      

      这样你就有了一个具有最新 long 和 lat 值的 pojo 对象。

      按照我认为您想要实现的目标,我会说使用从解析服务器响应中的内部 json 数组获得的 'sub'arraylist 来填充您的列表视图。

      更新 - 更具体的答案

      在内部 for 循环中创建 pojo

      if (strServerResponse != null) {
          try {
      
          JSONArray arr = new JSONArray(strServerResponse);
      
          for (int k = 0; k < arr.length(); k++) {
      
              JSONObject jsonObj1 = arr.getJSONObject(k);
      
              // Comment these out:
      
              //1 pojo = new Pojo();
              date = jsonObj1.optString("login_date");
              inTime = jsonObj1.optString("login_time");
              outTime = jsonObj1.optString("logout_time");
      
              Log.e("login time from server",""+inTime);
              Log.e("login out from server",""+outTime);
              Log.e("login date from server",""+date);
              //2 pojo.setDate(date);
              //3 pojo.setLoginTime(inTime);
              //4 pojo.setLogoutTime(outTime);
      
              JSONArray subArrayLat = jsonObj1.getJSONArray("lati_long");
              for (int i = 0; i < subArrayLat.length(); i++) {
      
                  // And put them here
      
                  pojo = new Pojo();
      
                  pojo.setDate(date);
                  pojo.setLoginTime(inTime);
                  pojo.setLogoutTime(outTime);
      
                  String lat = subArrayLat.getJSONObject(i).getString("Latitude").toString();
                  String loong = subArrayLat.getJSONObject(i).getString("Longitude").toString();
                  Log.e("jsonarray lat", "" + lat);
                  Log.e("jsonarray longg", "" + loong);
                  pojo.setLat(lat);
                  pojo.setLong(loong);
      
                  // Same with this too
                  history.add(pojo);
              }
      
              // history.add(pojo);
          }
      }  
      

      【讨论】:

      • 我必须在列表视图中显示 login_time、logout_time、login_date。这些条目有多个
      • 更新了我的答案以反映快速修复
      • 应该的。我检查了你代码的每一行,这是唯一相关的问题。您是否在进行其他一些更改后进行了此更改?将您的代码恢复为您发布问题时的状态并尝试一下。
      【解决方案5】:

      将此代码放入您的 getView()

      View v = convertView;
          ViewHolder holder;
      
          v = inflater.inflate(R.layout.history_item, parent, false);
          if(v==null)
          {
              holder=new ViewHolder();
              pojo = list.get(position);
              holder.date = (TextView) v.findViewById(R.id.historyDate);
              holder.logintime = (TextView) v.findViewById(R.id.historyLoginTime);
              holder.lougouttime = (TextView) v.findViewById(R.id.historyLogoutTime);
              holder.details = (TextView) v.findViewById(R.id.historyDetails);
              v.setTag(holder);
          }else{
              holder=(ViewHolder)v.getTag();
          }
          holder.date.setText(pojo.getDate());
          holder.logintime.setText(pojo.getLoginTime());
          holder.lougouttime.setText(pojo.getLogoutTime());
          final String lat = pojo.getLat().toString();
          String longg = pojo.getLong().toString();
          Log.e("adapter latitude", "" + lat);
          Log.e("adapter longitude", "" + longg);
          holder.details .setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  Intent i = new Intent(context, MapActivity.class);
                  i.putExtra("lat", "" + lat);
                  i.putExtra("longg", "+longg");
                  context.startActivity(i);
              }
          });
      
          return v;
      

      视图持有者类

      protected  class ViewHolder{
              TextView date,logintime,lougouttime,details;
      
          }
      

      将此粘贴​​到您的适配器类中

      【讨论】:

        【解决方案6】:

        在你的情况下应该有一些改变

        第一 [Pojo类]

        更改 Pojo 类定义以将纬度和经度存储在列表中

        class Pojo{
           List<String> lat;
           List<String> longi;
        
           private List<String> getLat(){
               return this.lat;
           }
        
           private List<String> getLongi(){
               return this.longi;  
           }
        
           private void setLat(List<String> lat){
             this.lat = lat;
           }
        
           private void setLongi(List<String> longi){
            this.longi = longi;
        
           }
        

        第二[For循环逻辑]

        List<String> lati = new ArrayList<String>();
        List<String> longi = new ArrayList<String>();
          for (int i = 0; i < subArrayLat.length(); i++) {
                 String lat = subArrayLat.getJSONObject(i).getString("Latitude").toString();
                 String loong = subArrayLat.getJSONObject(i).getString("Longitude").toString();
                 lati.add(lat);
                 longi.add(loong);
           }
            pojo.setLat(lati);//adding latitude list
            pojo.setLongi(longi); //adding longitude list
        

        第三 [内部getview]

        通过以下方式访问这些列表

        List<String> lat = pojo.getLat();
        List<String> longg = pojo.getLongi();
        

        希望对您有所帮助!

        【讨论】:

        • @DroidwalaThanku...但我在 lati.add(lat) 处遇到指针异常;
        • 只需使用.. List lati = new ArrayList() & List longi = new ArrayList; ...在答案中完成编辑:)
        • 当你说它不工作时..你在 getview 中使用新的纬度和长列表值吗?
        • 你能发布你的代码吗..你是如何在 onclick 中使用它的?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多