JSON Array shows blank screen on android - android

I am fetching JSON Array and trying to show it in a list view. I debugged and got that I recieve the array as required but when i run my list view is blank on android screen. When I run no error is shown in syntax or while in emulator. Here is my code:
I have used volley to call the api and fetch json data.
DashBoard.java
public class Dashboard extends AppCompatActivity {
private RequestQueue queue;
ListView listView;
ArrayList<rowitem> arrayList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
queue = Volley.newRequestQueue(this);
listView = (ListView) findViewById(R.id.myListView);
arrayList = new ArrayList<>();
String url = "https://api.rootnet.in/covid19-in/stats/latest";
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Display the first 500 characters of the response string.
try {
JSONObject result = new JSONObject(response).getJSONObject("data");
JSONArray jsonArray = result.getJSONArray("regional");
for(int i=0; i<jsonArray.length(); i++)
{
JSONObject json_data = jsonArray.getJSONObject(i);
String location = json_data.getString("loc");
String totalcase = json_data.getString("totalConfirmed");
String recovered = json_data.getString("discharged");
String deaths = json_data.getString("deaths");
rowitem model = new rowitem();
model.setLocation(location);
model.setTotalcase(totalcase);
model.setRecovered(recovered);
model.setDeaths(deaths);
arrayList.add(model);
}
} catch (JSONException e) {
Toast.makeText(Dashboard.this, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(Dashboard.this, "Server is not responding (Covid-19 Tracker)", Toast.LENGTH_LONG).show();
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
customlistviewadapter adapter = new customlistviewadapter(this, arrayList);
listView.setAdapter(adapter);
}
}
customlistviewadapter.java
package com.example.maps;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.view.View;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
public class customlistviewadapter extends BaseAdapter {
Context context;
ArrayList<rowitem> arrayList;
public customlistviewadapter(Context context,ArrayList<rowitem> arrayList) {
this.context = context;
this.arrayList = arrayList;
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return arrayList.get(position);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.row, parent, false);
}
TextView location, totalcase, recovered, deaths;
location = (TextView) convertView.findViewById(R.id.location);
totalcase = (TextView) convertView.findViewById(R.id.cases);
recovered = (TextView) convertView.findViewById(R.id.healthy);
deaths = (TextView) convertView.findViewById(R.id.deaths);
location.setText(arrayList.get(position).getLocation());
totalcase.setText(arrayList.get(position).getTotalcase());
recovered.setText(arrayList.get(position).getRecovered());
deaths.setText(arrayList.get(position).getDeaths());
return convertView;
}
}

Related

Adapter for objects from JSON

I get data in JSON from API, and there are id and url. Now, i need to create a button "Add to favorites" for each image that i display. When i try to set adapter.setListener(this);, i get an error, because i can't use string format.
How can i resolve this problem? I spend 5 hours on this, and can't resolve it :(
MainActivity:
protected void onCreate(Bundle savedInstanceState) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.listItem);
favorites = findViewById(R.id.buttonFav);
catDetailsArrayList = new ArrayList<>();
myAdapter = new MyAdapter(MainActivity.this ,catDetailsArrayList);
searchbtn = findViewById(R.id.buttonSearch);
searchbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
catDetailsArrayList.clear();
myAdapter.notifyDataSetChanged();
displayCats();
}
});
});
}
private void displayCats() {
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, 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 jsonObject1 = jsonArray.getJSONObject(i);
String jsonCatUrl2 = jsonObject1.getString("url");
String jsonCatId2 = jsonObject1.getString("id");
CatDetails catDetails = new CatDetails();
catDetails.setUrl(jsonCatUrl2);
catDetails.setId(jsonCatId2);
catDetailsArrayList.add(catDetails);
}
listView.setAdapter(myAdapter);
myAdapter.notifyDataSetChanged();
} catch(JSONException e){
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),error.getMessage(),Toast.LENGTH_LONG).show();
}
});
requestQueue.add(stringRequest);
}
MyAdapter:
public class MyAdapter extends BaseAdapter {
public Activity activity;
public ArrayList<CatDetails> catDetailsArrayList;
public LayoutInflater inflater;
Button btn;
TextView idnr;
public MyAdapter(Activity activity, ArrayList<CatDetails> catDetailsArrayList) {
this.activity = activity;
this.catDetailsArrayList = catDetailsArrayList;
}
#Override
public Object getItem(int position) {
return catDetailsArrayList.get(position);
}
#Override
public long getItemId(int position) {
return (long)position;
}
#Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
if (inflater == null) {
inflater = this.activity.getLayoutInflater();
}
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_item, null);
}
ImageView imageView = convertView.findViewById(R.id.ImageView);
final CatDetails catDetails = this.catDetailsArrayList.get(position);
Picasso.get().load(catDetails.getUrl()).into(imageView);
idnr =convertView.findViewById(R.id.textView);
btn = convertView.findViewById(R.id.buttonFav);
final String id = catDetails.getId();
idnr.setText(catDetails.getId());
return convertView;
}
#Override
public int getCount() {
return this.catDetailsArrayList.size();
}
I display the id that i receive from server for each item, it's ok, but i don't know how to set the button "add to favorites" to works fine. It must receive item id (that i received from server) as a param, but id is in string format.
final String id = catDetails.getId();
change it to
final String id = Integer.toString(catDetails.getId());

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

