Json Parsing Android in Listview - android

I am working on application in which i am getting list of my history using pubnub which contains message and time token. The Original Json string is given below:
[[{"message":"hdjcjcjjckckckckvkckckck","timetoken":14151866297757284},{"message":"ufjfjfjcjfjchfjdhwjroritkgjcj","timetoken":14151869212145693},{"message":"qMobile","timetoken":14152601234812083}],14151866297757284,14152601234812083]
After using following method i have get the following Json String in JSONObject c.
{"message":"hdjcjcjjckckckckvkckckck","timetoken":14151866297757284}
pubnub.history(channel, true, 100, new Callback() {
#Override
public void successCallback(String channel,
Object message) {
notifyUser("HISTORY : " + message);
Log.i("Received msg : ", message.toString()); //<==== receiving Messages here
try {
JSONArray jsonObj = new JSONArray(message.toString());
JSONArray jArray = new JSONArray(jsonObj.get(0).toString());
for (int i = 0; i < jArray.length(); i++) {
JSONObject c = jArray.getJSONObject(i);
String messageString=c.getString("message");
String timeString=c.getString("timetoken");
String abc = timeString;
}
}
Now i just want to display my each Json Object in ListView like this
message:dsfdsvsfvdfvfdvdvgd
timetoken:14132423414141
message:dsfwfwefwedcsfsw
timetoken:21431353153252
message:dthfjtyhnfgvb
timetoken:68624526246
Thanks in advance.

Declare one ArrayList of hashmap like below:
ArrayList<HashMap<String,String>> data= new ArrayList<HashMap<String,String>>();
HashMap<String,String> jsonData;
private EfficientAdapter adapter;
//In your onCreate() method, just initialize your adapter.
adapter = new EfficientAdapter(this);
Now, inside this for loop:
for (int i = 0; i < jArray.length(); i++) {
jsonData=new HashMap<String,String>();
JSONObject c = jArray.getJSONObject(i);
String messageString=c.getString("message");
String timeString=c.getString("timetoken");
String abc = timeString;
jsonData.put("message",messageString);
jsonData.put("timeStamp",timeString);
data.add(jsonData);
}
YOURLISTVIEW.setAdapter(adapter);
//List Adapter code:
private class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private Context context;
public EfficientAdapter(Context context) {
mInflater = LayoutInflater.from(context);
this.context = context;
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int arg0) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.YOUR LAYOUT FILE TO SHOW MESSAGE AND TIME, null);
//Just create one xml in layout folder and give that layout file name like R.layout.list_item.
holder = new ViewHolder();
holder.txtMessage = (TextView) convertView.findViewById(R.id.txtMessage);
holder.txtTimestamp = (TextView) convertView.findViewById(R.id.txtTimestamp);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtMessage.setText(data.get(position).get("message"));
holder.txtTimestamp.setText(data.get(position).get("timeStamp"));
convertView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//your list click event here
}
});
return convertView;
}
class ViewHolder {
TextView txtMessage;
TextView txtTimestamp;
}
}

A better option is to use GSON, it will save your time in the future with json parsing.
Download gson and add it to your project http://search.maven.org/#artifactdetails%7Ccom.google.code.gson%7Cgson%7C2.3%7Cjar
Paste your json - http://www.jsonschema2pojo.org/, and make a java class representation.
Use your json String (or Reader), your created class (in point 2.) and get a object that has all the values that the json has -
Gson gson = new Gson();
yourObject = gson.fromJson(yourJsonString, yourObject.class);
And then use this object inside your adapter. For example - message = yourObject.get(position).getMessage();

Related

App get crashed when trying to display Data through listview

