Recyclerview Out Of Memory Error (using Volley) - java

I'm using Volley to fetch data from a json array and I'm facing some real problems on loading more data! I've set OFFSET in my SQL Query to send 10 item, each time Android send a page number to get more data! It works perfectly and I've already tested my php codes with Postman application and there is no problem with that! I guess something is wrong about my recyclerview or the way I'm fetching data from server that cause out of memory issue! so please if you take a look at my code probably you could find the problem!
here is my code:
My Adapter:
public class ReviewsAdapter extends RecyclerView.Adapter<ReviewsAdapter.ReviewsHolder> {
private Context context;
private ArrayList<ReviewsList> reviewsList;
public ReviewsAdapter(ArrayList<ReviewsList> reviewsList, Context context) {
this.reviewsList = reviewsList;
this.context = context;
}
#Override
public ReviewsAdapter.ReviewsHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ReviewsAdapter.ReviewsHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.row_reviews, parent, false));
}
private float f;
#Override
public void onBindViewHolder(ReviewsAdapter.ReviewsHolder holder, int position) {
holder.userName.setText(reviewsList.get(position).getSentBy());
for (f = 0.0f; f <= 5.0f; f += 0.5f) {
if (f == Float.valueOf(reviewsList.get(position).getRate())) {
holder.ratingBar.setRating(f);
}
}
holder.date.setText(reviewsList.get(position).getDate());
holder.Ctext.setText(reviewsList.get(position).getCText());
}
#Override
public int getItemCount() {
return reviewsList.size();
}
class ReviewsHolder extends RecyclerView.ViewHolder {
TextView userName, date;
JustifiedTextView Ctext;
RatingBar ratingBar;
ReviewsHolder(View view) {
super(view);
userName = view.findViewById(R.id.userName);
ratingBar = view.findViewById(R.id.commentRate);
date = view.findViewById(R.id.commentDate);
Ctext = view.findViewById(R.id.commentText);
}
}
}
List.java:
public class ReviewsList {
private int Cid;
private String sentBy, rate, date, Ctext;
public ReviewsList(int Cid, String sentBy, String rate, String date, String Ctext) {
this.sentBy = sentBy;
this.rate = rate;
this.date = date;
this.Ctext = Ctext;
this.Cid = Cid;
}
public String getSentBy() {
return sentBy;
}
public String getRate() {
return rate;
}
public String getDate() {
return date;
}
public String getCText() {
return Ctext;
}
}
My Activity:
public class ReviewsActivity extends AppCompatActivity {
private int page = 0;
private boolean itShouldLoadMore = true;
private RecyclerView recyclerView;
LinearLayoutManager linearLayoutManager;
private ArrayList<ReviewsList> reviewsLists;
private ReviewsAdapter reviewsAdapter;
TextView noMoreData;
NestedScrollView nestedScrollView;
#Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reviews);
noMoreData = findViewById(R.id.NoMoreDataTxt);
reviewsLists = new ArrayList<>();
reviewsAdapter = new ReviewsAdapter(reviewsLists, getApplicationContext());
linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView = findViewById(R.id.RecyclerView);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(reviewsAdapter);
firstLoadData();
recyclerView.setNestedScrollingEnabled(false);
nestedScrollView = findViewById(R.id.nestedScrollView);
nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
#Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
int totalItemCount = linearLayoutManager.getItemCount();
int lastVisible = linearLayoutManager.findLastVisibleItemPosition();
boolean endHasBeenReached = lastVisible + 5 >= totalItemCount;
if (totalItemCount > 0 && endHasBeenReached) {
loadMore();
}
}
});
recyclerView.setNestedScrollingEnabled(false);
}
public void firstLoadData() {
String url = "https://oh-music.ir/parastar/get_reviews.php?page=1" + "&nurseId=" + theId;
itShouldLoadMore = false;
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
itShouldLoadMore = true;
if (response.length() <= 0) {
noMoreData.setVisibility(View.VISIBLE);
return;
}
for (int i = 0; i < response.length(); i++) {
try {
JSONObject jsonObject = response.getJSONObject(i);
int id = jsonObject.getInt("id");
String sent_by = jsonObject.getString("sent_by");
String rate = jsonObject.getString("rate");
String date = jsonObject.getString("date");
String text = jsonObject.getString("text");
reviewsLists.add(new ReviewsList(id, sent_by, rate, date, text));
reviewsAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
itShouldLoadMore = true;
String message = "";
new VolleyErrorHandler(getApplicationContext(), error, message);
}
});
//Pay Attention to this line is this causing the crashing?
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(jsonArrayRequest);
}
private void loadMore() {
String url = "https://oh-music.ir/parastar/get_reviews.php?action=loadmore&page=" + String.valueOf(page++) + "&nurseId=" + theId;
itShouldLoadMore = false;
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
itShouldLoadMore = true;
if (response.length() <= 0) {
noMoreData.setVisibility(View.VISIBLE);
return;
}
for (int i = 0; i < response.length(); i++) {
try {
JSONObject jsonObject = response.getJSONObject(i);
int id = jsonObject.getInt("id");
String sent_by = jsonObject.getString("sent_by");
String rate = jsonObject.getString("rate");
String date = jsonObject.getString("date");
String text = jsonObject.getString("text");
reviewsLists.add(new ReviewsList(id, sent_by, rate, date, text));
reviewsAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
itShouldLoadMore = true;
String message = "";
new VolleyErrorHandler(getApplicationContext(), error, message);
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(jsonArrayRequest);
}
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen()) {
drawer.closeDrawer();
} else {
super.onBackPressed();
}
}
}
As you may ask for logcat errors, I've to say that there are lots of errors but not with red color! Here is some of them:
It starts like this:
Continues like this for about 100 lines of code:
And ends with these:
I will really appreciate your help ♥ Thanks for your time...
EDIT: I've to say that when recyclerview reaches the end and tries to load more data, it reproduce the previous items again! for example if there are 7 items it load 7 more items (the same items). and after some scroll up and down the app crashes.

I would say that this happens because you're disabling nested scrolling of the RecyclerView and also putting the RecyclerView inside the NestedScrollView resulting in the RecyclerView to load all the items at once and not to recycle any views which result in OOM and performance issues.
Solution:
Remove the NestedScrollView and set the ScrollListener on the RecyclerView directly.
Delete recyclerView.setNestedScrollingEnabled(false);

Related

How to add a search filter in RecyclerView to filter through parsed JSON data? edited