ListView : List Item are repeating on scroll

I have a ListView in which i am showing some data. I am requesting the data from the server which is in the form of JSON. Also, the data is paginated.
When the API is called for the first time it is loading n items.
I have implemented the logic that after the list end is reached API would be call again to fetch n more data.
API Calls are working fine as I have seen the result in the Logcat.
The Issue is the ListView is not updating properly on scroll after the API has been called for the second time.
Eg: Suppose I am calling API to fetch 7 items at a time. Then in the ListView i would see something like this:
Item1
Item2
..
Item7
Item1
Item2
....
JsonObjectRequest jo = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject jsonObject) {
pDialog.dismiss();
pDialog = null;
try {
JSONArray ja = jsonObject.getJSONArray("resultset"); // id, title, content, guid
for (int i = 0; i < ja.length(); i++) {
JSONObject jo = ja.getJSONObject(i);
SearchListItem ri = new SearchListItem();
ri.setId(jo.getInt("id"));
ri.setTitle(jo.getString("title"));
ri.setContent(jo.getString("content"));
listy.add(ri);
}
} catch (JSONException ex) {
Toast.makeText(getApplicationContext(), "json ex" + ex.getMessage(), Toast.LENGTH_SHORT).show();
ex.printStackTrace();
}
searchAdapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
pDialog.dismiss();
pDialog = null;
Log.d(TAG, "!!!! ERROR " + volleyError.getMessage());
}
});
//Toast.makeText(ListActivity.this, jo.toString().toCharArray(), Toast.LENGTH_SHORT).show();
AppController.getInstance().addToRequestQueue(jo);
//Adapter
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.Toast;
import com.o.R;
import com.o.SearchListItem;
import java.util.List;
public class SearchListAdapter extends BaseAdapter {
Context context;
List<SearchListItem> items;
//ImageLoader imageLoader = AppController.getInstance().getImageLoader();
public SearchListAdapter(Context context, List<SearchListItem> items)
{
this.context = context;
this.items = items;
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int position) {
return items.indexOf(getItem(position));
}
class ViewHolder
{
TextView txtTitle;
TextView txtContent;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);// creates the objects of all views
if(convertView == null)
{
convertView = inflater.inflate(R.layout.style_row, null);
holder = new ViewHolder();
holder.txtTitle = (TextView) convertView.findViewById(R.id.txtAbout);
holder.txtContent = (TextView) convertView.findViewById(R.id.txtDetail);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
try {
SearchListItem rowItem = (SearchListItem) getItem(position);
holder.txtTitle.setText(rowItem.getTitle());
holder.txtContent.setText(rowItem.getContent().substring(0,20));
}
catch (Exception e){
//Toast.makeText(SearchListAdapter.this,e.printStackTrace(),Toast.LENGTH_SHORT).show();
}
return convertView;
}
}
You have not set the tag on the view , do convertview.setTag(holder) ...
if(convertView == null)
{
convertView = inflater.inflate(R.layout.style_row, null);
holder = new ViewHolder();
holder.txtTitle = (TextView) convertView.findViewById(R.id.txtAbout);
holder.txtContent = (TextView) convertView.findViewById(R.id.txtDetail);
convertView.setTag(holder)
}
Your code seems fine , problem might be that you are requesting multiple times from your code on the server and ArrayList listy getting filled multiple times in the onResponse method of jsonRequest or your server might be returning multiple entries , seems nothing wrong with the posted code.