I'm trying to get data using retrofit2 and display those data using a list passing through as a parameter of Custom adapter. When I store data in a List in onResponse() method, in onResponse() method list have some value. But in oncreate() method its give me null. Though, I declared List as global. When I run the app sometimes its display nothing and sometimes app get crash. I know it's sounds like crazy. But it's happen. so, I want to know, what's wrong with my Code? how can I display data in listview?
Forgive me if something wrong with my question pattern yet this my maiden question at this site.
MainActivity`
public class LaboratoryValues extends AppCompatActivity {
public List<Data> productList = null;
List<Data>arrayList = null;
int size;
String st;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_laboratory_values);
//productList = new ArrayList<Data>();
getInvestigation();
for(int i =0; i < size; i++){
st = arrayList.get(i).getName();
}
System.out.println("Name : "+st);//here print Name : null
ListView lview = (ListView) findViewById(R.id.listview);
ListviewAdapter adapter = new ListviewAdapter(this, arrayList);
lview.setAdapter(adapter);
}
private void getInvestigation() {
/* final ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setCancelable(false); // set cancelable to false
progressDialog.setMessage("Please Wait"); // set body
progressDialog.show(); // show progress dialog*/
ApiInterface apiService =
Api.getClient(ApiInterface.BASE_URL).create(ApiInterface.class);
Call<Investigation> investigationCall = apiService.getInvestigation();
investigationCall.enqueue(new Callback<Investigation>() {
#Override
public void onResponse(Call<Investigation> call, Response<Investigation> response) {
arrayList = response.body().getData();
//productList.addAll(arrayList);
size = response.body().getData().size();
for (int i = 0; i < size; i++) {
System.out.println("Name : " + arrayList.get(i).getName());//here printing Name is ok
}
}
#Override
public void onFailure(Call<Investigation> call, Throwable t) {
Toast.makeText(getApplicationContext(),"data list is empty",Toast.LENGTH_LONG).show();
}
});
}
}
Custom Adapter (listviewAdapter)
public class ListviewAdapter extends BaseAdapter {
public List<Data> productList;
Activity activity;
//Context mContext;
public ListviewAdapter(Activity activity, List<Data> productList) {
super();
this.activity = activity;
this.productList = productList;
}
#Override
public int getCount() {
return productList.size();
}
#Override
public Object getItem(int position) {
return productList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView name;
TextView normal_finding;
TextView increased;
TextView decreased;
TextView others;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
LayoutInflater inflater = activity.getLayoutInflater();
if (convertView == null) {
convertView = inflater.inflate(R.layout.listview_row, null);
holder = new ViewHolder();
holder.name = convertView.findViewById(R.id.name);
holder.normal_finding =convertView.findViewById(R.id.normal_finding);
holder.increased = convertView.findViewById(R.id.increased);
holder.decreased = convertView.findViewById(R.id.decreased);
holder.others =convertView.findViewById(R.id.others);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Data item = productList.get(position) ;
holder.name.setText(item.getName());
System.out.println("holderName : "+item.getName() );
holder.normal_finding.setText(item.getNormal_finding());
System.out.println("holderName : "+item.getNormal_finding() );
holder.increased.setText(item.getIncreased());
holder.decreased.setText(item.getDecreased());
holder.others.setText(item.getOthers());
return convertView;
}
}
It's perfectly normal that it dosent work.
putting your method getInvistigation() before the loop does not mean that the response of your request was done
Calling a webservice creates another thread that waits for the server to send the response, sometimes the response takes time depends from the server and the latency of your internet connection.
you simply need to place the treatment (the loop and adapter) inside getInvistagion after getting the data.

NotifyDatasetChanged not working on a custom Adapter

I'm trying to fill a ListView with a custom Adapter.
I want to use the NotifyDatasetChanged to refresh the layout, but it doesn't work.
I retrieve some JSON data from an HTTP request, and I manipulate the result string then I fill the ListView
What's wrong in my code?
UPDATE THE CODE (For the advice)
public class CalendarioFragment extends Fragment {
ListView listView;
ArrayList<Calendario> calenList;
CalendarioAdapter adapter;
String json;
ArrayList<String> arrayId = new ArrayList<String>();
ArrayList<String> arrayData = new ArrayList<String>();
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.calendario_layout, null);
listView = (ListView) view.findViewById(R.id.listCale);
listView.setEmptyView(view.findViewById(R.id.emptyElement));
calenList = new ArrayList<Calendario>();
adapter = new CalendarioAdapter(getActivity(), calenList);
listView.setAdapter(adapter);
execQuery("query", "0");
return view;
}
private void execQuery(final String query, final String taskId) {
final MyAsyncTask asyncTask = new MyAsyncTask(new AsyncResponse() {
#Override
public void onTaskCompleted(String output) {
if (output == null) {
Toast.makeText(getActivity(), "Nessuna connessione internet attiva!", Toast.LENGTH_SHORT).show();
} else {
json = output;
try {
ParseJson();
calenList.clear();
String[] ids = arrayId.toArray(new String[arrayId.size()]);
String[] date = arrayData.toArray(new String[arrayData.size()]);
for (int i = 0; i < ids.length; i++) {
Calendario calendario = new Calendario();
calendario.setId(ids[i]);
calendario.setData(date[i]);
calenList.add(calendario);
adapter.updateData(calenList);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, getActivity());
asyncTask.execute(query, taskId);
}
private void ParseJson() throws JSONException {
JSONObject jsonObject = new JSONObject(json);
JSONArray jsonArray = jsonObject.getJSONArray("risposta");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject JO = jsonArray.getJSONObject(i);
arrayId.add(JO.getString("ID"));
arrayData.add(JO.getString("DATA"));
}
}
}
This is the CustomAdapterCode:
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
public class CalendarioAdapter extends BaseAdapter {
private ArrayList listData;
private LayoutInflater layoutInflater;
final static String TAG = "sb.dl";
public CalendarioAdapter(Context context, ArrayList listData) {
Log.d(TAG, "CalendarioAdapter");
this.listData = listData;
layoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.d(TAG, "CalendarioAdapter.getView");
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.calendario_row_layout, null);
holder = new ViewHolder();
holder.edId = (TextView) convertView.findViewById(R.id.edId);
holder.edData = (TextView) convertView.findViewById(R.id.edData);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Calendario newsItem = (Calendario) listData.get(position);
holder.edId.setText(newsItem.getId());
holder.edData.setText(newsItem.getData());
return convertView;
}
static class ViewHolder {
TextView edId;
TextView edData;
}
public void updateData(ArrayList<Calendario> updatedData) {
listData = updatedData;
this.notifyDataSetChanged();
}
}
Problem:
listData is the variable inside of the Cale class. When you set new values to it the variable inly in Cale class is getting modified. The rest of the code where the duplicate of the data was set are not getting changed. In other words the data inside of the CalendarioAdapter is not updated when you are modifing the listData which is in Cale class.
Solution:
You need to pass the updated listData to adapter again after it was changed. In order to do that you need to create a method inside of your CalendarioAdapter adapter which will be responsible for updating the data inside of adapter and then calling notifyDataSetChanged().
Add this method to your CalendarioAdapter adapter:
public void updateData(ArrayList<Calendario> updatedData) {
listDataInYourAdapter = newData;
this.notifyDataSetChanged();
}
Now to use that method, in your Cale class replace this:
adapter.notifyDataSetChanged();
with this:
updateData(listData);
After these three lines
listData = new ArrayList<Calendario>();
adapter = new CalendarioAdapter(getActivity(), listData);
listView.setAdapter(adapter);
You should never re-assign listData. Once you do, the reference of the list within the adapter has become detached, and it no longer can be notified for updates.
So, instead, you need to clear(), then addAll() on the list.
For example,
ParseJson(); // You should really pass 'output' as a parameter here
listData = getListData(); // Don't re-assign
Do this instead, then notify
ParseJson();
listData.clear();
listData.addAll(getListData());
Alternatively, why call listData.addAll(getListData());? You already have this method which does the correct thing of clearing, adding, and notifying.
private ArrayList<Calendario> getListData() {
listData.clear(); // Cleared
String[] ids = arrayId.toArray(new String[arrayId.size()]);
String[] date = arrayData.toArray(new String[arrayData.size()]);
for (int i = 0; i < ids.length; i++) {
Calendario calendario = new Calendario();
calendario.setId(ids[i]);
calendario.setData(date[i]);
listData.add(calendario); // Adding
}
adapter.notifyDataSetChanged(); // Notify
return listData;
}
So, realistically, you only need these two lines in the AsyncTask (and again, should add output as a parameter of ParseJson, you don't need to save the json = output).
ParseJson();
getListData();
I solved!
That was a stupid thing!
In parseJson sub, I need to clear the arrays before to fill them!
private void ParseJson() throws JSONException {
JSONObject jsonObject = new JSONObject(json);
JSONArray jsonArray = jsonObject.getJSONArray("risposta");
arrayId.clear();
arrayData.clear();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject JO = jsonArray.getJSONObject(i);
arrayId.add(JO.getString("ID"));
arrayData.add(JO.getString("DATA"));
}
}
Reassign the list again-> this is not recommended behavior.
Here is the correct way how to do it:
Inside the adapter: public void update(List<ItemMessage> updatedList){
list.clear();
list.addAll(updatedList);
notifyDataSetChanged();}
Don't forget to do it using a Handler

Whole listview gets duplicated

I've a listview which shows values from web service. Its fine when it loads the listview. But when I click on any item to open a new fragment (which shows details of the item) and get back to the same listview, its items doubles everytime. For example, if I have (in original) 5 items in total. Then when I get back from the fragment, the total count will be 10, then 15 and so on. It means the app is adding all items again and again. I searched for the solution and did what were the general solution like adapter.notifyDataSetChanged() but its still gets duplicated. If anyone can show me the problem, I would be grateful.
public class CustomListAdapter extends ArrayAdapter<Model> {
private Context mContext;
int resource;
private ArrayList<Model> mListData = new ArrayList<Model>();
public CustomListAdapter(Context mContext, int resource, ArrayList<Model> mListData) {
super(mContext, resource, mListData);
this.resource = resource;
this.mContext = mContext;
this.mListData = mListData;
}
public void setListData(ArrayList<Model> mListData) {
this.mListData = mListData;
notifyDataSetChanged();
}
#Override
public int getCount() {
return super.getCount();
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
View v = convertView;
final ViewHolder holder;
if (v == null) {
holder = new ViewHolder();
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
v = inflater.inflate(resource, parent, false);
holder.custname = (TextView) v.findViewById(R.id.cust_name);
holder.date = (TextView) v.findViewById(R.id.date);
holder.staffname = (TextView) v.findViewById(R.id.staff_name);
holder.time = (TextView) v.findViewById(R.id.time);
holder.service = (TextView) v.findViewById(R.id.service);
holder.refid = (TextView) v.findViewById(R.id.refid);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
final Model item = mListData.get(position);
holder.custname.setText(item.getCustname());
holder.date.setText(item.getDate());
holder.staffname.setText(item.getStaffname());
holder.time.setText(item.getTime());
holder.service.setText(item.getService());
holder.refid.setText(item.getRefid());
return v;
}
class ViewHolder {
TextView custname, date, staffname, time, service, refid;
}
}
public class ListFrag extends Fragment{
private SwipeMenuListView listView;
private CustomListAdapter adapter;
private CShowProgress cShowProgress;
private SQLiteHandler db;
private String uid, bookingId;
private ArrayList<Model> arrayList = new ArrayList<>();
private static final String BOOKED_LIST = "http://192.168.220.13/android/showbookinglist";
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.listfrag, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
listView = (SwipeMenuListView)view.findViewById(R.id.list);
db = new SQLiteHandler(getActivity());
cShowProgress = CShowProgress.getInstance();
fetchDetails();
adapter = new CustomListAdapter(getActivity(), R.layout.listitem, arrayList);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String a = arrayList.get(i).getCustname();
String b = arrayList.get(i).getStaffname();
String c = arrayList.get(i).getService();
String d = arrayList.get(i).getDate();
String e = arrayList.get(i).getTime();
String f = arrayList.get(i).getRefid();
String g = arrayList.get(i).getEmail();
String h = arrayList.get(i).getServprice();
String j = arrayList.get(i).getSpeclprice();
String k = arrayList.get(i).getStatus();
db.addDetails(a, b, c, d, e, f, g, h, j, k);
DetailsView details = new DetailsView();
((Bookings)getActivity()).replaceFragment(details);
}
});
}
private void fetchDetails() {
cShowProgress.showProgress(getActivity());
StringRequest stringRequest = new StringRequest(Request.Method.POST, BOOKED_LIST,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
cShowProgress.hideProgress();
try {
JSONArray jsonArray = new JSONArray(response);
for(int i=0; i<jsonArray.length(); i++){
JSONObject obj = jsonArray.getJSONObject(i);
Model model = new Model();
model.setCustname(obj.getString("customername"));
model.setDate(obj.getString("staffdate"));
model.setStaffname(obj.getString("staffname")+"(Staff)");
model.setTime(obj.getString("stafftime"));
model.setService(obj.getString("servicename"));
model.setRefid(obj.getString("booking_referenceid"));
model.setEmail(obj.getString("customeremail"));
model.setServprice(obj.getString("serviceprice"));
model.setSpeclprice(obj.getString("specialprice"));
model.setStatus(obj.getString("status"));
model.setBookid(obj.getString("bookingid"));
arrayList.add(model);
}
adapter.notifyDataSetChanged();
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(getActivity(), "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), "VolleyError" + error.toString(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("spaid", "145");
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
requestQueue.add(stringRequest);
}
}
try to change it as.. B'coz you are adding the elements in previously created list.. So you have to clear it.
private void fetchDetails() {
if(arrayList!=null )arrayList.clear(); // this line
cShowProgress.showProgress(getActivity());
The thing is that when you get back to the fragment it is recreated and onViewCreated is called again. From there you call again fetchDetails() and then your are adding the whole List for a second time to the adapter. So you can clear the list before fetchDetails() or just if you have to fetch them again.
change your try - catch block of onResponse method by below.
try {
JSONArray jsonArray = new JSONArray(response);
arrayList = new ArrayList<>();
for(int i=0; i<jsonArray.length(); i++)
{
JSONObject obj = jsonArray.getJSONObject(i);
Model model = new Model();
model.setCustname(obj.getString("customername"));
model.setDate(obj.getString("staffdate"));
model.setStaffname(obj.getString("staffname")+"(Staff)");
model.setTime(obj.getString("stafftime"));
model.setService(obj.getString("servicename"));
model.setRefid(obj.getString("booking_referenceid"));
model.setEmail(obj.getString("customeremail"));
model.setServprice(obj.getString("serviceprice"));
model.setSpeclprice(obj.getString("specialprice"));
model.setStatus(obj.getString("status"));
model.setBookid(obj.getString("bookingid"));
arrayList.add(model);
}
adapter.notifyDataSetChanged();
This is happening because you are not clearing the arrayList. Due to this every time that you construct the array and the adapter, you are adding the elements into an array that already has elements.
That why you have 5, then 10, then 15 and so on..
Clear the array before adding new elements
arrayList.clear();
Or program another strategy like:
Not populate the array every time you return to the fragment.
Check if he element existe before add it into the array.

Android adapter for a custom layout listview based on a class

I have a class that looks like this:
public class Vizita {
public int icon;
public String titlu;
public String loc;
public String idviz;
public Vizita(){
super();
}
public Vizita(int icon, String titlu, String loc, String idviz) {
super();
this.icon = icon;
this.titlu = titlu;
this.loc = loc;
this.idviz = idviz;
}
}
I use AsyncTask to retrieve a JSON array from a PHP. All works perfect for simple layout of listview. But I want to use a more complex layout, so I designed one that uses all 4 values from Vizita.class above. But I do not know how to set the adapter for it, because the way I try it, gives me errors.
Of course I am trying to do it in onPostExecute, like this:
public class MyActivity extends Activity {
{...}
JSONArray lststat;
{...}
public JSONArray liststatus() {
JSONArray jdata=post.getserverdataX(url_connectX);
return jdata;
}
class asyncpost extends AsyncTask< String, String, String > {
Vizita weather_data[];
....
protected void onPostExecute(String result) {
VizitaAdapter adapter = new VizitaAdapter(MyActivity.this,R.layout.listview_item_row, weather_data);
myListView.setAdapter(adapter);
...}
And in doInBackground I am processing the JSON like this:
lststat = liststatus();
JSONObject json_data;
try {
int length = lststat.length();
Vizita weather_data[] = new Vizita[length];
for (int i = 0; i < length; i++)
{
json_data = lststat.getJSONObject(i);
weather_data[i].titlu =json_data.getString("clientnume");
weather_data[i].idviz =json_data.getString("idvizite");
weather_data[i].loc =json_data.getString("localitate");
}
} catch (Exception e) {
Log.e(null, e.toString());
}
where liststatus() is where I call the asyncTask to retrieve the needed JSONArray.
But I receive a java.lang.NullPointerException in the for loop (if I comment the setAdapter line).
I assume I did not initialize the weather_data array properly ?!?!?
If I (uncomment) set the adapter in onPostExecute I receive a crash error "Force close"
I do not receive any errors in the IDE, seeming that the syntaxes are fine.
Please tell me what am I doing wrong? And how can I fix it?
The code for the VizitaAdapter is bellow
public class VizitaAdapter extends ArrayAdapter<Vizita>{
Context context;
int layoutResourceId;
Vizita data[] = null;
public VizitaAdapter(Context context, int layoutResourceId, Vizita[] data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
WeatherHolder holder = null;
if(row == null)
{
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new WeatherHolder();
holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
holder.txtLoco = (TextView)row.findViewById(R.id.txtLocalitate);
holder.txtIdviz = (TextView)row.findViewById(R.id.txtIdVizite);
row.setTag(holder);
}
else
{
holder = (WeatherHolder)row.getTag();
}
Vizita weather = data[position];
holder.txtTitle.setText(weather.titlu);
holder.txtLoco.setText(weather.loc);
holder.txtIdviz.setText(weather.idviz);
holder.imgIcon.setImageResource(weather.icon);
return row;
}
static class WeatherHolder
{
ImageView imgIcon;
TextView txtTitle;
TextView txtLoco;
TextView txtIdviz;
}
}
Probably you forgot initialize Vizita object in loop:
json_data = lststat.getJSONObject(i);
weather_data[i] = new Vizita();
weather_data[i].titlu =json_data.getString("clientnume");
weather_data[i].idviz =json_data.getString("idvizite");
weather_data[i].loc =json_data.getString("localitate");

problem with an adapter in android app

I have an app in android in which I return some data from facebook(some names and id's) and right after I return this data I use an adapter to set all this names in a list view.
All this work I do it in onCreate().First time I use a method getData() to return some names from facebook and after that I call for the adapter.
The problem is that getData() returns in an array of Strings the names that will be setup up with the adapter.Now,the adapter called does some processing on this array.
How I return these names from web this part works slowly and the array is not filled in time so when the adapter gets called the array is still empty and I get force close.
this is how I do it:
private String[] mStrings;
private String[] fName;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.invitefriends);
....................
/*In here I request for friends from facebook which ae set up in an array*/
mAsyncRunner.request("me/friends", new SampleRequestListener());
/*here is the adapter that processes the arrays returned in SampleRequestListener*/
adapter=new LazyAdapter1(this, mStrings,fName);
list.setAdapter(adapter);
}
/Here is the SampleRequestListener that does return from facebook the names in some arrays/
public class SampleRequestListener extends BaseRequestListener{
int i;
public void onComplete(final String response, final Object state){
friends = new ArrayList<Friends>();
try{
Log.d("facebook-example","Response: " + response.toString());
JSONObject json = Util.parseJson(response);
JSONArray array = json.optJSONArray("data");
if(array!=null){
for(int i=0; i<array.length(); i++)
{
String name=array.getJSONObject(i).getString("name");
String id= array.getJSONObject(i).getString("id");
Friends f=new Friends(name,id);
friends.add(f);
Log.d(name,id);
}
mStrings = new String[friends.size()];
for(int i=0; i< mStrings.length; i++){
mStrings[i] = "http://graph.facebook.com/"+friends.get(i).getId()+"/picture?type=small";
}
fName = new String[friends.size()];
for(int i=0; i<friends.size(); i++)
{
fName[i]=friends.get(i).getName();
}
}
}
catch(JSONException e)
{
//do nothing
}
catch(FacebookError e)
{
e.getMessage();
}
}
}
And finally here is the adapter's body:
public class LazyAdapter1 extends BaseAdapter {
private Activity activity;
private String[] data;
private String[] nume;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;
public LazyAdapter1(Activity a, String[] d, String[] f) {
activity = a;
data=d;
nume=f;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return data.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public static class ViewHolder{
public TextView text;
public ImageView image;
}
public View getView(int position, View convertView, ViewGroup parent) {
//........
}
}
The problem is that mStrings[] and fName[] are not returned in time by the background thread so they are still empty when I try to act with the adapter on them.
So could someone tell how should I proceed for this thing to work right??Thanks
use the AsyncTask class and extend with your custom class.
this was good for getting the data in background process.
and when the data are fetched then set into the adapter
check this links
http://www.vogella.de/articles/AndroidPerformance/article.html
http://developer.android.com/reference/android/os/AsyncTask.html
http://www.xoriant.com/blog/mobile-application-development/android-async-task.html

Categories

Resources