I am developing an android app which shows a list of countries affected by Coronavirus , the total number of confirmed cases and total Deaths. I am using a JSON API to get the data and displaying it using a RecyclerView . The app works fine , and i get a list of all the countries with their respective case counts. I want to add a search option so that the users can filter the list and find a specific country. How do i do that? I am new to programming , if someone could help with this that would be awesome.
Here is the code snippet
MainActivity.java
private RecyclerView mRecyclerView;
private Corona_Stats_Adapter mCorona_Stats_Adapter;
private TextView mErrorDisplay;
private ProgressBar mProgressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.corona_stats);
mRecyclerView = (RecyclerView)findViewById(R.id.Corona_stats_recycler);
mErrorDisplay = (TextView) findViewById(R.id.tv_error_message_display);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setHasFixedSize(true);
mCorona_Stats_Adapter = new Corona_Stats_Adapter();
mRecyclerView.setAdapter(mCorona_Stats_Adapter);
mProgressBar = (ProgressBar)findViewById(R.id.pb_loading_indicator) ;
loadCoronaData();
}
private void loadCoronaData(){
showCoronaDataView();
//String Country = String.valueOf(mSearchQuery.getText());
new Fetch_data().execute();
}
private void showCoronaDataView(){
mErrorDisplay.setVisibility(View.INVISIBLE);
mRecyclerView.setVisibility(View.VISIBLE);
}
private void showErrorMessage(){
mRecyclerView.setVisibility(View.INVISIBLE);
mErrorDisplay.setVisibility(View.VISIBLE);
}
public class Fetch_data extends AsyncTask<Void,Void,String[]> {
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressBar.setVisibility(View.VISIBLE);
}
#Override
protected String[] doInBackground(Void... voids) {
URL covidRequestURL = NetworkUtils.buildUrl();
try {
String JSONCovidResponse = NetworkUtils.getResponseFromHttpUrl(covidRequestURL);
String[] simpleJsonCovidData = CovidJSON_Utils.getSimpleStringFromJson(MainActivity.this, JSONCovidResponse);
return simpleJsonCovidData;
} catch (IOException | JSONException e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(String[] coronaData) {
mProgressBar.setVisibility(View.INVISIBLE);
if(coronaData !=null){
showCoronaDataView();
mCorona_Stats_Adapter.setCoronaData(coronaData);
} else{
showErrorMessage();
}
}
}
}
RecyclerView Adapter class Corona_stats_Adapter.java
public class Corona_Stats_Adapter extends RecyclerView.Adapter<Corona_Stats_Adapter.Corona_Stats_AdapterViewHolder>
{
private Context context;
// private List<Country> countryList;
// private List<Country> countryListFiltered;
private String[] mCoronaData;
public Corona_Stats_Adapter(){
}
#NonNull
#Override
public Corona_Stats_AdapterViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int viewType) {
Context context = viewGroup.getContext();
int LayoutIdForListItem =R.layout.corona_stats_list_item;
LayoutInflater inflater =LayoutInflater.from(context);
boolean ShouldAttachToParentImmediately = false;
View view = inflater.inflate(LayoutIdForListItem,viewGroup,ShouldAttachToParentImmediately);
return new Corona_Stats_AdapterViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull Corona_Stats_AdapterViewHolder corona_stats_adapterViewHolder, int position) {
String coronaStats = mCoronaData[position];
corona_stats_adapterViewHolder.mCoronaTextView.setText(coronaStats);
}
#Override
public int getItemCount() {
if(null == mCoronaData) return 0;
return mCoronaData.length;
// return countryListFiltered.size();
}
public class Corona_Stats_AdapterViewHolder extends RecyclerView.ViewHolder {
public final TextView mCoronaTextView;
public Corona_Stats_AdapterViewHolder(#NonNull View view) {
super(view);
mCoronaTextView = (TextView) view.findViewById(R.id.tv_corona_data);
}
}
public void setCoronaData(String[] coronaData){
mCoronaData = coronaData;
notifyDataSetChanged();
}
}
Parsing the JSON data in CovidJSON_Utils.java
public final class CovidJSON_Utils {
public static String[] getSimpleStringFromJson(Context context, String codivJsonString)
throws JSONException {
final String COV_COUNTRY = "Countries";
final String COV_CONFIRMED = "confirmed";
final String COV_DEATHS = "deaths";
final String COV_MESSAGE_CODE = "code";
String[] parsedCovidData = null;
JSONObject covidJsonObject = new JSONObject(codivJsonString);
if (covidJsonObject.has(COV_MESSAGE_CODE)) {
int errorCode = covidJsonObject.getInt(COV_MESSAGE_CODE);
switch (errorCode) {
case HttpURLConnection.HTTP_OK:
break;
case HttpURLConnection.HTTP_NOT_FOUND:
return null;
default:
return null;
}
}
JSONArray countryCovidArray = covidJsonObject.getJSONArray(COV_COUNTRY);
parsedCovidData = new String[countryCovidArray.length()];
for (int i = 0; i < countryCovidArray.length(); i++) {
JSONObject countryJSONObject = countryCovidArray.getJSONObject(i);
String Country = countryJSONObject.getString("Country");
String Confirmed = String.valueOf(countryJSONObject.getInt("TotalConfirmed"));
String Deaths = String.valueOf(countryJSONObject.getInt("TotalDeaths"));
parsedCovidData[i] = Country + "- Cases " + Confirmed + "- Deaths " + Deaths;
}
return parsedCovidData;
}
}
The problem is with below initialization in the MainActivity.Oncreate method
mCorona_Stats_Adapter = new Corona_Stats_Adapter(this,countries);
Initialize the adapter in onPostExecute method with updated countries data.
Hope this will help you.
You have to set arraylist to update country data in adapter after getting data from the server.
Public void setCoronaData (Arraylist coronaData) {
countryList = coronaData;
notifyDataSetChanged ();
}

Layout Refresh issues in Activity with Tabs

