Hi in the below on back press from one fragment to current fragement duplicate list got creating using recyclerview in android.
If I am load my fragment it is giving me correct response.but moving to next fragment and coming back to current fragment .when I am coming back to the current fragment it is showing duplicate list in and not closing app.
public class HomeFragment extends Fragment implements ViewAppointmentAdapter.SelectIemClickListner,ViewAppointmentAdapter.StartSelectIemClickListner,DoctorAdapter.SelectIemClickListner, SpeclializationAdapter.MyItemClickListener, PatientAdapter.SelectIemClickListner,DoctorPatientListAdapter.SelectIemClickListner,DoctorPatientListAdapter.StartSelectIemClickListner,ViewAppointmentAdapter.SelectIemCancelClickListner {
public HomeFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
((NavigationViewActivity) getActivity()).setActionBarTitle("Home");
View rootView = inflater.inflate(R.layout.activity_home, container, false);
data_viewpatientlists = new ArrayList<>();
viewpatientdataLists = new ArrayList<>();
recyclerAppointmentlist = rootView.findViewById(R.id.recyclerAppointmentlist);
recyclerAppointmentlist.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
viewAppointmentAdapter = new ViewAppointmentAdapter(requireContext(), data_viewpatientlists, this, this, this);
data_viewpatientlists.clear();
viewPatientList();
}
private void viewPatientList() {
// progressDialog = new ProgressDialog(getContext());
// progressDialog.setIndeterminate(true);
// progressDialog.setMessage("Loading...");
// progressDialog.setCanceledOnTouchOutside(false);
// progressDialog.setCancelable(false);
// progressDialog.show();
String RegistrationNo = LoginId;
final APIService service = RetroClass.getRetrofitInstance().create(APIService.class);
Call<Patient_ViewPatientlist> call = service.ViewPatientList(RegistrationNo);
Log.wtf("URL Called", call.request().url() + "");
call.enqueue(new Callback<Patient_ViewPatientlist>() {
#Override
public void onResponse(Call<Patient_ViewPatientlist> call, Response<Patient_ViewPatientlist> response) {
Log.e("response", new Gson().toJson(response.body()));
if (response.isSuccessful()) {
Log.e("response", new Gson().toJson(response.body()));
Patient_ViewPatientlist patient_patientlist = response.body();
viewpatientdataLists = patient_patientlist.getData();
for (Data_Viewpatientlist view_patientList : viewpatientdataLists) {
String First_name = view_patientList.getFName();
String last_name = view_patientList.getLName();
String SlotFrom = view_patientList.getSlotFrom();
String SlotTo = view_patientList.getSlotTo();
String FromDate = view_patientList.getForDate();
String booking_id = view_patientList.getBookingId();
String doct_id = view_patientList.getDocId();
String profile_photo = view_patientList.getProfllePhoto();
DateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd");
DateFormat outputFormat = new SimpleDateFormat("dd-MMM-yyyy");
Date date = null;
try {
date = inputFormat.parse(FromDate);
} catch (ParseException e) {
e.printStackTrace();
}
String outputDateStr = outputFormat.format(date);
Data_Viewpatientlist data_doctorpatientlist = new Data_Viewpatientlist(booking_id, First_name, last_name, outputDateStr, SlotFrom, SlotTo);
data_viewpatientlists.add(data_doctorpatientlist);
Log.d("data_viewpatientlists", String.valueOf(data_viewpatientlists.size()));
recyclerAppointmentlist.setAdapter(viewAppointmentAdapter);
viewAppointmentAdapter.notifyDataSetChanged();
}
}
// progressDialog.dismiss();
}
#Override
public void onFailure(Call<Patient_ViewPatientlist> call, Throwable t) {
Log.d("error", t.getMessage());
// progressDialog.dismiss();
}
});
}
I haven't looked deeply, but it looks like you are clearing the list of the passed adapter only when you create your fragment.
When you return to the previous fragment, the onCreateView is not called, it is called fragment method onAttach.
Try to override the onAttach method and clear the list there.
Try This:
first of all clear a data of 'recyclerAppointmentlist' in onResponse() and then add the new records
it looks like this:
call.enqueue(new Callback<Patient_ViewPatientlist>() {
#Override
public void onResponse(Call<Patient_ViewPatientlist> call, Response<Patient_ViewPatientlist> response) {
Log.e("response", new Gson().toJson(response.body()));
if (response.isSuccessful()) {
viewpatientdataLists.clear()
Patient_ViewPatientlist patient_patientlist = response.body();
viewpatientdataLists = patient_patientlist.getData();
Related
I am populating RecyclerView's adapter with ArrayList. List contain model object class which holds data from server. And it needs to be loaded into Tab Fragment.
I have tried everything I know about life cycle of a list and it seems that this list is deleted from memory at some point in that cycle.
Here is relevant part of code:
public class TrueFragment extends Fragment {
public static List<AllPositiveModel> newsList = new ArrayList<>();
private RecyclerView recyclerView;
private NewsAdapterTrue adapter;
private OnFragmentInteractionListener mListener;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_true, container, false);
recyclerView = rootView.findViewById(R.id.recycler_view_true);
newsList = getResult();
adapter = new NewsAdapterTrue(newsList, getActivity());
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
return rootView;
}
public List<AllPositiveModel> getResult(){
final List<AllPositiveModel> items = new ArrayList<>();
GETAll getApiService;
getApiService = ApiUtils.getAPIServiceFetchAll();
getApiService.getAllNews().enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
if (response.isSuccessful()) {
if (response.body() != null) {
Log.i("onSuccess", response.body());
String jsonresponse = response.body();
try {
//getting the whole json object from the response
JSONObject obj = new JSONObject(response.body());
JSONArray dataArray = obj.getJSONArray("data");
for (int i = 0; i < dataArray.length(); i++) {
String title, desc, link, date, img, paper;
final Integer id, positive, negative;
JSONObject dataobj = dataArray.getJSONObject(i);
AllPositiveModel item = new AllPositiveModel(dataobj.getInt("id"), dataobj.getString("title"),
dataobj.getString("description"), dataobj.getString("link"),
dataobj.getString("date"), dataobj.getString("image"),
dataobj.getInt("positive_votes"), dataobj.getInt("negative_votes"),
dataobj.getString("paper"));
id = dataobj.getInt("id");
title = dataobj.getString("title");
desc = dataobj.getString("description");
link = dataobj.getString("link");
date = dataobj.getString("date");
img = dataobj.getString("image");
positive = dataobj.getInt("positive_votes");
negative = dataobj.getInt("negative_votes");
paper = dataobj.getString("paper");
items.add(item);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.i("onEmptyResponse", "Returned empty response");
}
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
}
});
return items;
}
}
When I print in Log values of list inside of getResult() method, it works fine. But after it gets out from the method, list is empty.
You have already a list on Global level, no need to create a new list. i have updated your code try to run it and test hopefully it will work.
public class TrueFragment extends Fragment {
public static List<AllPositiveModel> newsList = new ArrayList<>();
private RecyclerView recyclerView;
private NewsAdapterTrue adapter;
private OnFragmentInteractionListener mListener;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_true, container, false);
recyclerView = rootView.findViewById(R.id.recycler_view_true);
getResult();// Call this method
adapter = new NewsAdapterTrue(newsList, getActivity());
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
return rootView;
}
public void getResult(){
// final List<AllPositiveModel> items = new ArrayList<>(); no need for this as you have a list on global level
GETAll getApiService;
getApiService = ApiUtils.getAPIServiceFetchAll();
getApiService.getAllNews().enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
if (response.isSuccessful()) {
if (response.body() != null) {
Log.i("onSuccess", response.body());
String jsonresponse = response.body();
try {
//getting the whole json object from the response
JSONObject obj = new JSONObject(response.body());
JSONArray dataArray = obj.getJSONArray("data");
for (int i = 0; i < dataArray.length(); i++) {
String title, desc, link, date, img, paper;
final Integer id, positive, negative;
JSONObject dataobj = dataArray.getJSONObject(i);
AllPositiveModel item = new AllPositiveModel(dataobj.getInt("id"), dataobj.getString("title"),
dataobj.getString("description"), dataobj.getString("link"),
dataobj.getString("date"), dataobj.getString("image"),
dataobj.getInt("positive_votes"), dataobj.getInt("negative_votes"),
dataobj.getString("paper"));
id = dataobj.getInt("id");
title = dataobj.getString("title");
desc = dataobj.getString("description");
link = dataobj.getString("link");
date = dataobj.getString("date");
img = dataobj.getString("image");
positive = dataobj.getInt("positive_votes");
negative = dataobj.getInt("negative_votes");
paper = dataobj.getString("paper");
newsList.add(item);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.i("onEmptyResponse", "Returned empty response");
}
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
}
});
// return items;
}
}
Try this.I modified the code.
public class TrueFragment extends Fragment {
public static List<AllPositiveModel> newsList; //changed here
private RecyclerView recyclerView;
private NewsAdapterTrue adapter;
private OnFragmentInteractionListener mListener;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_true, container, false);
recyclerView = rootView.findViewById(R.id.recycler_view_true);
newsList = getResult(); //no changes here
adapter = new NewsAdapterTrue(newsList, getActivity());
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
return rootView;
}
public List<AllPositiveModel> getResult(){
final List<AllPositiveModel> items = new ArrayList<>();
GETAll getApiService;
getApiService = ApiUtils.getAPIServiceFetchAll();
getApiService.getAllNews().enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
if (response.isSuccessful()) {
if (response.body() != null) {
Log.i("onSuccess", response.body());
String jsonresponse = response.body();
try {
//getting the whole json object from the response
JSONObject obj = new JSONObject(response.body());
JSONArray dataArray = obj.getJSONArray("data");
for (int i = 0; i < dataArray.length(); i++) {
String title, desc, link, date, img, paper;
final Integer id, positive, negative;
JSONObject dataobj = dataArray.getJSONObject(i);
AllPositiveModel item = new AllPositiveModel(dataobj.getInt("id"), dataobj.getString("title"),
dataobj.getString("description"), dataobj.getString("link"),
dataobj.getString("date"), dataobj.getString("image"),
dataobj.getInt("positive_votes"), dataobj.getInt("negative_votes"),
dataobj.getString("paper"));
id = dataobj.getInt("id");
title = dataobj.getString("title");
desc = dataobj.getString("description");
link = dataobj.getString("link");
date = dataobj.getString("date");
img = dataobj.getString("image");
positive = dataobj.getInt("positive_votes");
negative = dataobj.getInt("negative_votes");
paper = dataobj.getString("paper");
items.add(item);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.i("onEmptyResponse", "Returned empty response");
}
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
}
});
return items;
}
}
I have managed to solve the problem:
I have initialized adapter and recyclerview inside method getResult()
adapter = new NewsAdapterTrue(TrueNewsList, getActivity());
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
But I am still confused why my list is getting deleted from memory after it's being populated. I have almost same fragment and there is working just fine. I hope someone will answer me.
After a long search on the internet I couldn't find any solution to meet my requirements.
I have one array list which is passed into the dialog fragment, but my requirement is:
When the user selects the date it calls the web service again and gets another data according to data and passes the same dialog fragment. How can I achieve that ? I have tried with static value but its not clearing the value. My code is:
public static class DatePickerDialogFragment extends DialogFragment implements
DatePickerDialog.OnDateSetListener
{
String userName;
public interface UserUserIdListener {
void updateIdUserName(String userName);
}
public static final int FLAG_START_DATE = 0;
public static final int FLAG_END_DATE = 1;
public static List<Orederlist>reportorderIdList=new ArrayList<>();
// private List<Userlist> reportUserList = new ArrayList<>();
private int flag = 0;
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
return new DatePickerDialog(getActivity(), this, year, month, day);
}
public void setFlag(int i) {
flag = i;
}
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
Calendar calendar = Calendar.getInstance();
Calendar calendar1=Calendar.getInstance();
calendar1.set(year, monthOfYear, dayOfMonth);
calendar.set(year, monthOfYear, dayOfMonth);
String reportOrderIds="";
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
if (flag == FLAG_START_DATE) {
textviewFromDate.setText(format.format(calendar.getTime()));
fromDateReport=textviewFromDate.getText().toString();
JSONObject pieObject = new JSONObject();
try
{
pieObject.put("fromDate",""+fromDateReport);
pieObject.put("orderId",""+reportOrderIds);
pieObject.put("password",""+sPrefs.getString(Constants.PASSWORD,""));
pieObject.put("toDate",""+toDateReport);
pieObject.put("user",""+sPrefs.getString(Constants.USER_NAME,""));
pieObject.put("subUser",""+reportSubUsers);
progressDialog = new ProgressDialog(getContext());
progressDialog.setMessage("Loading....");
progressDialog.setCancelable(false);
progressDialog.show();
} catch (Exception e)
{
e.printStackTrace();
}
// String TAG = "delivered";
RequestQueue requestQueue = Volley.newRequestQueue(getContext());
JsonObjectRequest jsOnbjRequest = new
JsonObjectRequest(Request.Method.POST,
Constants.GetSummarizedReports, pieObject,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response)
{
progressDialog.dismiss();
try {
JSONArray jsonArray = (JSONArray) response.get("orderlist");
{
if (jsonArray.length()>0)
{
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json = jsonArray.getJSONObject(i);
// Integer name = json.optInt();
String name = json.optString("orderId").toString();
Orederlist user = new Orederlist(name);
user.setOrderId(name);
reportorderIdList.add(user);
}}
}
} catch (Exception e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
}
}) {
#Override
public String getBodyContentType() {
return "application/json";
}
};
jsOnbjRequest.setRetryPolicy(new DefaultRetryPolicy(500000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
requestQueue.add(jsOnbjRequest);
} else if (flag == FLAG_END_DATE) {
textviewToDate.setText(format.format( calendar1.getTime()));
toDateReport= textviewToDate.getText().toString();
JSONObject pieObject = new JSONObject();
try
{
pieObject.put("fromDate",""+fromDateReport);
pieObject.put("orderId",""+reportOrderIds);
pieObject.put("password",""+sPrefs.getString(Constants.PASSWORD,""));
pieObject.put("toDate",""+toDateReport);
pieObject.put("user",""+sPrefs.getString(Constants.USER_NAME,""));
pieObject.put("subUser",""+reportSubUsers);
progressDialog = new ProgressDialog(getContext());
progressDialog.setMessage("Loading....");
progressDialog.setCancelable(false);
progressDialog.show();
} catch (Exception e)
{
e.printStackTrace();
}
// String TAG = "delivered";
RequestQueue requestQueue = Volley.newRequestQueue(getContext());
JsonObjectRequest jsOnbjRequest = new
JsonObjectRequest(Request.Method.POST,
Constants.GetSummarizedReports, pieObject,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response)
{
progressDialog.dismiss();
try {
JSONArray jsonArray = (JSONArray) response.get("orderlist");
{
if (jsonArray.length()>0)
{
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json = jsonArray.getJSONObject(i);
// Integer name = json.optInt();
String name = json.optString("orderId").toString();
Orederlist user = new Orederlist(name);
user.setOrderId(name);
reportorderIdList.add(user);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
}
}) {
#Override
public String getBodyContentType() {
return "application/json";
}
};
jsOnbjRequest.setRetryPolicy(new DefaultRetryPolicy(500000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
requestQueue.add(jsOnbjRequest);
}
}
}
and for dialog fragment pass data is :
FragmentManager managerOrderIds = getSupportFragmentManager();
UserJobIds dialogOrderIds = new UserJobIds();
dialogOrderIds.setdata(orderIdList,reportorderIdList);//with static array list which is not claer the value
dialogOrderIds.show(managerOrderIds, "Dialog");
What you can do is just create a newInstance of Dialog Fragment assign data to it, then call show().Below is an example.
public class D2Fragment extends DialogFragment {
private ArrayList<String> list;
public static D2Fragment getInstanceFor(ArrayList<String> list){
D2Fragment d2Fragment=new D2Fragment();
d2Fragment.list=list;
return d2Fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.item_dialog, container,
false);
getDialog().setTitle("DialogFragment Sample");
Log.e("size",list.size()+"");// Here is the list
// Do something else
return rootView;
}
}
When you show dialog.
ArrayList<String> list=new ArrayList<>();
list.add("Val1");
list.add("Val2");
D2Fragment d2Fragment=D2Fragment.getInstanceFor(list);
d2Fragment.show(getSupportFragmentManager(),"dialog2");
Or just create a setter for your data.
public class D2Fragment extends DialogFragment {
private ArrayList<String> list;
public void setData(ArrayList<String> list){
this.list=list;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.item_dialog, container,
false);
getDialog().setTitle("DialogFragment Sample");
Log.e("size",list.size()+"");// Here is the list
// Do something else
return rootView;
}
}
and to show Dialog.
ArrayList<String> list = new ArrayList<>();
list.add("Val1");
list.add("Val2");
D2Fragment d2Fragment = new D2Fragment();
d2Fragment.setData(list);
d2Fragment.show(getSupportFragmentManager(), "dialog2");
In activity you can always find that particular DialgFragment by tag you assigned at the time of transaction.
Fragment fragment=getSupportFragmentManager().findFragmentByTag("dialog2");
if(fragment!=null && fragment instanceof D2Fragment){
((D2Fragment)fragment).call();// You can call any public method of this dialog fragment here
}
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.
i have two activty A and B in my app. i am loading data from api in my listview using json and store that data in listview using getter setter method
in activity A.
now i want to maintain data in listview after start B activity and when i back from B to A activity i dont wont to download data again from json.
i am right now doing it by sotirng api responce in string and after back from B to A i pass json string to adapter but it still take time to load listview
any idea how to prevent loading time and getting data instantly when i back from B to A.
here is code of my activty A
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_product_list);
pref =getSharedPreferences("MyPrefs", Context.MODE_PRIVATE);
editor = pref.edit();
itemCount_database = new ItemCount_database(this);
item_adding_cart = new Item_adding_cart(this);
String fromhome =pref.getString("from_product_view_back_Btn","");
if(fromhome.equals("yes"))
{
editor.putString("from_product_view_back_Btn","no");
editor.commit();
overridePendingTransition(R.anim.right_in, R.anim.right_out);
stored_json();
recycler_adapter = new Product_list_Recycler_Adapter(this,datalist);
recyclerView.setAdapter(recycler_adapter);
recycler_adapter.setListener(ProductList_Activity.this);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
}
else
{
overridePendingTransition(R.anim.left_in, R.anim.left_out);
pDialog = new ProgressDialog(this);
pDialog.setMessage("Loading...");
pDialog.show();
jsoncall();
}
initialised_actionbar();
checkout = (TextView)findViewById(R.id.txt_checkout_product_list);
txt_total_amount =(TextView)findViewById(R.id.total_amount_in_checkout_label);
checkout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent myint = new Intent(ProductList_Activity.this,Cart.class);
startActivity(myint);
}
});
footer =(LinearLayout) findViewById(R.id.footer);
footer.setVisibility(View.GONE);
cart_item_count =item_adding_cart.total_product_count(1);
if(cart_item_count==0 )
{
footer.setVisibility(View.GONE);
cart_count_background.setVisibility(View.GONE);
}
else
{
footer.setVisibility(View.VISIBLE);
cart_count_background.setVisibility(View.VISIBLE);
}
wishlist_item_count = item_adding_cart.getrowcount_wishlist();
if(wishlist_item_count==0)
{
// wishlist_count_backround.setVisibility(View.GONE);
}
else
{
// wishlist_count_backround.setVisibility(View.VISIBLE);
}
recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
initialization();
hidePDialog();
}
}, 3000);
boolean popup_once=pref.getBoolean("total_item_cart_insert_qery",true);
if(popup_once)
{
editor.putBoolean("total_item_cart_insert_qery",false);
editor.commit();
item_adding_cart.insert_total_item_in_cart(0);
}
}
public void jsoncall() {
final HashMap<String, String> params = new HashMap<String, String>();
params.put("sub_cate_id","24");
params.put("city_id","3");
CustomRequest_JsonObject servicelistrequest = new CustomRequest_JsonObject
(/*Request.Method.POST,*/
url,
params,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
stored_json_string = response.toString();
editor.putString("stored_json_prodcutlist",stored_json_string);
editor.commit();
try {
JSONArray data = response.getJSONArray("data");
for (int ie = 0; ie < data.length(); ie++) {
JSONObject dataobje = data.getJSONObject(ie);
ModelData_Product_list_act Model = new ModelData_Product_list_act();
Model.setProduct_id(dataobje.getString("product_id"));
Model.setTitle(dataobje.getString("title"));
Model.setImage(dataobje.getString("product_image"));
Model.setWieght(dataobje.getString("weight"));
Model.setLatest_price(dataobje.getString("mrp"));
Model.setDiscount(dataobje.getString("discount"));
Model.setPre_price(dataobje.getString("retail_price"));
Model.setUnit(dataobje.getString("unit"));
datalist.add(Model);
loadlistview();
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_LONG).show();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
hidePDialog();
Toast.makeText(getApplicationContext(), "error : " + error.getMessage(), Toast.LENGTH_LONG).show();
}
}
);
AppController.getInstance().addToRequestQueue(servicelistrequest);
}
public void stored_json() {
pDialog = new ProgressDialog(this);
pDialog.setMessage("Loading...");
pDialog.show();
String mystored_json = pref.getString("stored_json_prodcutlist","");
try {
JSONObject myjsonojb = new JSONObject(mystored_json);
JSONArray data = myjsonojb.getJSONArray("data");
for (int ie = 0; ie < data.length(); ie++) {
JSONObject dataobje = data.getJSONObject(ie);
ModelData_Product_list_act Model = new ModelData_Product_list_act();
Model.setProduct_id(dataobje.getString("product_id"));
Model.setTitle(dataobje.getString("title"));
Model.setImage(dataobje.getString("product_image"));
Model.setWieght(dataobje.getString("weight"));
Model.setLatest_price(dataobje.getString("mrp"));
Model.setDiscount(dataobje.getString("discount"));
Model.setPre_price(dataobje.getString("retail_price"));
Model.setUnit(dataobje.getString("unit"));
datalist.add(Model);
// loadlistview();
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_LONG).show();
}
}
Instead of using startActivity use startActivityForResult(yourIntent,REQ_CODE)
Intent startActivity = new Intent(context,ClassName.class);
startActivityForResult(startActivity,REQ_CODE);
after your come back from Activity B ,so can send your list from activity and can get in Activity A.
Then onActivityResult callback method get your intent data
I Have another idea use background task is on create and store it to local db and display the data from local db in on resume .you always call list view from local db so when you come back b to a on resume will call so it will not call on create so it will not call background data
How can i pass the position of item using intent to start a new activity?
I want to start a new activity called single which displays the rating of the movie correspondingly..pls help
I have been trying this for the past two days.
Here is the code:
public class NowPlaying extends Fragment {
private static final String TAG = NowPlaying.class.getSimpleName();
// Movies json url
private static final String url = "http://private-8149-themoviedb.apiary-mock.com/3/movie/now_playing?api_key=";
private ProgressDialog pDialog;
private List<NowPlayingInfo> bottom = new ArrayList<NowPlayingInfo>() ;
NowPlayingAdapter adapter;
RecyclerView recyclerView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_main, container, false);
ActionBar toolbar = ((AppCompatActivity) getActivity()).getSupportActionBar();
toolbar.setTitle("Now playing");
recyclerView = (RecyclerView) v.findViewById(R.id.cardList);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(linearLayoutManager);
adapter = new NowPlayingAdapter(getActivity(), bottom);
recyclerView.setAdapter(adapter);
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Loading...");
pDialog.show();
adapter.SetOnItemClickListener(new NowPlayingAdapter.OnItemClickListener() {
#Override
public void onItemClick(View v, int position) {
// do something with position
Intent i = new Intent(v.getContext(), Single.class);
//pass the position of the item to single class
v.getContext().startActivity(i);
}
});
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, response.toString());
hidePDialog();
try {
JSONArray jsonArray = response.getJSONArray("results");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
NowPlayingInfo trailer = new NowPlayingInfo();
trailer.setTitle(jsonObject.getString("original_title"));
String iss = "http://image.tmdb.org/t/p/w500" + jsonObject.getString("poster_path") ;
trailer.setImage(iss);
bottom.add(trailer);
adapter.notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
}
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
AppController.getInstance().addToRequestQueue(jsonObjectRequest);
return v;
}
#Override
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
}
adapter.SetOnItemClickListener(new NowPlayingAdapter.OnItemClickListener() {
#Override
public void onItemClick(View v, int position) {
NowPlayingInfo _nowPlaying = bottom.get(position);
// do something with position
Intent i = new Intent(v.getContext(), Single.class);
//pass the position of the item to single class
i.putExtra("ISS", _nowPlaying.getImage()); //you can put your current playing info.
i.putExtra("POSITION", position); //you can put your position to next activity.
v.getContext().startActivity(i);
}
});
Add this in your SingleInfo Class.
String _rating = "";
public String get_rating() {
return _rating;
}
public void set_rating(String _rating) {
this._rating = _rating;
}
Add this in your Single class -
int _currentPos = 0 ; //Global variable .
_currentPos = getIntent().getIntExtra("position", 0);// paste this in onCreate()
Add this code in onResponse of Single Class -
try {
JSONArray jsonArray = response.getJSONArray("results");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
SingleInfo s = new SingleInfo();
s.set_rating(jsonObject.getString("rating"));
single.add(s);
}
//changed by Shoeb
SingleInfo _singleInfo = single.get(_currentPos); //position from previous activity
textView.setText(_singleInfo.get_rating());
//end changes
} catch (JSONException e) {
e.printStackTrace();
}
Add an extra to your intent
i.putExtra("position",position);
And on the other activity:
getIntent().getIntExtra("position", 0);