ListView and SetAdapter null pointer exception

I have got a problem with listview for a json parser !
(ArretsFragment.java) :
package activity;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.JsonArrayRequest;
import com.example.pierre.tan.R;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import adapter.CustomListAdapter;
import app.AppController;
import model.Movie;
public class ArretsFragment extends Fragment {
// Log tag
private static final String TAG = MainActivity.class.getSimpleName();
// Movies json url
private static final String url = "http://api.androidhive.info/json/movies.json";
private List<Movie> movieList = new ArrayList<Movie>();
private ListView listView;
private CustomListAdapter adapter;
public ArretsFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
listView = (ListView) getActivity().findViewById(R.id.list);
adapter = new CustomListAdapter(getActivity(), movieList);
listView.setAdapter(adapter);
// Showing progress dialog before making http request
// Creating volley request obj
JsonArrayRequest movieReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = null;
try {
obj = response.getJSONObject(i);
} catch (JSONException e) {
e.printStackTrace();
}
Movie movie = new Movie();
movie.setTitle(obj.getString("title"));
movie.setThumbnailUrl(obj.getString("image"));
movie.setRating(((Number) obj.get("rating"))
.doubleValue());
movie.setYear(obj.getInt("releaseYear"));
// Genre is json array
JSONArray genreArry = obj.getJSONArray("genre");
ArrayList<String> genre = new ArrayList<String>();
for (int j = 0; j < genreArry.length(); j++) {
genre.add((String) genreArry.get(j));
}
movie.setGenre(genre);
// adding movie to movies array
movieList.add(movie);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(movieReq);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_arrets, container, false);
// Inflate the layout for this fragment
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onDetach() {
super.onDetach();
}
}
and i've got this (CustomListAdapter.java) :
package adapter;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;
import com.example.pierre.tan.R;
import java.util.List;
import app.AppController;
import model.Movie;
public class CustomListAdapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List<Movie> movieItems;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
public CustomListAdapter(Activity activity, List<Movie> movieItems) {
this.activity = activity;
this.movieItems = movieItems;
}
#Override
public int getCount() {
return movieItems.size();
}
#Override
public Object getItem(int location) {
return movieItems.get(location);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.list_row, null);
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
NetworkImageView thumbNail = (NetworkImageView) convertView
.findViewById(R.id.thumbnail);
TextView title = (TextView) convertView.findViewById(R.id.title);
TextView rating = (TextView) convertView.findViewById(R.id.rating);
TextView genre = (TextView) convertView.findViewById(R.id.genre);
TextView year = (TextView) convertView.findViewById(R.id.releaseYear);
// getting movie data for the row
Movie m = movieItems.get(position);
// thumbnail image
thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);
// title
title.setText(m.getTitle());
// rating
rating.setText("Rating: " + String.valueOf(m.getRating()));
// genre
String genreStr = "";
for (String str : m.getGenre()) {
genreStr += str + ", ";
}
genreStr = genreStr.length() > 0 ? genreStr.substring(0,
genreStr.length() - 2) : genreStr;
genre.setText(genreStr);
// release year
year.setText(String.valueOf(m.getYear()));
return convertView;
}
}
When i try to lauch my application i've got these errors :
04-16 11:14:57.416 27043-27043/com.example.pierre.tan E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.pierre.tan, PID: 27043
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at activity.ArretsFragment.onCreate(ArretsFragment.java:55)
at android.support.v4.app.Fragment.performCreate(Fragment.java:1763)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:915)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1136)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:739)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1499)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:456)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
It's a little difficult process so if someone can help me it would be very nice
Your problem is inside:
listView = (ListView) getActivity().findViewById(R.id.list);
Your activity does not contains your listView.
Add all of this to onActivityCreated() method
listView = (ListView) getView().findViewById(R.id.list);
adapter = new CustomListAdapter(getActivity(), movieList);
listView.setAdapter(adapter);
and learn Fragment lifecycle.
You parse an empty array of Movies to your adapter:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
listView = (ListView) getActivity().findViewById(R.id.list);
// movieList is an empty array at this point.
adapter = new CustomListAdapter(getActivity(), movieList);
listView.setAdapter(adapter);
// ...
}
I guess you just have to set your adapter after you've populated the list with data from the movieReq request.
You have to infalte your layout before retrieve the listview.
In a fragment, do all your treatments in the onCreateView method.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_arrets, container, false);
listView = (ListView) getActivity().findViewById(R.id.list);
adapter = new CustomListAdapter(getActivity(), movieList);
listView.setAdapter(adapter);
// Showing progress dialog before making http request
// Creating volley request obj
JsonArrayRequest movieReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = null;
try {
obj = response.getJSONObject(i);
} catch (JSONException e) {
e.printStackTrace();
}
Movie movie = new Movie();
movie.setTitle(obj.getString("title"));
movie.setThumbnailUrl(obj.getString("image"));
movie.setRating(((Number) obj.get("rating"))
.doubleValue());
movie.setYear(obj.getInt("releaseYear"));
// Genre is json array
JSONArray genreArry = obj.getJSONArray("genre");
ArrayList<String> genre = new ArrayList<String>();
for (int j = 0; j < genreArry.length(); j++) {
genre.add((String) genreArry.get(j));
}
movie.setGenre(genre);
// adding movie to movies array
movieList.add(movie);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(movieReq);
// Inflate the layout for this fragment
return rootView;
}