Its an Activity with Tabs, I'm getting data from API using Volley library. There is only one Fragment. Whenever Tab is changed either by sliding or clicking the Tab, the function that calls the APIs is called with different data.
Problems:
1) It loads items every time on working internet, but it sometimes shows and sometimes not. When I press home button (i.e. activity is running and in background) and then select the app from opened apps list it shows data. I've to pause and resume app to view changes by pressing home button and reselecting from opened apps. If I lock screen and unlock screen then also it shows the content.
2) Similar to problem 1) there is an info button on top right corner it shows/hides a layout when clicked. But some time when problem 1) occurs it also behaves same.
3) Also looks similar to 1) and 2) there is TextView (Options) that shows/hides a layout when clicked But some time when problem 1) occurs it also behaves same.
Any help would be appreciated, I'm running out of time...
Here is screenshot: Screenshot
RestaurantDetailActivity.java
public class RestaurantDetailActivity extends AppCompatActivity {
LinearLayout contactLayout;
TabLayout tabLayout;
ViewPager viewPager;
TextView nameTv, descrTv, timingsTv, totalRatingsTv;
RatingBar ratingsRb;
ImageView restaurantIv;
String resId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_restaurant_detail);
//get data from previews activity
Intent intent = getIntent();
//init views
nameTv = findViewById(R.id.nameTv);
ratingsRb = findViewById(R.id.ratingsRb);
descrTv = findViewById(R.id.descrTv);
timingsTv = findViewById(R.id.timingsTv);
totalRatingsTv = findViewById(R.id.totalRatingsTv);
contactLayout = findViewById(R.id.contactLayout);
tabLayout = findViewById(R.id.tabLayout);
viewPager = findViewById(R.id.viewPager);
timingsTv = findViewById(R.id.timingsTv);
restaurantIv = findViewById(R.id.restaurantIv);
resId = intent.getStringExtra("id");
//setup tabs
setupViewPager(viewPager);
tabLayout.setupWithViewPager(viewPager);
final String name = intent.getStringExtra("name");
final String ratings = intent.getStringExtra("ratings");
String description = intent.getStringExtra("description");
String status = intent.getStringExtra("status");
String resPaused = intent.getStringExtra("resPaused");
String open = intent.getStringExtra("openTime");
String close = intent.getStringExtra("closeTime");
//set data in header
nameTv.setText(name);
ratingsRb.setRating(Float.parseFloat(ratings));
descrTv.setText(description);
final String timings;
if (resPaused.equals("0")) {
timings = con24to12(open) + " - " + con24to12(close);timingsTv.setTextColor(getApplicationContext().getResources().getColor(R.color.colorWhite));
} else {
timings = "Closed Today";
timingsTv.setTextColor(getApplicationContext().getResources().getColor(R.color.colorRadish));
}
//set timings
if (Utils.compareOpenTime(open)) {
timingsTv.setTextColor(getApplicationContext().getResources().getColor(R.color.colorWhite));
timingsTv.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_time_white, 0, 0, 0);
timingsTv.setText(con24to12(open));
} else {
timingsTv.setText(timings);
}
totalRatingsTv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent1 = new Intent(getApplicationContext(), RestaurantReviewsActivity.class);
intent1.putExtra("restId", resId);
intent1.putExtra("restName", name);
intent1.putExtra("restRatings", ratings);
startActivity(intent1);
}
});
final Bitmap b = BitmapFactory.decodeFile(getExternalCacheDir() + "/TopServeImages" + "/" + intent.getStringExtra("image"));
restaurantIv.setImageBitmap(b);
}
ViewPagerAdapter adapter;
private void setupViewPager(ViewPager viewPager) {
adapter = new ViewPagerAdapter(getSupportFragmentManager());
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Getting Menu...");
progressDialog.show();
String token = "auth" + System.currentTimeMillis();
Map<String, String> params = new HashMap<>();
params.put("Token", token);
params.put("RestaurantID", resId);
Log.d("TheToken", Utils.getToken() + "" + Utils.getEmail());
String url = ApiManager.headerUrl + ApiManager.menuItemsUrl;
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST,
url, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
progressDialog.dismiss();
Log.d("TheResponse", response.toString());
try {
JSONObject jsonObject = response.getJSONObject("Response");
JSONArray jsonArray = jsonObject.getJSONArray("MenuCategories");
for (int i = 0; i < jsonArray.length(); i++) {
String menuItemCategoryID = jsonArray.getJSONObject(i).getString("MenuItemCategoryID");
String name = jsonArray.getJSONObject(i).getString("Name");
String restaurantID = jsonArray.getJSONObject(i).getString("RestaurantID");
adapter.addFragment(RestaurantFragment.newInstance((i + 1), "" + name, restaurantID, menuItemCategoryID), "" + name);
adapter.notifyDataSetChanged();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Exception: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
try {
if (error.getMessage().toLowerCase().contains("no address associated with hostname")) {
Toast.makeText(getApplicationContext(), "Slow or no Internet connection...", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
Volley.newRequestQueue(this).add(jsonObjReq);
viewPager.setAdapter(adapter);
}
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> fragmentList = new ArrayList<>();
private final List<String> fragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
#Override
public int getCount() {
return fragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
fragmentList.add(fragment);
fragmentTitleList.add(title);
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return fragmentTitleList.get(position);
}
}
public void clicks(View view) {
if (view == findViewById(R.id.backTv)) {
onBackPressed();
} else if (view == findViewById(R.id.infoBtn)) {
if (contactLayout.getVisibility() == View.GONE) {
contactLayout.setVisibility(View.VISIBLE);
} else {
contactLayout.setVisibility(View.GONE);
}
}
}
public String con24to12(String from) {
DateFormat df = new SimpleDateFormat("HH:mm:ss");
DateFormat outputformat = new SimpleDateFormat("hh:mm aa");
Date date = null;
String output = null;
try {
date = df.parse(from);
output = outputformat.format(date);
from = output;
} catch (Exception pe) {
Toast.makeText(getApplicationContext(), "" + pe.getMessage(), Toast.LENGTH_SHORT).show();
}
return from;
}
}
RestaurantFragment.java
public class RestaurantFragment extends Fragment {
String title;
int page;
String restaurantId;
String menuItemCategoryID;
AdapterMenu mAdapter;
List<ModelMenu> menuList;
ImageView fabCartIv;
RecyclerView recyclerView;
public RestaurantFragment() {
}
public static RestaurantFragment newInstance(int page, String title, String restID, String menuItemCategoryID) {
RestaurantFragment fragmentFirst = new RestaurantFragment();
Bundle args = new Bundle();
args.putInt("someInt", page);
args.putString("someTitle", title);
args.putString("restId", restID);
args.putString("menuItemCategoryID", menuItemCategoryID);
fragmentFirst.setArguments(args);
return fragmentFirst;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
page = getArguments().getInt("someInt", 0);
title = getArguments().getString("someTitle");
restaurantId = getArguments().getString("restId");
menuItemCategoryID = getArguments().getString("menuItemCategoryID");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_restaurant, container, false);
recyclerView = view.findViewById(R.id.menuRecyclerView);
fabCartIv = view.findViewById(R.id.fabCartIv);
loadMenuItems();
return view;
}
private void loadMenuItems() {
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));
menuList = new ArrayList<>();
String token = "auth" + System.currentTimeMillis();
Map<String, String> params = new HashMap<>();
params.put("Token", token);
params.put("RestaurantID", restaurantId);
String url = ApiManager.headerUrl + ApiManager.menuItemsUrl;
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST,
url, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONObject joResponse = response.getJSONObject("Response");
JSONArray jaMainMenu = joResponse.getJSONArray("MainMenu");
JSONArray jaMenuItemImages = joResponse.getJSONArray("MenuItemImages");
JSONArray jaLinkedMenuItems = joResponse.getJSONArray("LinkedMenuItems");
for (int i = 0; i < jaLinkedMenuItems.length(); i++) {
String menuItemCategoryID1 = jaLinkedMenuItems.getJSONObject(i).getString("MenuItemCategoryID");
if (menuItemCategoryID.equals(menuItemCategoryID1)) {
String menuItemID1 = jaLinkedMenuItems.getJSONObject(i).getString("MenuItemID");
for (int j = 0; j < jaMainMenu.length(); j++) {
String deleted = jaMainMenu.getJSONObject(j).getString("Deleted");
String description = jaMainMenu.getJSONObject(j).getString("Description");
String ingredients = jaMainMenu.getJSONObject(j).getString("Ingredients");
String inventory = jaMainMenu.getJSONObject(j).getString("Inventory");
String menuItemID = jaMainMenu.getJSONObject(j).getString("MenuItemID");
String name = jaMainMenu.getJSONObject(j).getString("Name");
String paused = jaMainMenu.getJSONObject(j).getString("Paused");
String price = jaMainMenu.getJSONObject(j).getString("Price");
String rating = jaMainMenu.getJSONObject(j).getString("Rating");
String restaurantID = jaMainMenu.getJSONObject(j).getString("RestaurantID");
String servedEnd = jaMainMenu.getJSONObject(j).getString("ServedEnd");
String servedStart = jaMainMenu.getJSONObject(j).getString("ServedStart");
String imageURL = jaMenuItemImages.getJSONObject(j).getString("ImageURL");
if (menuItemID1.equals(menuItemID)) {
ModelMenu cModels = new ModelMenu("" + deleted,
"" + description,
"" + ingredients,
"" + inventory,
"" + menuItemID,
"" + name,
"" + paused,
"$" + price,
"" + rating,
"" + restaurantID,
"" + servedEnd,
"" + servedStart,
"" + imageURL);
menuList.add(cModels);
}
}
mAdapter = new AdapterMenu(menuList, getActivity().getApplicationContext(), RestaurantFragment.this);
recyclerView.setAdapter(mAdapter);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
try {
if (error.getMessage().toLowerCase().contains("no address associated with hostname")) {
} else {
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
Volley.newRequestQueue(getActivity()).add(jsonObjReq);
}
}
AdapterMenu.java
public class AdapterMenu extends RecyclerView.Adapter<AdapterMenu.MyHolder> {
List<ModelMenu> menuList;
Context context;
Fragment fragment;
public AdapterMenu(List<ModelMenu> menuList, Context context, Fragment fragment) {
this.menuList = menuList;
this.context = context;
this.fragment = fragment;
}
#NonNull
#Override
public MyHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(context).inflate(R.layout.row_menus, viewGroup, false);
return new MyHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final MyHolder myHolder, int i) {
final String title = menuList.get(i).getName();
final String description = menuList.get(i).getDescription();
final String price = menuList.get(i).getPrice();
final String image = menuList.get(i).getImage();
final String ingredients = menuList.get(i).getIngredients();
final String restaurantID = menuList.get(i).getRestaurantID();
final String menuItemID = menuList.get(i).getMenuItemID();
String notServing;
if (menuList.get(i).getServedStart().equals("null") && menuList.get(i).getServedEnd().equals("null")) {
notServing = "";
myHolder.itemView.setBackgroundColor(context.getResources().getColor(R.color.colorWhite));
} else {
String startTime = Utils.timeTo12hr(menuList.get(i).getServedStart());
String endTime = Utils.timeTo12hr(menuList.get(i).getServedEnd());
notServing = "Only Serving between " + startTime + " - " + endTime;
myHolder.itemView.setBackgroundColor(context.getResources().getColor(R.color.colorGray1));
}
myHolder.titleTv.setText(title);
myHolder.descriptionTv.setText(description);
myHolder.priceTv.setText(price);
myHolder.notServingTv.setText(notServing);
myHolder.addHintTv.setText("Add " + title + " To Order");
myHolder.optionsTv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (myHolder.addItemLayout.getVisibility() == View.VISIBLE) {
myHolder.addItemLayout.setVisibility(View.GONE);
myHolder.optionsTv.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_down_black, 0);
} else {
myHolder.addItemLayout.setVisibility(View.VISIBLE);
myHolder.optionsTv.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_up_black, 0);
}
}
});
myHolder.addItemBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences sp = context.getSharedPreferences("OderSP", Context.MODE_PRIVATE);
int count = sp.getInt("itemCount", 0);
SharedPreferences.Editor editor = sp.edit();
editor.putInt("itemCount", count + 1);
editor.apply();
onAddField(context, myHolder, title, price);
}
});
myHolder.infoBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, MenuDetailActivity.class);
intent.putExtra("title", title);
intent.putExtra("description", description);
intent.putExtra("image", image);
intent.putExtra("ingredients", ingredients);
intent.putExtra("restaurantID", restaurantID);
intent.putExtra("menuItemID", menuItemID);
intent.putExtra("image", image);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
try {
final Bitmap b = BitmapFactory.decodeFile(context.getExternalCacheDir() + "/TopServeImages" + "/" + image);
if (b == null) {
ImageDownloader.execute(new Runnable() {
#Override
public void run() {
new ImageDownloader().awsImageDownload(myHolder, image);
}
});
} else {
myHolder.iconIv.setImageBitmap(b);
}
} catch (Exception e) {
ImageDownloader.execute(new Runnable() {
#Override
public void run() {
new ImageDownloader().awsImageDownload(myHolder, image);
}
});
}
}
private int itemsCount = 0;
private void onAddField(final Context context, MyHolder myHolder, final String title, String price) {
final LinearLayout parentLinearLayout = myHolder.itemView.findViewById(R.id.menu_roLl);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View rowView = inflater.inflate(R.layout.row_additeminfo, null);
parentLinearLayout.addView(rowView, parentLinearLayout.getChildCount() - 1);
final TextView titleTv = rowView.findViewById(R.id.orderInfoTitleTv);
final TextView priceTv = rowView.findViewById(R.id.orderInfoPrice);
final ImageButton removeBtn = rowView.findViewById(R.id.orderInfoRemoveBtn);
itemsCount++;
EasyDB easyDB = EasyDB.init(context, "ITEMS_DB")
.setTableName("ITEMS_TABLE")
.addColumn(new Column("Item_Id", new String[]{"text", "unique"}))
.addColumn(new Column("Item_Name", new String[]{"text", "not null"}))
.addColumn(new Column("Item_Price", new String[]{"text", "not null"}))
.doneTableColumn();
easyDB.addData("Item_Id", title + (parentLinearLayout.getChildCount() - 1))
.addData("Item_Name", title)
.addData("Item_Price", price)
.doneDataAdding();
titleTv.setText("Order: " + itemsCount + " " + title);
priceTv.setText(price);
SharedPreferences sp = context.getSharedPreferences("OderSP", Context.MODE_PRIVATE);
itemsCount = sp.getInt("itemCount", 0);
SharedPreferences.Editor editor = sp.edit();
editor.putInt("itemCount", itemsCount);
editor.apply();
removeBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onDelete(parentLinearLayout, view, title);
}
});
}
private void onDelete(final LinearLayout parentLinearLayout, final View v, final String title) {
AlertDialog.Builder builder = new AlertDialog.Builder(v.getRootView().getContext());
builder.setTitle("Remove this item?");
builder.setMessage(title);
builder.setPositiveButton("Remove", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
parentLinearLayout.removeView((View) v.getParent());
itemsCount--;
SharedPreferences sp = context.getSharedPreferences("OderSP", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putInt("itemCount", itemsCount);
editor.apply();
EasyDB easyDB = EasyDB.init(context, "ITEMS_DB")
.setTableName("ITEMS_TABLE")
.addColumn(new Column("Item_Id", new String[]{"text", "unique"}))
.addColumn(new Column("Item_Name", new String[]{"text", "not null"}))
.addColumn(new Column("Item_Price", new String[]{"text", "not null"}))
.doneTableColumn();
easyDB.deleteRow("Item_Id", "" + title + (parentLinearLayout.getChildCount()));
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
builder.create().show();
}
#Override
public int getItemCount() {
return menuList.size();
}
class MyHolder extends RecyclerView.ViewHolder {
TextView titleTv, priceTv, descriptionTv, notServingTv, addHintTv, optionsTv, orderInfoTitleTv, orderInfoPrice;
ImageButton infoBtn, orderInfoRemoveBtn;
ImageView iconIv;
Button addItemBtn;
LinearLayout addItemLayout;
RelativeLayout orderInfoLayout;
MyHolder(#NonNull View itemView) {
super(itemView);
iconIv = itemView.findViewById(R.id.iconIv);
titleTv = itemView.findViewById(R.id.titleTv);
priceTv = itemView.findViewById(R.id.priceTv);
descriptionTv = itemView.findViewById(R.id.descriptionTv);
notServingTv = itemView.findViewById(R.id.notServingTv);
addHintTv = itemView.findViewById(R.id.addHintTv);
optionsTv = itemView.findViewById(R.id.optionsTv);
orderInfoTitleTv = itemView.findViewById(R.id.orderInfoTitleTv);
orderInfoPrice = itemView.findViewById(R.id.orderInfoPrice);
infoBtn = itemView.findViewById(R.id.infoBtn);
orderInfoRemoveBtn = itemView.findViewById(R.id.orderInfoRemoveBtn);
addItemBtn = itemView.findViewById(R.id.addItemBtn);
addItemLayout = itemView.findViewById(R.id.addItemLayout);
orderInfoLayout = itemView.findViewById(R.id.orderInfoLayout);
}
}
}
Here is how I fixed the issue:
First, understand the problem.
In the first activity where you fetch the restaurant list, that is fine.
When the restaurant is clicked, you pass the restaurant id to the RestaurantDetailActivity and do an API request.
In the API request you pass the restaurant id and get the response. The response contains a lost of all the categories of that restaurant and also the list of all the dishes provided by the restaurant in all the categories. This is very important.
At this stage you take only the list of categories in the response and start creating a fragment for each category. You pass the category id to each fragment.
Then each fragment does an API request to the the same API which was called at the activity level (point number 3 above). Each fragment does the same request independently and extracts only the list of menu items that belong to that category. That is a waste of resources.
When a fragment goes out of view , it is destroyed and then recreated when user swipes back to the tab. Every time user comes to a fragment, it loads data again. This repeated loading of data was causing the device to go unresponsive.
Now here is what I did. At step 3, when a string request is done for a particular restaurant and all the menu items are received in response. I create a separate List of menu items for each category at this stage and then pass the list to each fragment. Now each fragment has to just display the list it has received from the activity. Each fragment is not responsible for doing its own string request and parsing it to creating its own list of items. Rather it just received the list from activity and displays it. In this was only one API request is done at activity level. No matter how many time the user switches tabs, there is no extra API request.
public class ModelMenu implements Serializable {
private String deleted, description, ingredients, inventory, menuItemID, name, paused, price, rating, restaurantID, servedEnd, servedStart, image;
public ModelMenu() {
}
public ModelMenu(String name, String price) {
this.name = name;
this.price = price;
}
public ModelMenu(String deleted, String description, String ingredients, String inventory, String menuItemID, String name, String paused, String price, String rating, String restaurantID, String servedEnd, String servedStart, String image) {
this.deleted = deleted;
this.description = description;
this.ingredients = ingredients;
this.inventory = inventory;
this.menuItemID = menuItemID;
this.name = name;
this.paused = paused;
this.price = price;
this.rating = rating;
this.restaurantID = restaurantID;
this.servedEnd = servedEnd;
this.servedStart = servedStart;
this.image = image;
}
public String getDeleted() {
return deleted;
}
public void setDeleted(String deleted) {
this.deleted = deleted;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getIngredients() {
return ingredients;
}
public void setIngredients(String ingredients) {
this.ingredients = ingredients;
}
public String getInventory() {
return inventory;
}
public void setInventory(String inventory) {
this.inventory = inventory;
}
public String getMenuItemID() {
return menuItemID;
}
public void setMenuItemID(String menuItemID) {
this.menuItemID = menuItemID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPaused() {
return paused;
}
public void setPaused(String paused) {
this.paused = paused;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
public String getRestaurantID() {
return restaurantID;
}
public void setRestaurantID(String restaurantID) {
this.restaurantID = restaurantID;
}
public String getServedEnd() {
return servedEnd;
}
public void setServedEnd(String servedEnd) {
this.servedEnd = servedEnd;
}
public String getServedStart() {
return servedStart;
}
public void setServedStart(String servedStart) {
this.servedStart = servedStart;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
}
public class RestaurantFragment extends Fragment {
private String title;
private int page;
private String restaurantId;
private String menuItemCategoryID;
private AdapterMenu mAdapter;
private List<ModelMenu> menuList;
TextView orderTimeTv, changeTimeTv, tenPercentTv, fifteenPercentTv, twentyPercentTv, customTipTv, totalTipTv, subTotalTv, taxTotalTv, totalTv, pickedTimeTv, pickedDateTv, todayTv, cancelTv, itemCountTv;
ImageView fabCartIv;
RecyclerView recyclerView;
public RestaurantFragment() {
// Required empty public constructor
}
// newInstance constructor for creating fragment with arguments
/*public static RestaurantFragment newInstance(int page, String title, String restID, String menuItemCategoryID) {
RestaurantFragment fragmentFirst = new RestaurantFragment();
Bundle args = new Bundle();
args.putInt("someInt", page);
args.putString("someTitle", title);
args.putString("restId", restID);
args.putString("menuItemCategoryID", menuItemCategoryID);
fragmentFirst.setArguments(args);
return fragmentFirst;
}*/
public static RestaurantFragment newInstance(int page, String title, String restID, String menuItemCategoryID, List<ModelMenu> menuList) {
RestaurantFragment fragmentFirst = new RestaurantFragment();
Bundle args = new Bundle();
args.putInt("someInt", page);
args.putString("someTitle", title);
args.putString("restId", restID);
args.putString("menuItemCategoryID", menuItemCategoryID);
args.putSerializable("menuList", (Serializable) menuList);
fragmentFirst.setArguments(args);
return fragmentFirst;
}
// Store instance variables based on arguments passed
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
page = getArguments().getInt("someInt", 0);
title = getArguments().getString("someTitle");
restaurantId = getArguments().getString("restId");
menuItemCategoryID = getArguments().getString("menuItemCategoryID");
menuList = (List<ModelMenu>) getArguments().getSerializable("menuList");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_restaurant, container, false);
recyclerView = view.findViewById(R.id.menuRecyclerView);
itemCountTv = view.findViewById(R.id.itemCountTv);
fabCartIv = view.findViewById(R.id.fabCartIv);
/*if (title.equals("Appetizers")) {
loadDataAppetizers();
} else if (title.equals("Breakfast")) {
loadBreakfast();
} else if (title.equals("Noodle")) {
loadNoodle();
}*/
loadMenuItems();
fabCartIv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showCartDialog();
}
});
count();
return view;
}
private void loadMenuItems() {
//recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));
//Log.i("mytag", "list received with size: " + menuList.size() + ", in tab: " + title);
mAdapter = new AdapterMenu(menuList, getActivity().getApplicationContext(), RestaurantFragment.this);
recyclerView.setAdapter(mAdapter);
/*String token = "auth" + System.currentTimeMillis();
final ProgressDialog progressDialog = new ProgressDialog(getActivity());
//show progress dialog
progressDialog.setMessage("Getting Menu Items...");
progressDialog.show();*/
/*Map<String, String> params = new HashMap<>();
params.put("Token", token);
params.put("RestaurantID", restaurantId);
Log.d("TheToken", Utils.getToken() + "" + Utils.getEmail());
String url = ApiManager.headerUrl + ApiManager.menuItemsUrl;
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST,
url, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//progressDialog.dismiss();
Log.d("TheResponse", response.toString());
try {
JSONObject joResponse = response.getJSONObject("Response");
JSONArray jaMainMenu = joResponse.getJSONArray("MainMenu");
JSONArray jaMenuItemImages = joResponse.getJSONArray("MenuItemImages");
JSONArray jaMenuCategories = joResponse.getJSONArray("MenuCategories");
JSONArray jaLinkedMenuItems = joResponse.getJSONArray("LinkedMenuItems");
JSONArray jaMenuSidesTitles = joResponse.getJSONArray("MenuSidesTitles");
JSONArray jaMenuSidesLinks = joResponse.getJSONArray("MenuSidesLinks");
JSONArray jaMenuSides = joResponse.getJSONArray("MenuSides");
*//*for (int j = 0; j < jaMenuCategories.length(); j++) {
String menuItemCategoryID = jaMainMenu.getJSONObject(j).getString("MenuItemCategoryID");
}*//*
for (int i = 0; i < jaLinkedMenuItems.length(); i++) {
String menuItemCategoryID1 = jaLinkedMenuItems.getJSONObject(i).getString("MenuItemCategoryID");
if (menuItemCategoryID.equals(menuItemCategoryID1)) {
String menuItemID1 = jaLinkedMenuItems.getJSONObject(i).getString("MenuItemID");
for (int j = 0; j < jaMainMenu.length(); j++) {
String deleted = jaMainMenu.getJSONObject(j).getString("Deleted");
String description = jaMainMenu.getJSONObject(j).getString("Description");
String ingredients = jaMainMenu.getJSONObject(j).getString("Ingredients");
String inventory = jaMainMenu.getJSONObject(j).getString("Inventory");
String menuItemID = jaMainMenu.getJSONObject(j).getString("MenuItemID");
String name = jaMainMenu.getJSONObject(j).getString("Name");
String paused = jaMainMenu.getJSONObject(j).getString("Paused");
String price = jaMainMenu.getJSONObject(j).getString("Price");
String rating = jaMainMenu.getJSONObject(j).getString("Rating");
String restaurantID = jaMainMenu.getJSONObject(j).getString("RestaurantID");
String servedEnd = jaMainMenu.getJSONObject(j).getString("ServedEnd");
String servedStart = jaMainMenu.getJSONObject(j).getString("ServedStart");
String imageURL = jaMenuItemImages.getJSONObject(j).getString("ImageURL");
if (menuItemID1.equals(menuItemID)) {
ModelMenu cModels = new ModelMenu("" + deleted,
"" + description,
"" + ingredients,
"" + inventory,
"" + menuItemID,
"" + name,
"" + paused,
"$" + price,
"" + rating,
"" + restaurantID,
"" + servedEnd,
"" + servedStart,
"" + imageURL);
menuList.add(cModels);
}
}
//adapter to be set to recyclerview
mAdapter = new AdapterMenu(menuList, getActivity().getApplicationContext(), RestaurantFragment.this);
recyclerView.setAdapter(mAdapter);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//progressDialog.dismiss();
try {
if (error.getMessage().toLowerCase().contains("no address associated with hostname")) {
} else {
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
Volley.newRequestQueue(getActivity()).add(jsonObjReq);*/
}
private int tipPercentage = 10;
private String date = "";
//used to pass lists in confirm order
private ArrayList idList = new ArrayList();
private ArrayList nameList = new ArrayList();
private ArrayList priceList = new ArrayList();
int ids = 0;
List<ModelMenu> menuList1;
MyAdapters myAdapters;
#SuppressLint("NewApi")
private void showCartDialog() {
View view = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_cart, null);
RecyclerView recyclerView = view.findViewById(R.id.menusLayout);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
menuList1 = new ArrayList<>();
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(view);
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialogInterface) {
tipPercentage = 10;
totalPriceAddRemove = 0.0;
idList.clear();
nameList.clear();
priceList.clear();
ids = 0;
}
});
builder.create().show();
orderTimeTv = view.findViewById(R.id.orderTimeTv);
changeTimeTv = view.findViewById(R.id.changeTimeTv);
tenPercentTv = view.findViewById(R.id.tenPercentTv);
fifteenPercentTv = view.findViewById(R.id.fifteenPercentTv);
twentyPercentTv = view.findViewById(R.id.twentyPercentTv);
customTipTv = view.findViewById(R.id.customTipTv);
totalTipTv = view.findViewById(R.id.totalTipTv);
subTotalTv = view.findViewById(R.id.subTotalTv);
taxTotalTv = view.findViewById(R.id.taxTotalTv);
totalTv = view.findViewById(R.id.totalTv);
pickedTimeTv = view.findViewById(R.id.pickedTimeTv);
pickedDateTv = view.findViewById(R.id.pickedDateTv);
todayTv = view.findViewById(R.id.todayTv);
cancelTv = view.findViewById(R.id.cancelTv);
final Button checkoutBtn = view.findViewById(R.id.checkoutBtn);
Button doneDTBtn = view.findViewById(R.id.doneDTBtn);
final TimePicker timePicker = view.findViewById(R.id.timePicker);
HorizontalCalendar hcCalendar = view.findViewById(R.id.hcCalendar);
final LinearLayout dateTimePickLayout = view.findViewById(R.id.dateTimePickLayout);
final RelativeLayout pricesLayout = view.findViewById(R.id.pricesLayout);
dateTimePickLayout.setVisibility(View.GONE);
pricesLayout.setVisibility(View.VISIBLE);
EasyDB easyDB = EasyDB.init(getActivity(), "ITEMS_DB") // "TEST" is the name of the DATABASE
.setTableName("ITEMS_TABLE") // You can ignore this line if you want
.addColumn(new Column("Item_Id", "text", "unique"))
.addColumn(new Column("Item_Name", "text", "not null"))
.addColumn(new Column("Item_Price", "text", "not null"))
.doneTableColumn();
Cursor res = easyDB.getAllData();
while (res.moveToNext()) {
String id = res.getString(1);
String name = res.getString(2);
String price = res.getString(3);
ModelMenu modelMenu = new ModelMenu("" + name, "" + price);
menuList1.add(modelMenu);
idList.add(ids);
nameList.add(name);
priceList.add(price);
ids++;
}
onAddField(getActivity());
myAdapters = new MyAdapters(getActivity(), menuList1);
recyclerView.setAdapter(myAdapters);
timePicker.setIs24HourView(true);
Calendar calendar = Calendar.getInstance();
final int hours = calendar.get(Calendar.HOUR_OF_DAY);
final int minute = calendar.get(Calendar.MINUTE);
final int year = calendar.get(Calendar.YEAR);
final int month = calendar.get(Calendar.MONTH) + 1;
final int day = calendar.get(Calendar.DAY_OF_MONTH);
date = day + "/" + month + "/" + year;
pickedTimeTv.setText(hours + ":" + minute);
pickedDateTv.setText(day + "/" + month + "/" + year);
timePicker.setHour(hours);
timePicker.setMinute(minute);
timePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
#Override
public void onTimeChanged(TimePicker timePicker, int hour, int minute) {
pickedTimeTv.setText(hour + ":" + minute);
}
});
}
Have you tried overriding onStop() in your Activities?
onStop() is called when your app is no longer visible to the user (i.e. pressing Home). You will next receive either onRestart(), onDestroy(), or nothing. This may explain your inconsistent behaviour.
You will likely need to take control and stop any updates to UI elements especially here, and then preserve the state of the UI as the user left it with onSaveInstanceState()
https://developer.android.com/topic/libraries/architecture/saving-states

