I am trying to fetch json data and put it in a ListView. I was following a tutorial and tried to implement this. Problem is: the tutorial was based on AppCompatActivity and I am trying to add it in a Fragment (Tab):
public class InstallsTab extends Fragment{
ListView installs;
String url = "http://localhost/android.php";
ProgressBar dialog;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.installs_tab, container, false);
installs = rootView.findViewById(R.id.install_list);
dialog = new ProgressBar(getActivity().getApplicationContext());
dialog.setVisibility(View.VISIBLE);
StringRequest request = new StringRequest(url, new Response.Listener<String>() {
#Override
public void onResponse(String string) {
parseJsonData(string);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(getActivity().getApplicationContext(), "Some error occurred!!", Toast.LENGTH_SHORT).show();
dialog.setVisibility(View.GONE);
}
});
RequestQueue rQueue = Volley.newRequestQueue(getActivity().getApplicationContext());
rQueue.add(request);
return rootView;
}
void parseJsonData(String jsonString) {
try {
JSONObject object = new JSONObject(jsonString);
JSONArray fruitsArray = object.getJSONArray("fruits");
ArrayList al = new ArrayList();
for(int i = 0; i < fruitsArray.length(); ++i) {
al.add(fruitsArray.getString(i));
}
ArrayAdapter adapter = new ArrayAdapter(getActivity().getApplicationContext(), android.R.layout.simple_list_item_1, al);
installs.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
dialog.setVisibility(View.GONE);
}
}
And the app is crashing on run.
you have not initialize your array list proper
Use this
ArrayList<String> al = new ArrayList<>();
Instead of this
ArrayList al = new ArrayList();
EDIT
also change this use i++ instead of ++i
for(int i = 0; i < fruitsArray.length(); i++) {
al.add(fruitsArray.getString(i));
}
Related
I don't know why the items added to ArrayList won't populate ListView, I tried checking if items are indeed added to ArrayList but it shows it does.
You can check the image of the added items here
Here is my code. I'm using another xml for checkedtextview so my listview will display items with checkboxes.
ArrayList<String> symptomsListTest = new ArrayList<>();
ListView chl1;
String URL = "***********";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
addListItem();
chl1 = (ListView) findViewById(R.id.checklistSample);
chl1.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
ArrayAdapter<String> aa = new ArrayAdapter<String>(this, R.layout.symptoms_checklist, R.id.txt_title, symptomsListTest);
//ArrayAdapter<String> aa=new ArrayAdapter<String>(this,R.layout.symptoms_checklist, R.id.txt_title,symptomsListTest);
chl1.setAdapter(aa);
chl1.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
String selectedItem = ((TextView) view).getText().toString();
if(symptomsListTest.contains(selectedItem))
{
symptomsListTest.remove(selectedItem); //remove deselected item from the list of selected items
}
else
{
symptomsListTest.add(selectedItem); //add selected item to the list of selected items
}
}
});
}
public void addListItem()
{
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL,
new Response.Listener<String>()
{
#Override
public void onResponse(String response)
{
try
{
JSONObject jsonObject = new JSONObject(response);
String success = jsonObject.getString("success");
String message = jsonObject.getString("message");
JSONArray jsonArray = jsonObject.getJSONArray("read");
if(success.equals("1"))
{
for(int i = 0; i < jsonArray.length(); i++)
{
JSONObject object = jsonArray.getJSONObject(i);
String symptom = object.getString("symptom1");
symptomsListTest.add(symptom);
//Toast.makeText(SAMPLE.this, ""+symptom, Toast.LENGTH_SHORT).show();
//Toast.makeText(Login.this, ""+message+"\nYour name is: "+name+"\nYour email is: "+email,Toast.LENGTH_SHORT).show();
}
}
else
{
Toast.makeText(SAMPLE.this, ""+message,Toast.LENGTH_SHORT).show();
}
}
catch (JSONException e)
{
e.printStackTrace();
Toast.makeText(SAMPLE.this, e.toString(),Toast.LENGTH_SHORT).show();
}
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
Toast.makeText(SAMPLE.this, error.toString(),Toast.LENGTH_SHORT).show();
}
})
{
#Override
protected Map<String, String> getParams() throws AuthFailureError
{
Map<String, String> params = new HashMap<>();
String result="success";
params.put("result", result);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
You are executing an AsyncTask which is giving a response after sometime, meanwhile the code of listView and it's adapter is already executed. You just need to add one line after the for loop like this :-
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject object = jsonArray.getJSONObject(i);
String symptom = object.getString("symptom1");
symptomsListTest.add(symptom);
//Toast.makeText(SAMPLE.this, ""+symptom, Toast.LENGTH_SHORT).show();
//Toast.makeText(Login.this, ""+message+"\nYour name is: "+name+"\nYour email is: "+email,Toast.LENGTH_SHORT).show();
}
//** Add This line **
aa.notifyDataSetChanged();
And make sure your ArrayAdapter is declared global. Hope this helps.
Im having trouble fetching json data into a fragment and i need help. I dont know where im going wrong.
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.crime_fragment,container);
RecyclerView rv = (RecyclerView)v.findViewById(R.id.recyclerCrime);
//gives the context of the parent activity
rv.setLayoutManager(new LinearLayoutManager(this.getActivity()));
rv.setAdapter(new OtherAdapter(this.getActivity(),fetchJSon()));
MySingleton.getInstance(this.getContext()).addToRequestQueue(stringRequest);
return v;
}
private ArrayList<ListItem> fetchJSon() {
final ArrayList<ListItem> items = new ArrayList<ListItem>();
stringRequest = new StringRequest(Request.Method.GET, urlData, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
for(int i = 0;i<jsonArray.length();i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
ListItem listItem = new ListItem(jsonObject.getString("name"),jsonObject.getString("createdBy"),jsonObject.getString("imageUrl"));
items.add(listItem);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
return items;
}
StringRequest send an async request which means the response come back a few seconds later to the main thread. But in the meantime main thread reads the other code blocks.
So you must send the request first. You can fill the list when the response come successfully.
View v = inflater.inflate(R.layout.crime_fragment, container);
RecyclerView rv = (RecyclerView) v.findViewById(R.id.recyclerCrime);
//gives the context of the parent activity
fetchJSon(rv);
return v;
}
private void fetchJSon(final RecyclerView rv) {
final ArrayList < ListItem > items = new ArrayList < ListItem > ();
stringRequest = new StringRequest(Request.Method.GET, urlData, new Response.Listener < String > () {#
Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
ListItem listItem = new ListItem(jsonObject.getString("name"), jsonObject.getString("createdBy"), jsonObject.getString("imageUrl"));
items.add(listItem);
}
rv.setLayoutManager(new LinearLayoutManager(this.getActivity()));
rv.setAdapter(new OtherAdapter(this.getActivity(),items));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {#
Override
public void onErrorResponse(VolleyError error) {}
});
MySingleton.getInstance(this.getContext()).addToRequestQueue(stringRequest);
}
I'm using volley for web services. So, when I run the app each time it doesn't show anything in the list. But when I use debug, sometimes I got the list correctly. So here is the code.
It's like it insert the listItem on Listview before getting the data from json , i tried to put a wait() before the adapter but android studio don't accept it .
Is there anyone who had similar problem ?
public class listedeal_res extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listedeal_res);
Button ajouter=(Button) findViewById(R.id.ajouetres);
Intent i =getIntent();
final ListView maListView = (ListView) findViewById(R.id.liste_deal_res);
final int idres=i.getIntExtra("idres",0);
final boolean b =true;
ajouter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(listedeal_res.this,AjouterDeal.class);
intent.putExtra("idres",idres);
listedeal_res.this.startActivity(intent);
}
});
final ArrayList<HashMap<String, String>> listItem = new ArrayList<HashMap<String, String>>();
final HashMap<String, String> map;
map = new HashMap<String, String>();
Response.Listener<String> resp=new Response.Listener<String>()
{
#Override
public void onResponse (String response) {
try {
JSONArray jsonResponse = new JSONArray(response);
int i=0;
while (jsonResponse.getJSONArray(i)!=null)
{
while (jsonResponse.getJSONArray(i)!=null)
{
map.put("Nom",jsonResponse.getJSONArray(i).getString(2));
map.put("Restraurant",jsonResponse.getJSONArray(i).getString(0));
map.put("description",jsonResponse.getJSONArray(i).getString(1));
listItem.add(map);
i++;
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
drinkeat.drinkandeat.javas.liste_deal_res_req liste_deal_res_req= new liste_deal_res_req(idres+"",resp);
RequestQueue queue= Volley.newRequestQueue(listedeal_res.this);
queue.add(liste_deal_res_req );
SimpleAdapter mSchedule = new SimpleAdapter (this.getBaseContext(), listItem, R.layout.row_deal_user,
new String[] {"Nom", "Restraurant", "description"}, new int[] {R.id.titlerow, R.id.resteaurantnaamerow, R.id.descriptionrow});
maListView.setAdapter(mSchedule);
}
}
Add notifydatasetchange method to your adapter like below
public void onResponse (String response) {
try {
JSONArray jsonResponse = new JSONArray(response);
int i=0;
while (jsonResponse.getJSONArray(i)!=null)
{
while (jsonResponse.getJSONArray(i)!=null)
{
map.put("Nom",jsonResponse.getJSONArray(i).getString(2));
map.put("Restraurant",jsonResponse.getJSONArray(i).getString(0));
map.put("description",jsonResponse.getJSONArray(i).getString(1));
listItem.add(map);
i++;
}
}
mSchedule.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
can anyone suggest that how to create expandable list-view with Json data, i want to parse json data in my expandable list view, plss suggest how can i create
This is exactly what you looking for,you can parse and display data to ExpandableListview
See this : http://www.tutorialsbuzz.com/2015/02/android-expandable-listview-json-http.html
public class MainActivity extends Activity {
String url = "http://api.tutorialsbuzz.com/cricketworldcup2015/cricket.json";
ProgressDialog PD;
private ExpandListAdapter ExpAdapter;
private ExpandableListView ExpandList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ExpandList = (ExpandableListView) findViewById(R.id.exp_list);
PD = new ProgressDialog(this);
PD.setMessage("Loading.....");
PD.setCancelable(false);
makejsonobjreq();
}
private void makejsonobjreq() {
PD.show();
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Method.GET, url,
null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
ArrayList<Group> list = new ArrayList<Group>();
ArrayList<Child> ch_list;
try {
Iterator<String> key = response.keys();
while (key.hasNext()) {
String k = key.next();
Group gru = new Group();
gru.setName(k);
ch_list = new ArrayList<Child>();
JSONArray ja = response.getJSONArray(k);
for (int i = 0; i < ja.length(); i++) {
JSONObject jo = ja.getJSONObject(i);
Child ch = new Child();
ch.setName(jo.getString("name"));
ch.setImage(jo.getString("flag"));
ch_list.add(ch);
} // for loop end
gru.setItems(ch_list);
list.add(gru);
} // while loop end
ExpAdapter = new ExpandListAdapter(
MainActivity.this, list);
ExpandList.setAdapter(ExpAdapter);
PD.dismiss();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
PD.dismiss();
}
});
MyApplication.getInstance().addToReqQueue(jsonObjReq, "jreq");
}
}
I have a RecyclerView on my tabview fragment Activity. iam using arrayList to fill items on the recyclerview. Those JSON data are taken from this URL through volley library.
Here is my code
public class EditorsChoiceFragment extends Fragment {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private static String LOG_TAG = "EditorsChoiceFragment";
private String urlJsonArry = "http://checkthisphone.com/black.apps/get_apps/editor.php";
private ProgressDialog pDialog;
private String jsonResponse;
private static String TAG = EditorsChoiceFragment.class.getSimpleName();
private String appTitle;
private String appDescription;
private JSONArray appDetails=null;
ArrayList<DataObject> results = new ArrayList<DataObject>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.editor_choice_layout, container, false);
makeJsonArrayRequest();
pDialog = new ProgressDialog(getContext());
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
mRecyclerView = (RecyclerView)view.findViewById(R.id.my_recycler_view);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getContext());
mRecyclerView.setLayoutManager(mLayoutManager);
// mAdapter.notifyDataSetChanged();
makeJsonArrayRequest();
mAdapter = new MyRecyclerViewAdapter(results);
mAdapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
return view;
}
#Override
public void onResume() {
super.onResume();
/*((MyRecyclerViewAdapter) mAdapter).setOnItemClickListener(new MyRecyclerViewAdapter
.MyClickListener() {
#Override
public void onItemClick(int position, View v) {
Log.i(LOG_TAG, " Clicked on Item " + position);
}
});*/
}
private void makeJsonArrayRequest() {
// showpDialog();
JsonArrayRequest req = new JsonArrayRequest(urlJsonArry,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
try {
for (int i = 0; i < response.length(); i++) {
JSONObject person = (JSONObject) response.get(i);
String title = person.getString("title");
String description = person.getString("description");
DataObject obj = new DataObject(title, description);
results.add(i, obj);
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
Log.d(TAG, e.getMessage());
}
hidepDialog();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
Toast.makeText(getContext(),
error.getMessage(), Toast.LENGTH_SHORT).show();
hidepDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(req);
}
private void showpDialog() {
if (!pDialog.isShowing())
pDialog.show();
}
private void hidepDialog() {
if (pDialog.isShowing())
pDialog.dismiss();
}
}
Log file indicates data coming correctly but recyclerview is not updating. I have used .notifyDataSetChanged(); but still it shows blank. Please me to find the error..
I didn't view your codes each line by line but what I can suggest is refactor these codes as a method like here
public void setAdapter(ArrayList<DataObject> results){
mAdapter = new MyRecyclerViewAdapter(results);
mRecyclerView.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
}
Call this in onCreateView once and again call this after retrieving the results that means inside onResponse method like here
try {
for (int i = 0; i < response.length(); i++) {
JSONObject person = (JSONObject) response.get(i);
String title = person.getString("title");
String description = person.getString("description");
DataObject obj = new DataObject(title, description);
results.add(i, obj);
}
}
catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
Log.d(TAG, e.getMessage());
}
//Call method here
setAdapter(results)
Please remove notifyDataSetChanged from the below places.
makeJsonArrayRequest();
mAdapter = new MyRecyclerViewAdapter(results);
mAdapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
notifyDataSetChanged should be called when you have changed the data in your adapter and want the adapter to know that data has been changes. So in this case you will call it some data added to your results array list.
So once you add data to your results in makeJsonArrayRequest() call
mAdapter.notifyDataSetChanged();
after the for loop.
Also in your adapter constructor make sure you are not creating a new array list and are reusing results as follows.
ArrayList<DataObject> results;
MyRecyclerViewAdapter(results){
this.results = results;
}
Let me know if this works. If it does not please post your adapter code so i can further debug.
You should notify DatasetChanged in onRequestFinished method of volley.
in MainActivity.java
RequestListener listener;
listener = new RequestListener();
volley_queue.addRequestFinishedListener(listener);
RequestListner class
class RequestListener implements RequestQueue.RequestFinishedListener {
#Override
public void onRequestFinished(Request request) {
mAdapter.notifyDataSetChanged();
}
}
try {
for (int i = 0; i < response.length(); i++) {
JSONObject person = (JSONObject) response.get(i);
String title = person.getString("title");
String description = person.getString("description");
DataObject obj = new DataObject(title, description);
results.add(i, obj);
mAdapter.notifyItemInserted(i);
}
try
{
for (int i = 0; i < response.length(); i++)
{
JSONObject person = (JSONObject) response.get(i);
String title = person.getString("title");
String description = person.getString("description");
DataObject obj = new DataObject(title, description);
results.add(i, obj);
}
}
catch (JSONException e)
{
e.printStackTrace();
Toast.makeText(getContext(),"Error: " + e.getMessage(),Toast.LENGTH_LONG).show();
Log.d(TAG, e.getMessage());
}
mAdapter.notifyDataSetChanged();
hidepDialog();