get string from arraylist and settext inside fragment android - android

I want to get string from arraylist inside oncreateview fragment but i cant figure itout since no position index has been pass. get(position) return error.
String price = arrayList.get(position).getPrice();
i need to get string price and settext for price.this is my main concern.
this values should return from arraylist.
this is response JSON array from volley using mysingleton.
Single Product Response: [{"price":"75","date":"2017-07-13 03:25:31","pk_i_id":"4"}]
this main activty fragment
public class MainActivityFragment extends Fragment {
private TextView product,price,date,title;
private String product_id;
ArrayList<ProductItem> arrayList = new ArrayList<>();
Context context;
public MainActivityFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_main_activity, container, false);
product = (TextView) view.findViewById(R.id.tv1);
title = (TextView) view.findViewById(R.id.tvTitle);
price = (TextView) view.findViewById(R.id.tvPrice);
date = (TextView) view.findViewById(R.id.tvDate);
if (getArguments() != null) {
Log.i(TAG, "getArgument is not null");
product_id = getArguments().getString("product_id");
ProductBackgroundTask productBackgroundTask = new ProductBackgroundTask(this.getActivity(), product_id);
arrayList = productBackgroundTask.getList();
String price = arrayList.get(position).getPrice();
// Log.d(TAG, "price: " + price);
product.setText(product_id);
// price.setText(price);
}else {
Log.i(TAG, "getArgument is null");
}
return view;
}
}
this is task to get arraylist using volley
public class ProductBackgroundTask {
private Context context;
ArrayList<ProductItem> arrayList = new ArrayList<>();
String json_url = "phpfile.php";
private String product_id;
public ProductBackgroundTask(Context context, String product_id) {
this.context = context;
this.product_id = product_id;
}
public ArrayList<ProductItem> getList(){
StringRequest stringRequest = new StringRequest(Request.Method.POST, json_url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, "Single Product Response: " + response);
try {
JSONArray jsonarr = new JSONArray(response);
for (int i = 0; i < jsonarr.length(); i++) {
JSONObject jsonobj = jsonarr.getJSONObject(i);
ProductItem productItem = new ProductItem(jsonobj.getString("price"), jsonobj.getString("date"), jsonobj.getInt("pk_i_id"));
arrayList.add(productItem);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<>();
params.put("product_id", product_id);
return params;
}
};
MySingleton.getInstance(context).addToRequestQueue(stringRequest);
return arrayList;
}
}
and this is class of array list
public class ProductItem {
private String Price,Date;
private int ProductId;
public ProductItem(String Price, String Date, int ProductId){
this.setPrice(Price);
this.setDate(Date);
this.setProductId(ProductId);
}
public int getProductId() {
return ProductId;
}
public void setProductId(int productId) {
ProductId = productId;
}
public String getPrice() {
return Price;
}
public void setPrice(String price) {
Price = price;
}
public String getDate() {
return Date;
}
public void setDate(String date) {
Date = date;
}

Clearly in your oncreate you haven’t initialized the product item and you cannot parse the complete list.You can try two to solve this
1.Pass specific item number instead of position i.e
say if you want to show 4th item then position=3
2.Or write a loop like this to parse entire arrayList like this
for(ProductItem productItem:arrayList){
String price = productItem.getPrice();
// Log.d(TAG, "price: " + price);
product.setText(product_id);
price.setText(price);
}

Mistake you're doing is that in the MainActivityFragment your trying to assign the value to the arrayList even before the data is added to the arrayList in the ProductBackgroundTask-getList. That's the reason you are getting the list null all the time. Try to use interfaces.
1.Make your MainActivityFragment implement the interface.
2.Set the value to the interface method once you get the data from the server.
3.Get the data in the MainActivityFragment inside interface method and do all the operation you're doing inside the onCreateView method.
Now your arraylist will have the data whatever you received from the server.
Below is the link for the example on interfaces if you haven't used them before. He is doing exactly as your requirement.
https://www.justinmccandless.com/post/setting-up-a-callback-function-in-android/

Allow me. The arrayList that you return from getList isn't populated at the time you call String price = arrayList.get(position).getPrice();. The server call using volley takes some time to process and that's when the onResponse gets called. This happens AFTER you've returned the arrayList which is in fact empty.
The sequence of events is as follows.
• Call to arrayList = productBackgroundTask.getList(); which returns an empty ArrayList.
• String price = arrayList.get(position).getPrice();
Now after a while..
• onResponse inside getList() gets called.
Do you now see why it's empty?
Simple Solution: • Define a simple interface ProductListener alongside ProductBackgroundTask. (With only a single abstract method onProducts).
• Instantiate it inside the Fragment's onCreateView using an anonymous class and pass it to the constructor of ProductListener to save it for later use. Do whatever you want to do with the products inside the onProducts method. (Since that will be called with the actual data)
• Call its onProducts method with the data that's parsed and fetched inside the onResponse method.
ProductBackgroundTask code:
public class ProductBackgroundTask {
private Context context;
// I removed the instance ArrayList since that can be made
// local.
// Here, we add a reference to our callback interface as we can use it later.
private ProductListener listener;
String json_url = "http://192.168.43.55/android/v1/productList.php";
private String product_id;
// Instantiate this class using an additional listener argument
// which would be a concrete implementation of our interface.
public ProductBackgroundTask(Context context, String product_id, ProductListener listener) {
this.context = context;
this.product_id = product_id;
this.listener = listener;
}
// getList should not return anything,
// so I keep the return as void.
public void getList() {
StringRequest stringRequest = new StringRequest(Request.Method.POST, json_url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
ArrayList<ProductItem> arrayList = new ArrayList<>();
Log.d(TAG, "Single Product Response: " + response);
try {
JSONArray jsonarr = new JSONArray(response);
for (int i = 0; i < jsonarr.length(); i++) {
JSONObject jsonobj = jsonarr.getJSONObject(i);
ProductItem productItem = new ProductItem(jsonobj.getString("price"), jsonobj.getString("date"), jsonobj.getInt("pk_i_id"));
arrayList.add(productItem);
}
// Notice this line here, this is what
// calls the callback with the products.
listener.onProducts(arrayList);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<>();
params.put("product_id", product_id);
return params;
}
};
MySingleton.getInstance(context).addToRequestQueue(stringRequest);
}
}
// Callback interface, we would need a concrete implementation
// of this and pass that to the constructor of ProductBackgroundTask.
interface ProductListener {
void onProducts(ArrayList<ProductItem> products);
}
The code inside onCreateView:
ProductBackgroundTask productBackgroundTask = new ProductBackgroundTask(this.getActivity(), product_id, new ProductListener() {
// This method will be called with the needed products.
// Give an anonymous class implementation of our interface
// right here since we won't be using it anymore.
public void onProducts(ArrayList<ProductItem> products) {
// Get the price you want.
String str = arrayList.get(0).getPrice();
// Use str wherever necessary. Use the UI thread here if you need
// to change any visible elements on the screen.
}
});
// Simply call this method to get the ball rolling.
productBackgroundTask.getList();
This is a concrete implementation of the this answer and you won't be changing much code.

Related

Access shared preferences from a helper class

I have a fragment that calls a helper class in order to make a jsonRequest with Volley.
Upon response, the helper class creates a custom object, but in order to set it up, it needs to check some values stored in Shared Preferences.
The problem is that I can't access getSharedPreferences inside the helper class.
public class MyDataHandler {
ArrayList<MyItem> itemsArrayList = new ArrayList<>();
public List<MyItem> getAll(Boolean completed, String current, final MyAsyncResponse callBack) {
String url = "https://my.api/" + current;
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(
Request.Method.GET,
url,
null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for (int i = 0; i < response.length(); i++) {
try {
JSONObject jsonObject = response.getJSONObject(i);
MyItem myItem = new MyItem();
if (!completed) {
SharedPreferences sharedPreferences = getSharedPreferences("MyApp", MODE_PRIVATE); // this doesn't work
if (sharedPreferences.getBoolean("someKey", false)) {
// set properties in MyItem
}
}
itemsArrayList.add(myItem);
} catch (JSONException e) {
e.printStackTrace();
}
}
if (null != callBack) callBack.processFinished(itemsArrayList);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
);
AppController.getInstance().addToRequestQueue(jsonArrayRequest);
return itemsArrayList;
}
How can I access Shared Preferences if this class isn't attached to any particular activity?
I assume that you are instantiating MyDataBaseHandler as "getAll" is a non static function
create a constructor and a member variable like this :-
MyDataBaseHandler{
Context context;
public MyDataHandler(Context context){ //pass your activity here
this.context=context;
}
// write rest of your code
}
now you can use this context member variable and access your shared perefrence using context.getSharedPreference("MyApp", Context.MODE_PRIVATE).

Recyclerview json data binding has failed

I am trying to bind JSON data on to the recyclerView , but data seems not to bind to the RecyclerView.
Surprisingly when i Toast the data i see it's available. What could be the problem?
private void parseJson(String result){
try {
if (result!=null) {
String resultTostring = "" + result;
JSONObject obj = new JSONObject(resultTostring).getJSONObject("ScheduleResource");
JSONArray arr = obj.getJSONArray("Schedule");
itemList = new ArrayList<>();
for (int i = 0; i < arr.length(); i++)
{
String DepartureAirport = arr.getJSONObject(i).getJSONObject("Flight").getJSONObject("Departure").getString("AirportCode");
String ArrivalAirport = arr.getJSONObject(i).getJSONObject("Flight").getJSONObject("Arrival").getString("AirportCode");
String Duration = arr.getJSONObject(i).getJSONObject("TotalJourney").getString("Duration");
String DepartureTime = arr.getJSONObject(i).getJSONObject("Flight").getJSONObject("Departure").getJSONObject("ScheduledTimeLocal").getString("DateTime");
String ArrivalTime = arr.getJSONObject(i).getJSONObject("Flight").getJSONObject("Arrival").getJSONObject("ScheduledTimeLocal").getString("DateTime");
String Stops = arr.getJSONObject(i).getJSONObject("Flight").getJSONObject("Details").getJSONObject("Stops").getString("StopQuantity");
FlightModel model = new FlightModel();
model.setDepartureAirport(DepartureAirport);
model.setArrivalAirport(ArrivalAirport);
model.setDuration(Duration);
model.setDeparturTimee(DepartureTime);
model.setArrivalTime(ArrivalTime);
model.setStops(Stops);
model.Stops= Stops;
itemList.add(model);
Toast.makeText(FlightListActivity.this, "DEPT : " + DepartureAirport + " Arrival " + ArrivalAirport+
" Duration : " + Duration + " Dept time : "+ DepartureTime+" Arr Time "+ ArrivalTime
+" Stops "+ Stops, Toast.LENGTH_LONG).show();
}
// Setup and Handover data to recyclerview
final FlightAdapter adapter = new FlightAdapter(FlightListActivity.this, itemList);
flights_rv.setAdapter(adapter);
flights_rv.setLayoutManager(new LinearLayoutManager(FlightListActivity.this));
}
else{
Toast.makeText(FlightListActivity.this,Config.POOR_NETWORK_CONNECTION, Toast.LENGTH_LONG).show();
}
}
catch (JSONException r){
System.out.println("ERROR PROB : "+ r);
// Toast.makeText(ListOfFlights.this,"ERROR PROB : "+ r,Toast.LENGTH_LONG).show();
}
}
In my Adapter i have attached the Layout which will have the appearance of the data in the List , and also my POJO class is set which has both getters and setters, but when i try to attach the adapter on to the RecyclerView the data doesn't bind why ?
EDIT
My Adapter Class
public class FlightAdapter extends RecyclerView.Adapter<FlightHolder> {
private List<FlightModel> itemList= Collections.emptyList();
private Context context;
public FlightAdapter(Context context,List<FlightModel> itemList) {
this.context = context;
this.itemList = itemList;
}
#Override
public FlightHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.new_details, parent, false);
FlightHolder rcv = new FlightHolder(layoutView, context);
return rcv;
}
#Override
public void onBindViewHolder(FlightHolder holder, int position) {
final FlightModel sr = itemList.get(position);
final String DepartureAirport = sr.getDepartureAirport();
final String ArrivalAirport = sr.getArrivalAirport();
final String Duration = sr.getDuration();
final String DepartureTime = sr.getDeparturTimee();
final String ArrivalTime = sr.getArrivalTime();
final String Stops = sr.getStops();
final String DirectFlight = sr.getDirectFlights();
holder.from_txt.setText(DepartureAirport);
holder.to_txt.setText(ArrivalAirport);
holder.duration_txt.setText(Duration);
holder.depature_txt.setText(DepartureTime);
holder.arrival_txt.setText(ArrivalTime);
holder.stops_txt.setText(Stops);
holder.dept_txt.setText(DepartureAirport);
holder.arr_txt.setText(ArrivalAirport);
holder.root.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Intent i = new Intent(FlightAdapter.this.context, DetailsLocalLeader.class);
// context.startActivity(i);
}
});
}
#Override
public int getItemCount() {
;
return itemList.size();
}
}
For more information , below is the link to the project :
https://github.com/huxaiphaer/FlightsApp/blob/master/app/src/main/java/adapter/FlightAdapter.java
First of all, get someone to review your code structure. Read and understand Java Standard Naming Conventions. Use a design pattern for your app, probably MVP. Use Gson library to parse JSON data for you.
To answer your question, I would say that your JSON structure is flawed. Your code outputs this error
ERROR PROB : org.json.JSONException: Value "SOME_LONG_JSON" at Flight of type org.json.JSONArray cannot be converted to JSONObject
It means that you are trying to parse a JSONArray as a JSONObject. In the Schedule array, there's 9th entry which is supposed to be a JSONObject(as seen in previous 8 entries). But, it is a JSONArray.
So, first 8 entries are like:
{
"Departure": {},
"Arrival": {},
"MarketingCarrier": {},
"Equipment": {},
"Details": {}
}
and, the 9th entry is like :
[
{
"Departure": {},
"Arrival": {},
"MarketingCarrier": {},
"Equipment": {},
"Details": {}
},
{
"Departure": {},
"Arrival": {},
"MarketingCarrier": {},
"Equipment": {},
"Details": {}
}
]
That's why you get this parsing exception in try-catch block. So, you can do this to check if your object is JSONArray or JSONObject like this in parseJson(String result):
Object departureObject = arr.getJSONObject(i).getJSONObject("Flight").get("Departure");
if (departureObject instanceof JSONObject) {
String departureAirport = ((JSONObject) departureObject).getString("Airport");
}
else if (departureObject instanceof JSONArray) {
JSONArray departures = (JSONArray) departureObject;
// use for-loop here to get data from array
}
But, seriously, use POJO with Gson and simplify parsing process. Also, if you have control over how API works, try to keep an object of one type only. If it is supposed to be a list, it better be a list even if there are no items or if there's one or more.
Try these things, it might solve this problem, but I doubt it. You will face more problems with parsing I think. Ping me after you've done this.
Also, if you try to parse all of JSON received by Server, you will see that it is not even complete. Look at the end of your JSON data.
Try something like this for your adapter:
public class FlightAdapter extends RecyclerView.Adapter<FlightAdapter.MyViewHolder> {
private List<FlightModel> mItemList;
private Context context;
public class MyViewHolder extends RecyclerView.ViewHolder {
//TODO: Add all your views and the types hear!
Public TextView mTvName;
public MyViewHolder(View v){
super(v);
//TODO: add here for each view in your row
mTvName = (TextView)v.findViewById(R.id.tvName);
}
}
public FlightAdapter(Context context,List<FlightModel> itemList) {
this.context = context;
this.mItemList = itemList;
}
#Override
public FlightHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.new_details, parent, false);
return new MyViewHolder(layoutView);
}
#Override
public void onBindViewHolder(FlightHolder holder, int position) {
FlightModel model = mItemList.get(position);
//TODO: Add for each view and data point!!
String name = model.getName();
holder.mTvName.setText(name);
holder.layoutView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Intent i = new Intent(FlightAdapter.this.context, DetailsLocalLeader.class);
// context.startActivity(i);
}
});
}
#Override
public int getItemCount() {
return mItemList.size();
}
}
Disclaimer!
I typed this in a text editor, so there might be a few syntax errors or misspellings. Please let me know if you have any issues.

