问题
I have a large JSON array. I am reading the data from JSON array and storing it in a list view, But the list view repeats the same data.
i.e the last data from the JSON instead of displaying all the data.
Here is my code.
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();
}
}
Here is the adapter.
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;
}
}
This is JSON data
[
{
"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"
}
]
}
]
Is there anything wrong here? Please help me.
回答1:
You have declared Your CustomObject Pojo's variable is global variable. declare it as Local variable
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();
should be declared inside for loop like Pojo pojo = new Pojo();
回答3:
First of all check at this line myAdapter = new HistoryAdapter(HistoryActivity.this, history); that history has a right data (not same, etc).
Second, edit getView function of your adapter
Replace this:
View v = convertView;
v = inflater.inflate(R.layout.history_item, parent, false);
To this:
View v = convertView;
if(convertView == null) {
v = inflater.inflate(R.layout.history_item, parent, false);
}
UPD: Replace this:
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
To this:
inflater = LayoutInflater.from(a);
Please response about result
回答4:
I have discovered your problem.
The initial/outside JSONArray has only 1 JSONObject as shown below
[
{ // 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
]
Thus your outside for loop for (int k = 0; k < arr.length(); k++) { is called only once, thus giving you only 1 item in your List View.
Also the reason you're seeing only the latest long and lat values is commented below
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);
}
And so you have one pojo object with the latest long and lat values.
Going by what I think you want to achieve, I'll say use the 'sub'arraylist gotten from parsing the inner json array in server respone to populate your list view.
UPDATE - A more specific answer
Create the pojo inside the inner for loop
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);
}
}
回答5:
Put this code in your 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;
The view holder class
protected class ViewHolder{
TextView date,logintime,lougouttime,details;
}
paste this in your adapter class
回答6:
Few changes which should work in your case
First [Pojo Class]
Change Pojo class definition to store latitude and longitude in list
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;
}
Second[For loop logic]
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
Third [ Inside getview]
Access those list in following way
List<String> lat = pojo.getLat();
List<String> longg = pojo.getLongi();
Hope it helps!
来源:https://stackoverflow.com/questions/32862656/listview-displaying-same-data