set image bitmap to imageView adapter

At the moment i am using custom adapter/recycle view to build a simple image and a small galery under the image, every time when i click on one of the images below it loads the image in the main imageView above.
My problem at the moment is, that everytime i click on the images on the galery i do a request for the image, i get the id of the clicked image and load again the image to display it above.
I don't like very well my solution, i want to get the bitmap of the clicked image and display it in the imageView above.
So in my main activity i do a simple request to get the main image, the rest of the images are loading in another reques of my activity that loads a recycle view with all images.
here is the activity:
public class PhotosForPlant extends AppCompatActivity implements IResult,PhotosForPlantsAdapter.OnItemClickListener {
RecyclerView recyclerView;
ArrayList<Photo> photos = new ArrayList<Photo>();
VolleyService mVolleyService;
IResult mResultCallback = null;
IResult mResultCallback2 = null;
final String GETREQUEST = "GETCALL";
PhotosForPlantsAdapter adapter;
String token;
TextView familyTxt;
TextView genreTxt;
TextView specieTxt;
TextView specieDescription;
ImageView plantImg;
int familyId;
int genreId;
String familyName;
String genreName;
Double lat = null;
Double lon = null;
Double alt = null;
String time = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.AppTheme);
setContentView(R.layout.photos_for_plant);
Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);;
setSupportActionBar(myToolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
findViewById(R.id.user_ic2).setVisibility(View.GONE);
TextView toolbarText = (TextView) myToolbar.findViewById(R.id.toolbar_title);
toolbarText.setText("Dados planta");;
familyTxt = (TextView)findViewById(R.id.FamilyName);
genreTxt = (TextView)findViewById(R.id.GenreName);
specieTxt = (TextView)findViewById(R.id.SpecieName);
specieDescription = (TextView)findViewById(R.id.specieDescription);
plantImg = (ImageView)findViewById(R.id.plantImage);
token = checkForToken();
getAllPhotos();
getSpecificPlant();
}
private void getSpecificPlant() {
String id = getIntent().getExtras().getString("plantId");
final String URL = "http://109d0157.ngrok.io/plants/" + id;
getSpecificVolleyCallback();
mVolleyService = new VolleyService(mResultCallback2,this);
mVolleyService.getDataObjectVolley(GETREQUEST,URL,token);
}
private void getAllPhotos() {
String id = getIntent().getExtras().getString("plantId");
final String URL = "http://109d0157.ngrok.io/fotos/" + id + "/plants";
getFotosForPlantVolleyCallback();
mVolleyService = new VolleyService(mResultCallback,this);
mVolleyService.getDataVolley(GETREQUEST,URL,token);
recyclerView = (RecyclerView)findViewById(R.id.gallery);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(),5,GridLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
adapter = new PhotosForPlantsAdapter(getApplicationContext(), photos,this);
recyclerView.setAdapter(adapter);
}
private void getSpecificVolleyCallback() {
mResultCallback2 = new IResult() {
#Override
public void notifySuccess(String requestType, JSONObject response) {
try {
Log.d("ENTREIAQUI","ENTREI");
String specie = response.getString("specie");
loadImage(specie);
familyName = response.getJSONObject("genre").getJSONObject("family").getString("name");
genreName = response.getJSONObject("genre").getString("name");
genreId = response.getJSONObject("genre").getInt("id");
genreTxt.setText(genreName);
specieTxt.setText(specie);
familyTxt.setText(familyName);
specieDescription.setText(response.getString("description"));
familyId = response.getJSONObject("genre").getJSONObject("family").getInt("id");
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void notifySuccess(String requestType, JSONArray response) {
Log.d("ENTREIAQUI","ENTREI");
}
#Override
public void notifyError(String requestType, VolleyError error) {
Log.d("erro!",error.toString());
Log.d("ENTREIAQUI","ENTREI");
}
};
}
void getFotosForPlantVolleyCallback(){
mResultCallback = new IResult() {
#Override
public void notifySuccess(String requestType, JSONObject response) {
}
#Override
public void notifySuccess(String requestType, JSONArray response) {
Photo photo;
// iterate over the JSONArray response
for (int i=0; i < response.length(); i++) {
try {
JSONObject object = response.getJSONObject(i); // get the individual object from JSONArray
Log.d("objeto",object.toString());
int id = Integer.parseInt(object.getString("id")); // get the unique identifier from the object
if(lat != null && lon != null && alt != null){
lat = Double.parseDouble(object.getString("lat"));
lon = Double.parseDouble(object.getString("lon"));
alt = Double.parseDouble(object.getString("altitude"));
}
time = object.getString("date");
String path = object.getString("image");
photo = new Photo(path,id,lat,lon,alt,time); // construct the object
photos.add(photo); // add the object to the arraylist so it can be used on the cardLayout
} catch (JSONException e) {
e.printStackTrace();
}
}
adapter.notifyDataSetChanged();
}
#Override
public void notifyError(String requestType, VolleyError error) {
Log.d("resposta",error.toString());
}
};
}
public void genrePressed(View view){
Intent i = new Intent(this,SpecieLibrary.class);
i.putExtra("id",String.valueOf(genreId));
i.putExtra("name",String.valueOf(genreName));
startActivity(i);
}
public void familyPressed(View view){
Intent i = new Intent(this,GenreLibrary.class);
i.putExtra("id",String.valueOf(familyId));
i.putExtra("name",String.valueOf(familyName));
startActivity(i);
}
#Override
public void notifySuccess(String requestType, JSONObject response) {
}
#Override
public void notifySuccess(String requestType, JSONArray response) {
}
#Override
public void notifyError(String requestType, VolleyError error) {
}
public String checkForToken() {
SharedPreferences sharedPref = getSharedPreferences("user", MODE_PRIVATE);
String tokenKey = getResources().getString(R.string.token);
String token = sharedPref.getString(getString(R.string.token), tokenKey); // take the token
return token;
}
public void loadImage(String specie){
String url = "http://109d0157.ngrok.io/images/" + specie + "/Thumbnail.jpg";
Picasso.with(PhotosForPlant.this)
.load(url)
.into(plantImg);
}
#Override
public void onRowClick(int position, int id,String path, View view) {
String url = "http://109d0157.ngrok.io/" + path;
Picasso.with(PhotosForPlant.this)
.load(url)
.into(plantImg);
}
}
the loadImage, is where i load the main image and then i have the onRowClick that comes from my custom adapter, i get the path of the clicked row there and so i load it again, but what i need is to get somehow the bitmap there and setImageResource on the plantImg.
Here is my adapter:
public class PhotosForPlantsAdapter extends RecyclerView.Adapter<PhotosForPlantsAdapter.ViewHolder> {
private ArrayList<Photo> photos;
private Context context;
private OnItemClickListener listener;
public interface OnItemClickListener {
void onRowClick(int position,int id,String path, View view);
}
public PhotosForPlantsAdapter(Context context, ArrayList<Photo> photos,OnItemClickListener listener) {
this.photos = photos;
this.context = context;
this.listener = listener;
}
#Override
public PhotosForPlantsAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.photos_for_plant_row, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final PhotosForPlantsAdapter.ViewHolder viewHolder, final int i) {
String urlFoto = photos.get(i).getPath();
String url = "http://109d0157.ngrok.io/" + urlFoto;
viewHolder.img.setScaleType(ImageView.ScaleType.CENTER_CROP);
Picasso.with(context)
.load(url)
.resize(240, 120)
.centerInside()
.into(viewHolder.img);
viewHolder.img.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
listener.onRowClick(viewHolder.getAdapterPosition(),photos.get(i).getId(),photos.get(i).getPath(), view);
}
}
});
}
#Override
public int getItemCount() {
return photos.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private ImageView img;
public ViewHolder(View view) {
super(view);
img = (ImageView) view.findViewById(R.id.img);
}
}
}
try to set Image in this way as bitmap
URL newurl = new URL("http://109d0157.ngrok.io/" + urlFoto);
mIcon_val=BitmapFactory.decodeStream(newurl.openConnection() .getInputStream());
viewHolder.img.setImageBitmap(mIcon_val);
and get Image in this way
Bitmap imgBitmap = ((BitmapDrawable)image.getDrawable()).getBitmap();