How to pass String into ListView - Android

I have made an ListView with items, qty, rate and retrieved the data from MySQL but I need to add even my "Service Charges" and "Net Amount" to the ListView but I have "Service Charges" and "Net Amount" in the variable not in the MYSQL how can I insert this two into the ListView.
Here is my code:
public void getPostedJobsLocal(){
String url=Config.GET_PAYMENT_BILL;
String url1= local_job_id;
String URL=url+url1;
StringRequest stringRequest = new StringRequest(URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
showJSONPosted(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
private void showJSONPosted(String response) {
ParseJSONPayBillLocal pj = new ParseJSONPayBillLocal(response);
pj.parseJSONPayBillLocal();
CustomListPayBillLocal cl = new CustomListPayBillLocal(this, ParseJSONPayBillLocal.items, ParseJSONPayBillLocal.qty,ParseJSONPayBillLocal.rate);
lview.setAdapter(cl);
}
So how can insert the "Service Charges" and "Net Amount" which I have as variable into the ListView?
Its more of a hack. You can add the items to the String arrays before giving it to the Adapter.
Something like this,
private void showJSONPosted(String response) {
ParseJSONPayBillLocal pj = new ParseJSONPayBillLocal(response);
pj.parseJSONPayBillLocal();
ParseJSONPayBillLocal.items = append(ParseJSONPayBillLocal.items, "Service Charges");
ParseJSONPayBillLocal.qty = append(ParseJSONPayBillLocal.qty, "your_qty");
ParseJSONPayBillLocal.rate = append(ParseJSONPayBillLocal.rate, "your_rate");
ParseJSONPayBillLocal.items = append(ParseJSONPayBillLocal.items, "Net Amount");
ParseJSONPayBillLocal.qty = append(ParseJSONPayBillLocal.qty, "your_qty");
ParseJSONPayBillLocal.rate = append(ParseJSONPayBillLocal.rate, "your_rate");
CustomListPayBillLocal cl = new CustomListPayBillLocal(this, ParseJSONPayBillLocal.items, ParseJSONPayBillLocal.qty, ParseJSONPayBillLocal.rate);
lview.setAdapter(cl);
}
public static <T> T[] append(T[] arr, T element) {
final int N = arr.length;
arr = Arrays.copyOf(arr, N + 1);
arr[N] = element;
return arr;
}
Make a model class containing Service Charges and Net Amount
public class MyModel {
String serviceCharges;
String netAmount;
public MyModel (String serviceCharges, String netAmount){
this.serviceCharges= serviceCharges;
this.netAmount= netAmount;
}
public String getServiceCharges() {
return serviceCharges;
}
public void setServiceCharges(String serviceCharges) {
this.serviceCharges= serviceCharges;
}
public String getNetAmount() {
return netAmount;
}
public void setNetAmount(String netAmount) {
this.netAmount= netAmount;
}
}
Now you can create an ArrayList of MyModel class and add your services charges and net amount values:
ArrayList<MyModel> myModelArray = new ArrayList<MyModel>();
myModelArray.add(new MyModel("serviceCharge1","netAmount1"));
myModelArray.add(new MyModel("serviceCharge2","netAmount2"));
.......
.......
Now you can pass this myModelArray to your list adapter for binding data with the list view.
Retrieve values by:
myModelArray.get(position).getServiceCharges();
myModelArray.get(position). getNetAmount();
Note: Shift to retrofit, it is 4 times faster than volley.

Method called before the initialization of an Adapter , executing after the adapter initialization in Android

Inside my Fragment onCreateView method I have call a method named getData() which has implemented to get some data as json response from server using android volley library.
getData() method :
public void getData(MyCustomListener<CompleteCartProItem> customListener) {
if (MyApplication.getAndroidSession().getAttribute("cart") != null) {
Log.i("cart_null", "NOT null");
RequestQueue requestQueue = VolleySingleton.getsInstance().getRequestQueue();
CartDetails cartDetails = (CartDetails) MyApplication.getAndroidSession().getAttribute("cart");
ArrayList<CartItem> jsonSendArray = cartDetails.getShoppingList();
final String jsonString = new Gson().toJson(jsonSendArray,
new TypeToken<ArrayList<CartItem>>() {
}.getType());
Log.i("json_object", jsonString);
String url = "http://10.0.2.2:8080/ECommerceApp/getAllProductsAction";
JsonArrayRequest arrayRequest = new JsonArrayRequest(Request.Method.GET, url,
response -> {
List<CompleteCartProItem> completeCart = new Gson().fromJson(response.toString(),
new TypeToken<List<CompleteCartProItem>>() {
}.getType());
Log.i("response", completeCart.get(0).getP_name());// successfully prints out the 0th product name.
customListener.onResponse(completeCart);
}, error -> Log.i("Volley_error", error.getMessage())) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("Content-Type", "application/json");
params.put("cartList", jsonString);
return params;
}
};
arrayRequest.setRetryPolicy(new RetryPolicy() {
#Override
public int getCurrentTimeout() {
return 5000;
}
#Override
public int getCurrentRetryCount() {
return 5000;
}
#Override
public void retry(VolleyError error) throws VolleyError {
}
});
requestQueue.add(arrayRequest);
} else {
Log.i("cart_null", "null");
}
}
Inside onCreateView :
...
getData(new MyCustomListener<CompleteCartProItem>() {
#Override
public void onResponse(List<CompleteCartProItem> response) {
completeCartProItems.addAll(response);
Log.i("executed", "Inside_onResponse");
Log.i("check", completeCartProItems.get(0).getP_name());
}
#Override
public void onError(String error_response) {
}
});
cart_item_scrollerAdapter = new CartItem_ScrollerAdapter(getActivity(), completeCartProItems);//completeCartProItems is an ArrayList of CompleteCartProItem (private List<CompleteCartProItem> completeCartProItems = new ArrayList<>();)
...
As you can see I m calling getData() before initializing the Adapter. But CartItem_ScrollerAdapter(...) constructor is calling before the getData() method here.
Constructor of CartItem_ScrollerAdapter(...) :
public CartItem_ScrollerAdapter(Context context, List<CompleteCartProItem> completeCartProItems) {
this.inflater = LayoutInflater.from(context);
this.context = context;
this.completeCartProItems = completeCartProItems;
Log.i("executed","Adapter");
}
As you can see Log.i("executed", "Inside_onResponse"); inside the getData() method is displays in the log cat after displaying the Log.i("executed","Adapter"); which is inside CartItem_ScrollerAdapter(...) . I havent initialize it anywhere before this. So that cause my completeCartProItems ArrayList passing to the constructor of CartItem_ScrollerAdapter(...) always empty.Any suggestions to get rid of this issue would be appreciable. Thank you.
Initialize the adapter before calling getData(). And when data is received, add it into ArrayList and call adapter's notifyDataSetChanged();
// completeCartProItems should be initialized before passing it into adapter.
cart_item_scrollerAdapter = new CartItem_ScrollerAdapter(getActivity(), completeCartProItems);
// Set your adatper here...
cart_horizontal_scroller.setAdapter(cart_item_scrollerAdapter);
getData(new MyCustomListener<CompleteCartProItem>() {
#Override
public void onResponse(List<CompleteCartProItem> response) {
completeCartProItems.addAll(response);
cart_item_scrollerAdapter.notifyDataSetChanged();
Log.i("executed", "Inside_onResponse");
Log.i("check", completeCartProItems.get(0).getP_name());
}
#Override
public void onError(String error_response) {
}
});

JSON Download # onCreateView leaves recyclerView empty

if (isConnected()) {
Event eInstance = new Event();
theEvents = eInstance.downloadEvents(eventsNightlife, getActivity());
rAdapter = new RecyclerAdapter(theEvents);
recyclerView.setAdapter(rAdapter);
progrsBar.setVisibility(View.GONE);
....
This is part of the code that runs at "onCreateView". The method downloadEvents uses Volley to download JSON data, extract it and return a list of items (theEvents). Now when my app starts, the recycler view is empty. If I go to my home screen out of the app and then run my app again, this time the data sometimes gets downloaded.
I debugged step by step, and at first launch (i mean when the app is not just resuming), theEvents is empty, so the download didn't return or manage to return anything...
Suggestions on how to execute things before the UI has been shown to the user or what actually needs to be done to approach this task better?
Also, I use a swipeRefreshLayout and at its onRefresh method I do:
public void onRefresh() {
Event eInstance = new Event();
theEvents = eInstance.downloadEvents(eventsNightlife, getActivity());
rAdapter.notifyDataSetChanged();
swipeRefreshLayout.setRefreshing(false);
}
but it doesn't work. I also tried to
rAdapter = new RecyclerAdapter(theEvents);
rAdapter.notifyDataSetChanged();
recyclerView.swapAdapter(rAdapter, false);
still not working.
EDIT: My downloadEvents method implementing Volley:
public List<Event> downloadEvents(String urlService, Context context) {
eventsList = new ArrayList<>();
RequestQueue requestQueue = Volley.newRequestQueue(context);
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest
(Request.Method.GET, urlService, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
String durationStr = null;
for (int i = 0; i < response.length(); i++) {
JSONObject eventJson = response.getJSONObject(i);
String title = eventJson.getString("EventTitle");
String body = eventJson.getString("EventBody");
String date = eventJson.getString("EventDate");
String time = eventJson.getString("EventTime");
int duration = Integer.parseInt(eventJson.getString("EventDuration"));
if (duration > 60) {
durationStr = "Duration: " + duration / 60 + " h";
} else if (duration < 60) {
durationStr = "Duration: " + duration + " m";
}
String place = eventJson.getString("EventPlace");
String organ = eventJson.getString("Organization");
Event event = new Event(title, body, date, time, durationStr, place, organ);
eventsList.add(event);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY ERROR", "" + error);
}
}
);
requestQueue.add(jsonArrayRequest);
return eventsList;
}
You can use EventBus for your purpose that is a simple and truth way.
Here, i write an example for how to use EventBus with volley.
Consider that i want to download some data.
This is the class that my download methods is inside it (you can add more methods to it in the future):
Im used volley to download my data:
// Download methods is inside volley
public class MyDownloader{
public static void downloadData(){
DownloadDataEvent dlDataEvent=new DownloadDataEvent();
List<String> myResult=new ArrayList<>();
...
#Override
public void onResponse(JSONArray response) {
super.onResponse(response);
if(respone!=null){
// Do what i want with my received data
dlDataEvent.setData(response);
}
// Post my event by EventBus
EventBus.getDefault().post(dlDataEvent);
...
}
}
}
This is my event:
public class DownloadDataEvent{
private JSONArray mData;
public void setData(JSONArray data){
mData=data;
}
public JSONArray setData(){
return mData;
}
}
Now i want to use my downloadData() method inside my MainActivity:
(I called my downloadData method inside onCreate.)
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
...
// I have to register this class for EventBus subscriber:
if(!EventBus.getDefault().isRegister(this)){
EventBus.getDefault().registerSticky(this);
}
// Call my downloadData method
if(isConnected()){
MyDownloader.downloadData();
}
}
// And for receive the data through EventBus, i have to create a
// method (subscriber) in this template:
public void onEventMainThread(DownloadDataEvent downloadDataEvent){
JSONArray result=downloadDataEvent.getData();
// Do what i want with my received data
}
}
you can create more than one subscriber every where you want to use received data.
I passed JSONArray to my DownloadDataEvent that it is not good. you can deserialize your received data and pass it to your DownloadDataEvent.
I used Volley to download data
Maybe my descriptions were confusing, but EventBus is a well-known library and is very easy to use.

Categories

Resources