Universal Image Loader using JSON instead of the Constants Class

I've got a functioning Universal Image Loader that I'm trying to switch to grabbing the image URLs from JSON rather than the Constants Class that it normally uses. I've created a JSON Parsing Class that outputs an ArrayList called galleryArrList. But I can't figure out how to implement my JSON Parsing class and also how to modify the Adapter class in the UILGrid class to accept the galleryArrList String. Here are the Classes:
UILGrid Class:
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.mysite.wcbc.UKVPConstants.Extra;
public class UILGrid extends AbsListViewBaseActivity {
String[] imageUrls;
DisplayImageOptions options;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.uil_grid);
Bundle bundle = getIntent().getExtras();
imageUrls = bundle.getStringArray(Extra.IMAGES);
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub)
.showImageForEmptyUri(R.drawable.ic_empty)
.showImageOnFail(R.drawable.ic_error).cacheInMemory(true)
.cacheOnDisc(true).bitmapConfig(Bitmap.Config.RGB_565).build();
listView = (GridView) findViewById(R.id.uil_gridview);
((GridView) listView).setAdapter(new ImageAdapter());
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
startImagePagerActivity(position);
}
});
}
private void startImagePagerActivity(int position) {
Intent intent = new Intent(this, CVP2.class); // ---- Change here
intent.putExtra(Extra.IMAGES, imageUrls);
intent.putExtra(Extra.IMAGE_POSITION, position);
startActivity(intent);
}
public class ImageAdapter extends BaseAdapter {
#Override
public int getCount() {
return imageUrls.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ImageView imageView;
if (convertView == null) {
imageView = (ImageView) getLayoutInflater().inflate(
R.layout.uil_grid_item, parent, false);
} else {
imageView = (ImageView) convertView;
}
imageLoader.displayImage(imageUrls[position], imageView, options);
return imageView;
}
}
}
my UILJSONParse Class:
import java.util.ArrayList;
import java.util.HashMap;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.AsyncTask;
public class UILJSONParse extends AsyncTask<String, String, JSONObject> {
// url to make request
private static String url = "http://www.mysite.com/apps/wcbc/galleryuil.txt";
// Hashmap for ListView
// ArrayList<HashMap<String, String>> arraylist;
ArrayList<HashMap<String, String>> galleryArrList = new ArrayList<HashMap<String, String>>();
// JSON Node names
private static final String TAG_GALLERY = "gallery";
private static final String TAG_GALLERYURL = "galleryurl";
private static final String TAG_ID = "id";
private static final String TAG_GALLERYDESCR = "gallerydescr";
// gallery JSONArray
JSONArray JSArrGallery = null;
#Override
protected JSONObject doInBackground(String... arg0) {
// Creating JSON Parser instance
JGrid4Adapter jParser = new JGrid4Adapter();
// getting JSON string from URL
JSONObject jsonOb = jParser.getJSONFromUrl(url);
return jsonOb;
}
#Override
protected void onPostExecute(JSONObject jsonOb) {
try {
JSArrGallery = jsonOb.getJSONArray(TAG_GALLERY);
// looping through All gallery images
for (int i = 0; i < JSArrGallery.length(); i++) {
JSONObject galleryJO = JSArrGallery.getJSONObject(i);
String idStr = galleryJO.getString(TAG_ID);
String urlStr = galleryJO.getString(TAG_GALLERYURL);
String descrStr = galleryJO.getString(TAG_GALLERYDESCR);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_ID, idStr);
map.put(TAG_GALLERYURL, urlStr);
map.put(TAG_GALLERYDESCR, descrStr);
// adding HashMap map to ArrayList galleryArrList, defined
// above
galleryArrList.add(map);
}// -- END for loop
} catch (JSONException e) {
e.printStackTrace();
}// --- END Try
}// --- END onPostExecute
}// --- END UILJSONParse Class
I've figured this out since asking the question. I have a Button Interface Activity where an AsyncTask is called that grabs the JSON data when a button is clicked. The AysncTask then bundles the data and sends it to my Gallery Grid Class. The AsyncTask is calling the above JSON Parsing Class. So here's the code:
// --- artwork button
cartoon_BTN.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
jsonFileStr = "artwork_json";
new ArtworkJSON().execute();
}
});
// --- end artwork button
private class ArtworkJSON extends AsyncTask<Void, Void, Void> {
JSONObject jsonobject;
String TAG_ID = "id";
String TAG_DESCR = "artworkdescr";
String TAG_MEDIUM = "artworkmedium";
String TAG_PRICE = "artworkprice";
String TAG_URL = "artworkurl";
ArrayList<HashMap<String, String>> hashArraylist;
ArrayList<String> urlArrayList;
ArrayList<String> idArrayList;
ArrayList<String> descrArrayList;
ArrayList<String> mediumArrayList;
ArrayList<String> priceArrayList;
String[] idStrArray, urlStrArray, descrStrArray, mediumStrArray,
priceStrArray;
String urlPathStr = "http://www.mysite.com/"
+ jsonFileStr + ".txt";
JSONArray JSArrArtwork = null;
String idStr, urlStr, descrStr, mediumStr, priceStr;
ProgressDialog loadImagesDia;
Intent bundleIn;
#Override
protected void onPreExecute() {
super.onPreExecute();
// Create a progressdialog
loadImagesDia = new ProgressDialog(Main_Interface.this);
loadImagesDia.setMessage("Loading Images...");
loadImagesDia.setIndeterminate(false);
// Show progressdialog
loadImagesDia.show();
}
#Override
protected Void doInBackground(Void... params) {
hashArraylist = new ArrayList<HashMap<String, String>>();//
// Retrieve JSON Objects from the given URL address
jsonobject = JSONforGallery.getJSONfromURL(urlPathStr);
try {
// Locate the array name in JSON
JSArrArtwork = jsonobject.getJSONArray("artwork");
idArrayList = new ArrayList<String>();
urlArrayList = new ArrayList<String>();
descrArrayList = new ArrayList<String>();
mediumArrayList = new ArrayList<String>();
priceArrayList = new ArrayList<String>();
for (int i = 0; i < JSArrArtwork.length(); i++) {
HashMap<String, String> map = new HashMap<String, String>();//
JSONObject artworkJO = JSArrArtwork.getJSONObject(i);
map.put("id", artworkJO.getString(TAG_ID));//
map.put("url", artworkJO.getString(TAG_URL));//
map.put("descr", artworkJO.getString(TAG_DESCR));//
map.put("medium", artworkJO.getString(TAG_MEDIUM));//
map.put("price", artworkJO.getString(TAG_PRICE));//
idStr = artworkJO.getString(TAG_ID);
urlStr = artworkJO.getString(TAG_URL);
descrStr = artworkJO.getString(TAG_DESCR);
mediumStr = artworkJO.getString(TAG_MEDIUM);
priceStr = artworkJO.getString(TAG_PRICE);
hashArraylist.add(map);//
idArrayList.add(idStr);
urlArrayList.add(urlStr);
descrArrayList.add(descrStr);
mediumArrayList.add(mediumStr);
priceArrayList.add(priceStr);
idStrArray = idArrayList.toArray(new String[idArrayList
.size()]);
urlStrArray = urlArrayList.toArray(new String[urlArrayList
.size()]);
descrStrArray = descrArrayList
.toArray(new String[descrArrayList.size()]);
mediumStrArray = mediumArrayList
.toArray(new String[mediumArrayList.size()]);
priceStrArray = priceArrayList
.toArray(new String[priceArrayList.size()]);
}
} catch (JSONException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void args) {
loadImagesDia.dismiss();
bundleIn = new Intent("com.veedabugmedia.ktg.UILGRID");
bundleIn.putExtra("idStrArrayKey", idStrArray);
bundleIn.putExtra("hashARKey", hashArraylist);
bundleIn.putExtra("urlStrArrayKey", urlStrArray);
bundleIn.putExtra("descrStrArrayKey", descrStrArray);
bundleIn.putExtra("mediumStrArrayKey", mediumStrArray);
bundleIn.putExtra("priceStrArrayKey", priceStrArray);
startActivity(bundleIn);
}
}
My updated UILGrid Activity:
public class UILGrid extends AbsListViewBaseActivity {
String[] idStr, imageUrls, descrStrGrid, mediumStrGrid, priceStrGrid;
DisplayImageOptions options;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.uil_grid);
// Retrieve data from About_Interface on item click event
Intent getBundsIn = getIntent();
idStr = getBundsIn.getStringArrayExtra("idStrArrayKey");
imageUrls = getBundsIn.getStringArrayExtra("urlStrArrayKey");
descrStrGrid = getBundsIn.getStringArrayExtra("descrStrArrayKey");
mediumStrGrid = getBundsIn.getStringArrayExtra("mediumStrArrayKey");
priceStrGrid = getBundsIn.getStringArrayExtra("priceStrArrayKey");
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub)
.showImageForEmptyUri(R.drawable.ic_empty)
.showImageOnFail(R.drawable.ic_error).cacheInMemory(true)
.cacheOnDisc(true).bitmapConfig(Bitmap.Config.RGB_565).build();
listView = (GridView) findViewById(R.id.uil_gridview);
((GridView) listView).setAdapter(new ImageAdapter());
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
startImagePagerActivity(position);
}
});
}// --- END onCreate
private void startImagePagerActivity(int position) {
Intent pagerIn = new Intent(this, UILPager.class);
pagerIn.putExtra("pagerUrlStrKey", imageUrls);
pagerIn.putExtra("pagerDescrStrKey", descrStrGrid);
pagerIn.putExtra("pagerMediumStrKey", mediumStrGrid);
pagerIn.putExtra("pagerPriceStrKey", priceStrGrid);
pagerIn.putExtra("pagerPositionKey", position);
startActivity(pagerIn);
}
public class ImageAdapter extends BaseAdapter {
#Override
public int getCount() {
return imageUrls.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ImageView imageView;
if (convertView == null) {
imageView = (ImageView) getLayoutInflater().inflate(
R.layout.uil_grid_item, parent, false);
} else {
imageView = (ImageView) convertView;
}
imageLoader.displayImage(imageUrls[position], imageView, options);
return imageView;
}
}
#Override
protected void onPause() {
super.onPause();
overridePendingTransition(R.anim.fadein, R.anim.fadeout);
UILGrid.this.finish();
}
}

Categories

Resources