error with loading data from web in android

i've added a column (named load_more) to the end of a recyclerview and each time i touch this column it should download ten more columns from a url. the first time that I touch load_more, it works properly but for the second time, program crashes.
this is the code of loading data to the recyclerview:
public class category extends AppCompatActivity {
private String url = "http://iranradiotherapy.ir/api/get_category_posts/?include=title,date&id=";
private RequestQueue requestQueue;
private ArrayList<HashMap<String, String>> data;
private RecyclerView recyclerView;
private adapter adapter;
private int page_counter;
private String page_number;
private boolean flag;
private int current;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_category);
Bundle b = getIntent().getExtras();
final String cat_id = b.getString("category_id");
url += cat_id;
Toast.makeText(category.this, url, Toast.LENGTH_SHORT).show();
data = new ArrayList<>();
flag = true;
page_counter = 1;
page_number= "&page=";
requestQueue = Volley.newRequestQueue(this);
get_data();
}
private void get_data() {
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url + page_number + page_counter, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray posts = response.getJSONArray("posts");
for (int i = 0; i < posts.length(); i++) {
HashMap<String, String> hashMap = new HashMap<>();
JSONObject temp = posts.getJSONObject(i);
String post_title = temp.getString("title");
String post_id = temp.getString("id");
String post_date = temp.getString("date");
hashMap.put("post_title", post_title);
hashMap.put("post_date", post_date);
hashMap.put("post_id", post_id);
data.add(hashMap);
}
final HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("load_more", "load_more");
data.add(hashMap);
recyclerView = (RecyclerView) findViewById(R.id.category_recycler_view);
adapter = new adapter(data);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
flag = true;
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), new RecyclerTouchListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
if (data.get(position).equals(hashMap)) {
load_more();
}
else {
Intent i = new Intent(category.this, post.class);
i.putExtra("post_id", data.get(position).get("post_id"));
category.this.startActivity(i);
}
}
}));
} catch (Exception e ) {
Toast.makeText(category.this, "error 1 : " + e.toString(), Toast.LENGTH_SHORT).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(category.this, "error 2 : " + error.toString(), Toast.LENGTH_SHORT).show();
}
});
requestQueue.add(jsonObjectRequest);
}
private void load_more() {
if (flag){
flag = false;
Toast.makeText(this, "load more data " + current, Toast.LENGTH_SHORT).show();
page_counter++;
get_data();
data.remove(data.size() - 1 );
}
}
}
and this is the adapter :
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
if (position + 1 == data.size()) {
holder.title.setVisibility(View.INVISIBLE);
holder.date.setVisibility(View.INVISIBLE);
holder.load_more.setVisibility(View.VISIBLE);
} else {
HashMap<String, String> d = data.get(position);
holder.title.setText(d.get("post_title"));
holder.date.setText(d.get("post_date"));
holder.load_more.setVisibility(View.INVISIBLE);
}
}

Values duplicating when fetching data from database and displaying to ListView

Im new to Android Developement and currently working on an app that should give me the time between first time clicking a button and second time clicking the button and add it to a currently selected customer.
Current Status of App:
I established a connection to da mySql Database using Volley and a local webservice.
It works to insert my customers and time stamps to the table, but when loading times for a specific customer i get a strange result in one case. I tried debugging it but the app keeps crashing on debugging without a message. When not debugging it doesnt crash but shows weird data.
To the problem:
In my main activity called "ZeitErfassen" i have a button to get an overview of all customers display in a ListView.
I create the Listview with a custom ArrayAdapter because i want to pass my objects to the next Activity where my customers are displayed.
So onCreate of the overview of customers i create a new arraylist and fill it with all customers from my database. this list i pass to my customadapter and then set it as my adapter of the Listview.
Now, when i click on an item, i call a php script and pass the customer_id to the query to fetch all times from database where customer_id = customer_id.
Now the part where i get "strange" data...
1.(Source:ZeitErfassen;Destination:AddCustomer) I create a new customer,example xyz, in the app, data gets passed to the database.
2.(Source:ZeitErfassen;Destination:DisplayCustomer) I call my overview for all customers where the ListView is filled with data as described above. At the end ob the List I see the customer i just created,xyz.
3.Go back to Main Activity(ZeitErfassen)
4.(Source:ZeitErfassen;Destination:DisplayCustomer)I open the overview for all customers again, and it shows my last created user two times! so last entry, xyz, entry before last, xyz!
After that, i can open the view as many times as i want, the customer never gets duplicated again!
The debugger stopps after step 2.
Now when i click on the new customers, it calls the script to fetch the times by customer_id.
One of the xyz entrys display the correct times from database.
The second one, i just found out, display the times where customer_id="". In the database the value for "" is 0.
I have no clue where the second customer suddenly appears from and debugging didnt help me either -.-
When i close the app an open it again, there ist just one entry for the user that was visible twice before closing the app. It doesnt duplicate on opening view...
Here is my code..
Main Activity ZeitErfassen
public class ZeitErfassen extends AppCompatActivity {
public static LinkedList<Kunde> kunden = new LinkedList<Kunde>();
boolean running = false;
long startTime,endTime,totalTime;
private SharedPreferences app_preferences;
private SharedPreferences.Editor editor;
private TextView displayTime;
public Button startEndButton;
private ArrayAdapter<String> adapter;
private Spinner spinner;
public static Kunde selectedCustomer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_zeit_erfassen);
//Einstellungen laden
app_preferences = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
startTime= app_preferences.getLong("startTime", 0);
endTime = app_preferences.getLong("endTime", 0);
running = app_preferences.getBoolean("running", false);
displayTime = (TextView)findViewById(R.id.zeit_bei_Kunde);
displayTime.setText((CharSequence) app_preferences.getString("zeitAnzeige", "Zeit bei Kunde"));
startEndButton = (Button)findViewById(R.id.start_Timer);
startEndButton.setText((CharSequence) app_preferences.getString("timerButton", "Start Timer"));
DatabaseHelper.customerFromDatabaseToList(this);
editor = app_preferences.edit();
editor.commit();
}
public void onDestroy() {
super.onDestroy();
editor.putLong("startTime", startTime);
editor.putString("zeitAnzeige", (String) displayTime.getText());
editor.putString("timerButton", (String) startEndButton.getText());
editor.putLong("endTime", endTime);
editor.putLong("totalTime", totalTime);
editor.putBoolean("running", app_preferences.getBoolean("running", false));
editor.commit();
this.finish();
}
public void onResume() {
super.onResume();
// saveCustomers();
// createDropDown();
}
public void startTimer(View view) {
editor = app_preferences.edit();
if(running == false) {
startTime = getTime();
running = true;
editor.putLong("startTime", startTime);
startEndButton.setText("End Timer");
displayTime.setText("Zeitstoppung läuft");
editor.putString("zeitAnzeige", (String) displayTime.getText());
editor.putString("timerButton", (String) startEndButton.getText());
editor.putBoolean("running", true);
editor.commit();
} else {
setSelectedCustomer();
endTime = getTime();
editor.putLong("endTime",endTime);
totalTime = endTime - startTime;
editor.putLong("totalTime", totalTime);
displayTime.setText(formatTime(totalTime));
editor.putString("zeitAnzeige", (String) displayTime.getText());
startEndButton.setText("Start Timer");
editor.putString("timerButton", (String) startEndButton.getText());
running = false;
editor.putBoolean("running", false);
editor.commit();
DatabaseHelper.timeToDatabase(String.valueOf(selectedCustomer.getId()),formatTime(totalTime),this);
// selectedCustomer.saveTimeToCustomer(selectedCustomer, formatTimeForCustomer(totalTime));
}
}
public String formatTime(Long totalTime) {
int hours = (int) ((totalTime / (1000*60*60)) % 24);
int minutes = (int) ((totalTime / (1000*60)) % 60);
int seconds = (int) (totalTime / 1000) % 60;
String time = (String.valueOf(hours) + ":" + String.valueOf(minutes) + ":" + String.valueOf(seconds));
return time;
}
public String formatTimeForCustomer(Long totalTime) {
StringBuilder time = new StringBuilder();
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
time.append((String.valueOf(year) + "." + String.valueOf(month) + "." + String.valueOf(day))).append(formatTime(totalTime));
return time.toString();
}
public void neuerKunde(View view) {
Intent intent = new Intent(this, AddKunde.class);
startActivity(intent);
}
public void kundenÜbersicht(View view) {
// setSelectedCustomer();
Intent intent = new Intent(this, DisplayCustomer.class);
startActivity(intent);
}
public long getTime() {
long millis = System.currentTimeMillis();
return millis;
}
public void setSelectedCustomer() {
if(kunden.size() > 0) {
if (spinner.getSelectedItem().toString() != null) {
String tempCustomer = spinner.getSelectedItem().toString();
for (Kunde k : kunden) {
if (k.getName().equals(tempCustomer)) {
selectedCustomer = k;
}
}
}
}
}
public void createDropDown() {
/*File file = new File(this.getFilesDir(),"kunden.ser"); NOT USED BECAUSE DATABASE WORKS
if(file.exists()) {
Kunde.importFromFile(this);
}*/
if (kunden.size() > 0) {
spinner = (Spinner) findViewById(R.id.chooseCustomer);
// Create an ArrayAdapter using the string array and a default spinner layout
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, DisplayCustomer.namesOfCustomers());
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(adapter);
}
}
}
DisplayCustomer(Where all customers are displayed with data from Database)
public class DisplayCustomer extends AppCompatActivity {
CustomerAdapter customerAdapter;
public ArrayAdapter<String> adapterCustomerView;
private ListView listCustomerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_customer);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ArrayList<Kunde> customerList = getCustomerObjects();
customerAdapter = new CustomerAdapter(this,customerList);
listCustomerView = (ListView)findViewById(R.id.list_View_Customers);
// adapterCustomerView = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, namesOfCustomers());
listCustomerView.setAdapter(customerAdapter);
openCustomerDetails();
}
public static ArrayList<String> namesOfCustomers() {
ArrayList<String> customerNames = new ArrayList<>();
if(ZeitErfassen.kunden.size() > 0 ) {
for (Kunde k : ZeitErfassen.kunden) {
customerNames.add(k.getName());
}
}
return customerNames;
}
public static ArrayList<Kunde> getCustomerObjects() {
ArrayList<Kunde> customerList = new ArrayList<>();
if(ZeitErfassen.kunden.size() > 0 ) {
for (Kunde k : ZeitErfassen.kunden) {
customerList.add(k);
}
}
return customerList;
}
public void openCustomerDetails() {
listCustomerView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Kunde kunde = new Kunde();
kunde = (Kunde)listCustomerView.getItemAtPosition(position);
Intent intent = new Intent(DisplayCustomer.this, DisplayDetailedCustomer.class);
intent.putExtra("selectedCustomerObject",(Parcelable)kunde);
startActivity(intent);
}
});
}
}
My CustomerAdapter to pass data from one intent to another.
public class CustomerAdapter extends ArrayAdapter<Kunde> {
public CustomerAdapter(Context context, ArrayList<Kunde> customerList) {
super(context,0,customerList);
}
public View getView(int position, View convertView, ViewGroup parent) {
//Data for this position
Kunde kunde = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.items_customer_layout, parent, false);
}
// Lookup view for data population
TextView tvName = (TextView) convertView.findViewById(R.id.tvCustomerName);
// Populate the data into the template view using the data object
tvName.setText(kunde.getName());
// Return the completed view to render on screen
return convertView;
}
}
DatabaseHelper Class
public class DatabaseHelper {
public static RequestQueue requestQueue;
public static String host = "http://192.168.150.238/";
public static final String insertUrl = host+"insertCustomer.php";
public static final String showUrl = host+"showCustomer.php";
public static final String insertTimeUrl = host+"insertTime.php";
public static final String showTimeUrl = host+"showTimes.php";
public static void customerFromDatabaseToList(final Context context) {
//Display customer from database
requestQueue = Volley.newRequestQueue(context);
final ArrayList<String> customerNames = new ArrayList<>();
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, showUrl, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray customers = response.getJSONArray("customers");
if(customers.length() > 0) {
for (int i = 0; i < customers.length(); i++) {
JSONObject customer = customers.getJSONObject(i);
String customerName = customer.getString("cus_name");
String customerAddress = customer.getString("cus_address");
int customerID = Integer.valueOf(customer.getString("cus_id"));
if (customerName != null && customerAddress != null) {
try {
Kunde k = new Kunde(customerName, customerAddress, customerID);
if (!listContainsObject(k)) {
ZeitErfassen.kunden.add(k);
}
} catch (Exception e) {
showAlert("Fehler in customerFromDatabaseToListn!", "Fehler", context);
}
} else {
showAlert("Fehler in customerFromDatabaseToListn!", "Fehler", context);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
requestQueue.add(jsonObjectRequest);
}
public static boolean listContainsObject(Kunde cust) {
for(Kunde k : ZeitErfassen.kunden) {
if(k.getId() == cust.getId()) {
return true;
}
}
return false;
}
public static void timeToDatabase(final String customer_id, final String time_value, final Context context) {
requestQueue = Volley.newRequestQueue(context);
StringRequest request = new StringRequest(Request.Method.POST, DatabaseHelper.insertTimeUrl, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
showAlert("Fehler","Fehler bei Verbindung zur Datenbank",context);
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> parameters = new HashMap<String,String>();
parameters.put("customerid",customer_id);
parameters.put("timevalue",time_value);
return parameters;
}
};
requestQueue.add(request);
};
public static void showAlert(String title, String message, Context context) {
// 1. Instantiate an AlertDialog.Builder with its constructor
AlertDialog.Builder builder = new AlertDialog.Builder(context);
// 2. Chain together various setter methods to set the dialog characteristics
builder.setMessage(message)
.setTitle(title);
// 3. Get the AlertDialog from create()
AlertDialog dialog = builder.create();
}
public static ArrayList<String> timesFromDataBaseToList(final Context context,final int customer_id) {
requestQueue = Volley.newRequestQueue(context);
final String cus_id = String.valueOf(customer_id) ;
final ArrayList<String> customerTimes = new ArrayList<>();
StringRequest jsonObjectRequest = new StringRequest(Request.Method.POST, showTimeUrl, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject object = new JSONObject(response.toString());
JSONArray times = object.getJSONArray("customertimes");
if (times.length() > 0) {
for (int i = 0; i < times.length(); i++) {
JSONObject jsonObject = times.getJSONObject(i);
String timeValue = jsonObject.getString("time_value");
if (timeValue != null) {
customerTimes.add(timeValue);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(context,"Fehler beim Holen der Zeiten",Toast.LENGTH_LONG).show();
error.printStackTrace();
}
}){
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> parameters = new HashMap<String,String>();
parameters.put("cus_id",cus_id);
return parameters;
}
};
requestQueue.add(jsonObjectRequest);
return customerTimes;
};
}
DisplayDetailedCustomer / Display the times
public class DisplayDetailedCustomer extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_detailed_customer);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Intent getCustomerParcable = getIntent();
Kunde customer = getCustomerParcable.getExtras().getParcelable("selectedCustomerObject");
TextView displayCustomerNameDetailed =(TextView) findViewById(R.id.detailedCustomerViewName);
TextView displayCustomerAddressDetailed =(TextView) findViewById(R.id.detailedCustomerAddress);
ListView timeListView = (ListView)findViewById(R.id.detailedTimeListView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, DatabaseHelper.timesFromDataBaseToList(this,customer.getId()));
timeListView.setAdapter(adapter);
displayCustomerNameDetailed.setText(customer.getName());
displayCustomerAddressDetailed.setText(customer.getAdresse());
}
}
Kunde Class / Customer Class with interface Parcelable
public class Kunde implements Serializable,Parcelable {
private String name;
private String adresse;
private int id;
public LinkedList<String> zeiten;
public Kunde(String name, String adresse) throws Exception{
setName(name);
setAdresse(adresse);
zeiten = new LinkedList<String>();
}
public Kunde(String name, String adresse,int id) throws Exception{
setName(name);
setAdresse(adresse);
setId(id);
zeiten = new LinkedList<String>();
}
public Kunde(){};
public void setId(int id) {
this.id = id;
}
public int getId(){
return id;
}
public void setName(String name) throws Exception {
if(name != null) {
this.name = name;
} else throw new Exception("Name ist ungueltig! in setName");
}
public void setAdresse(String adresse) throws Exception{
if(adresse != null) {
this.adresse = adresse;
}else throw new Exception("Adresse ist ungueltig! in setAdresse");
}
public String getName() {
return name;
}
public String getAdresse() {
return adresse;
}
public void saveZeit(Long totalTime) {
zeiten.add(String.valueOf(totalTime));
}
public void saveTimeToCustomer(Kunde customer,String time){
customer.zeiten.add(time);
}
//------------------------------------Parcelable Methods to pass Daata from one Intent to another----------------------------------------
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.id);
dest.writeString(this.name);
dest.writeString(this.adresse);
// dest.writeList(this.zeiten);
}
// this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
public static final Parcelable.Creator<Kunde> CREATOR = new Parcelable.Creator<Kunde>() {
public Kunde createFromParcel(Parcel in) {
return new Kunde(in);
}
public Kunde[] newArray(int size) {
return new Kunde[size];
}
};
// example constructor that takes a Parcel and gives you an object populated with it's values
private Kunde(Parcel in) {
LinkedList<String> zeiten = null;
id = in.readInt();
name = in.readString();
adresse = in.readString();
}
}
Thanks for taking your time!!

Categories

Resources