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
Related
I'm trying to make a laundry ordering application. I've made it to the order process, at the end of the order process, the user clicks the next button to checkout the ordered results, I have successfully made the checkout results, but what I made is still in one variable string. how to put the checkout results into an array variable so that I can post the results in the form of JSONArray?
HERE IS MY ORDER ACTIVITY CODE :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_produk);
// menghubungkan variablel pada layout dan pada java
listProduk = (ListView)findViewById(R.id.list_produk);
swipeProduct = (SwipeRefreshLayout)findViewById(R.id.swipeProduct);
radioExpress = (RadioButton)findViewById(R.id.radio_express);
radioReguler = (RadioButton)findViewById(R.id.radio_regular);
tvTotal = (TextView)findViewById(R.id.total);
next = (Button)findViewById(R.id.button_next);
actionBar = getSupportActionBar();
laundry_id = getIntent().getStringExtra(TAG_LAUNDRY_ID);
// untuk mengisi data dari JSON ke dalam adapter
productAdapter = new CheckboxAdapter(this, (ArrayList<ProductModel>) productList, this);
listProduk.setAdapter(productAdapter);
listProduk.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
productAdapter.setCheckBox(position);
}
});
// menampilkan widget refresh
swipeProduct.setOnRefreshListener(this);
swipeProduct.post(new Runnable() {
#Override
public void run() {
swipeProduct.setRefreshing(true);
productList.clear();
tvTotal.setText(String.valueOf(0));
radioReguler.isChecked();
regular = true;
productAdapter.notifyDataSetChanged();
callProduct();
}
}
);
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String checkbox = "";
for (ProductModel hold : productAdapter.getAllData()) {
int total = Integer.parseInt(hold.getProduct_price())*(hold.getCountProduct());
if (hold.isCheckbox()) {
checkbox += "\n" + hold.getProduct_name() + " " + total;
}
}
if (!checkbox.isEmpty()) {
dipilih = checkbox;
} else {
dipilih = "Anda Belum Memilih Menu.";
}
formSubmit(dipilih);
}
});
}
private void formSubmit(String hasil){
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
LayoutInflater inflater = getLayoutInflater();
View dialogView = inflater.inflate(R.layout.form_submit, null);
dialog.setView(dialogView);
dialog.setIcon(R.mipmap.ic_launcher);
dialog.setTitle("Menu Yang Dipilih");
dialog.setCancelable(true);
txtnamaProduk = (TextView) dialogView.findViewById(R.id.txtNama_produk);
txtnamaProduk.setText(hasil);
dialog.setNeutralButton("CLOSE", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dialog.show();
}
AND HERE IS THE CODE OF THE RESULT :
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String checkbox = "";
for (ProductModel hold : productAdapter.getAllData()) {
int total = Integer.parseInt(hold.getProduct_price())*(hold.getCountProduct());
if (hold.isCheckbox()) {
checkbox += "\n" + hold.getProduct_name() + " " + total;
}
}
if (!checkbox.isEmpty()) {
dipilih = checkbox;
} else {
dipilih = "Anda Belum Memilih Menu.";
}
formSubmit(dipilih);
}
});
}
in my code above, I still use the variable checkbox to accommodate all the results of the order chosen by the user. how to put all the result into array variable so i can post to server as a JSONArray? Please help me to solve this problem. because i'm still a beginner in android.
HERE IS MY ADAPTER CODE IF NEEDED :
public class CheckboxAdapter extends BaseAdapter{
private Context context;
private ArrayList<ProductModel> productItems;
ProdukLaundry produk;
public CheckboxAdapter(Context context, ArrayList<ProductModel> items, ProdukLaundry produk) {
this.context = context;
this.productItems = items;
this.produk = produk;
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public int getCount() {
return productItems.size();
}
#Override
public Object getItem(int position) {
return productItems.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View view, ViewGroup parent) {
final ViewHolder viewHolder;
final ProductModel items = productItems.get(position);
if(view == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.list_produk, null, true);
viewHolder.checkBox = (CheckBox) view.findViewById(R.id.checkBox_productName);
viewHolder.decrease = (TextView) view.findViewById(R.id.decrease_product);
viewHolder.count = (TextView) view.findViewById(R.id.count_product);
viewHolder.increase = (TextView) view.findViewById(R.id.increase_product);
viewHolder.price = (TextView) view.findViewById(R.id.product_price);
view.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) view.getTag();
}
viewHolder.checkBox.setText(items.getProduct_name());
viewHolder.price.setText(items.getProduct_price());
viewHolder.count.setText(String.valueOf(items.getCountProduct()));
//fungsi untuk set posisi textview + dan -
viewHolder.increase.setTag(R.integer.btn_plus_view, view);
viewHolder.increase.setTag(R.integer.btn_plus_pos, position);
viewHolder.decrease.setTag(R.integer.btn_minus_view, view);
viewHolder.decrease.setTag(R.integer.btn_minus_pos, position);
//fungsi untuk disable textview + dan - jika checkbox tidak di klik
viewHolder.decrease.setOnClickListener(null);
viewHolder.increase.setOnClickListener(null);
if(items.isCheckbox()){
viewHolder.checkBox.setChecked(true);
viewHolder.increase.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View tempview = (View) viewHolder.increase.getTag(R.integer.btn_plus_view);
TextView tv = (TextView) tempview.findViewById(R.id.count_product);
Integer pos = (Integer) viewHolder.increase.getTag(R.integer.btn_plus_pos);
int countProduct = Integer.parseInt(tv.getText().toString()) + 1;
tv.setText(String.valueOf(countProduct));
productItems.get(pos).setCountProduct(countProduct);
produk.tambah(pos);
}
});
viewHolder.decrease.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View tempview = (View)viewHolder.decrease.getTag(R.integer.btn_minus_view);
TextView tv = (TextView) tempview.findViewById(R.id.count_product);
Integer pos = (Integer) viewHolder.decrease.getTag(R.integer.btn_minus_pos);
int total = productItems.get(pos).getCountProduct();
if (total>0){
int countProduct = Integer.parseInt(tv.getText().toString()) - 1;
tv.setText(String.valueOf(countProduct));
productItems.get(pos).setCountProduct(countProduct);
produk.kurang(pos);
}
}
});
} else {
viewHolder.checkBox.setChecked(false);
//fungsi untuk reset jumlah harga dan produk pada checkbox
String count = viewHolder.count.getText().toString();
int jumlah = Integer.parseInt(count);
int harga = Integer.parseInt(productItems.get(position).getProduct_price());
int kurang = jumlah * harga;
viewHolder.count.setText("0");
productItems.get(position).setCountProduct(0);
produk.kurangCheckbox(kurang);
}
return view;
}
public ArrayList<ProductModel> getAllData(){
return productItems;
}
public void setCheckBox(int position){
ProductModel items = productItems.get(position);
items.setCheckbox(!items.isCheckbox());
notifyDataSetChanged();
}
static class ViewHolder{
TextView decrease, count, increase, price;
CheckBox checkBox;
}
}
just create getter setter method of Arraylist like below
CompleteOrder:-
public class CompleteOrder {
List<OrderItem> order_items;
public List<OrderItem> getOrder_items() {
return order_items;
}
public void setOrder_items(List<OrderItem> order_items) {
this.order_items = order_items;
}
}
Create another Getter setter class of variable you want to add in arraylist
OrderItem:-
public class OrderItem {
String product_name;
int product_total;
public OrderItem(String product_name, int product_total) {
this.product_name = product_name;
this.product_total = product_total;
}
public String getProduct_name() {
return product_name;
}
public void setProduct_name(String product_name) {
this.product_name = product_name;
}
public int getProduct_total() {
return product_total;
}
public void setProduct_total(int product_total) {
this.product_total = product_total;
}
}
Now in your onClick method just create new List as below
public void onClick(View view) {
String checkbox = "";
CompleteOrder completeOrder=new CompleteOrder();
List<OrderItem> masterProductorderCount=new ArrayList<>();
for (ProductModel hold : productAdapter.getAllData()) {
int total = Integer.parseInt(hold.getProduct_price())*(hold.getCountProduct());
if (hold.isCheckbox()) {
checkbox += "\n" + hold.getProduct_name() + " " + total;
masterProductorderCount.add(new OrderItem(holder.getProduct_name(),total);
}
}
completeOrder.setOrder_items(masterProductorderCount);
if (!checkbox.isEmpty()) {
dipilih = checkbox;
} else {
dipilih = "Anda Belum Memilih Menu.";
}
formSubmit(completeOrder);//pass object of CompleteOrder
}
});
CompleteOrder object give JSON output as below
{
"CompleteOrder":[
{
"product_name":"your product name",
"product_total":1
},
{
"product_name":"your product name",
"product_total":1
},
{
"product_name":"your product name",
"product_total":1
}
]
}
make a model that contains product name , total and etc,
then put each data into an object and put each object into an array
finally use Gson to map properties to model / list of models or the other way around.
ArrayList<Model> list = new ArrayList<>();
for (ProductModel hold : productAdapter.getAllData()) {
int total = Integer.parseInt(hold.getProduct_price())*(hold.getCountProduct());
if (hold.isCheckbox()) {
Model model = new Model();
model.productName = hold.getProduct_name();
model.total = total;
list.add(model);
}
}
String jsonArray = Gson().toJson(list);
You need to create a JSONObject for each entry in the JSONArray.
As far as I can see this should take care of it:
public void onClick(View view) {
String checkbox = "";
JSONArray jsonArray = new JSONArray();
for (ProductModel hold : productAdapter.getAllData()) {
int total = Integer.parseInt(hold.getProduct_price())*(hold.getCountProduct());
if (hold.isCheckbox()) {
checkbox += "\n" + hold.getProduct_name() + " " + total;
JSONObject jsonObj = new JSONObject();
jsonObj.put("product_name", hold.getProduct_name());
jsonObj.put("product_total", total);
jsonArray.put(jsonObj);
}
}
if (!checkbox.isEmpty()) {
dipilih = checkbox;
} else {
dipilih = "Anda Belum Memilih Menu.";
}
String jsonArrayString = jsonArray.toString();
formSubmit(dipilih);
}
Depending on your data the resulting string from jsonArrayString would be:
{[
{"product_name":"product1","product_total":1},
{"product_name":"product2","product_total":2},
{"product_name":"product3","product_total":3}
]}
I really do not know what you intend on doing with the JSON data so I just created a String "jsonArrayString".. do what ever you need to with it.
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);
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);
}
}
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!!
I am decoding jpeg images from a server request I get using json. I display them with a custom ListView Adapter along with a little text.
The images display correctly for the first 8 ImageViews in the ListView, however, after that it will no longer display the image (it will display the text). For example, if I have a total of 10 images, the last two images will not show in the ListView, but if I delete the first 2 images, the last two will show, so there is no concern about retrieving the actual images.
On my main activity (NotesActivity) I have a button that goes to another activity which does an asyntask, and in that async task in the onPostExecute, it returns back to the main activity where it should show the updated list (and it does, unless there are more than 8 images).
I don't know where to begin, any suggestions?
My Activity that contains the ListView
public class NotesActivity extends Activity implements OnClickListener {
String key = "NOTES";
String key2 = "UPDATE_NOTES";
Gson gson = new Gson();
// Notes myNotes = new Notes();
NotesList myNotes = new NotesList();
String bId;
String res = null;
EditText notes;
Button save;
private Button createNote;
private int position;
private String type;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.notes_layout);
createNote = (Button) findViewById(R.id.notes_layout_btn_createNote);
Bundle bundle = this.getIntent().getExtras();
position = bundle.getInt("position");
type = bundle.getString("type");
//
if (type.equals("LISTINGS")) {
Listings it = ListingsFragment.myListings.getListings().get(
position);
bId = it.getBID();
notes = (EditText) findViewById(R.id.notes);
}
//
if (type.equals("SHARED")) {
Listings it = SharedFragment.myShared.getListings().get(position);
bId = it.getBID();
notes = (EditText) findViewById(R.id.notes);
}
GetNotes getNotes = new GetNotes();
try {
NotesList copy = new NotesList();
getNotes.execute(key, bId).get();
for (int j = 0; j < myNotes.getNotes().size(); j++) {
Notes note = myNotes.getNotes().get(j);
System.out.println("Removed value: " + note.getIsRemoved());
if (note.getIsRemoved() == null) {
copy.getNotes().add(note);
}
}
NotesAdapter adapter = new NotesAdapter(this, R.layout.note_row,
copy.getNotes());
ListView lv = (ListView) findViewById(R.id.notes_layout_lv_notesList);
lv.setAdapter(adapter);
} catch (Exception e) {
}
createNote.setOnClickListener(this);
}
private class GetNotes extends AsyncTask<String, String, NotesList> {
#Override
protected NotesList doInBackground(String... things) {
ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("key", things[0]));
postParameters.add(new BasicNameValuePair("bId", things[1]));
// String valid = "1";
String response = null;
try {
response = CustomHttpClient.executeHttpPost(
"http://propclip.dev/mobile.php", postParameters);
res = response.toString();
// System.out.println("This is the response " + res);
// res = res.trim();
// res= res.replaceAll("\\s+","");
// error.setText(res);
// System.out.println(res);
myNotes = gson.fromJson(res, NotesList.class);
// System.out.println(res);
} catch (Exception e) {
res = e.toString();
}
return myNotes;
}
#Override
protected void onPostExecute(NotesList res) {
}
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.notes_layout_btn_createNote:
ProfileDataSource datasource = new ProfileDataSource(this);
datasource.open();
PropClipGlobal pcg = datasource.getUserIdenity();
Intent intent = new Intent(this, NewNoteActivity.class);
intent.putExtra("bId", bId);
intent.putExtra("uId", pcg.getUID());
intent.putExtra("username", pcg.getEm());
intent.putExtra("position", position);
intent.putExtra("type", type);
startActivity(intent);
}
}
}
My custom adapter
public class NotesAdapter extends ArrayAdapter<Notes> {
List<Notes> notes;
Context context;
public NotesAdapter(Context context, int resource, List<Notes> notes) {
super(context, resource, notes);
this.notes = notes;
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.note_row, null);
}
Notes note = notes.get(position);
ImageView icon = (ImageView) v.findViewById(R.id.note_row_icon);
TextView name = (TextView) v.findViewById(R.id.note_row_name);
TextView message = (TextView) v.findViewById(R.id.note_row_message);
TextView date = (TextView) v.findViewById(R.id.note_row_date);
String input = note.getNoteDate();
SimpleDateFormat inputDf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat outputDf = new SimpleDateFormat("dd, yyyy");
SimpleDateFormat monthFormat = new SimpleDateFormat("MM");
Date myDate = null;
try {
myDate = inputDf.parse(input);
} catch (ParseException e) {
e.printStackTrace();
}
String month = monthFormat.format(myDate);
date.setText(getMonth(Integer.parseInt(month)) + " "
+ outputDf.format(myDate));
message.setText(note.getNote());
name.setText(note.getFirstName() + " " + note.getLastName());
// System.out.println(p.getFileData());
byte[] imageAsBytes = Base64.decode(note.getFileData().getBytes(),
position);
icon.setImageBitmap(BitmapFactory.decodeByteArray(imageAsBytes, 0,
imageAsBytes.length));
System.out.println(note.getFileData());
return v;
}
public String getMonth(int month) {
return new DateFormatSymbols().getMonths()[month - 1];
}
}
Activity which eventually goes to the main activity (NotesActivity)
public class NewNoteActivity extends Activity implements OnClickListener {
private String uId;
private String bId;
private String username;
private String response;
private String key = "UPDATE_NOTES";
private Button submit;
private EditText note;
private int position;
private String type;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_note);
submit = (Button) findViewById(R.id.activity_new_note_btn_submit);
note = (EditText) findViewById(R.id.activity_new_note_et_note);
Intent intent = getIntent();
bId = intent.getStringExtra("bId");
uId = intent.getStringExtra("uId");
username = intent.getStringExtra("username");
position = intent.getIntExtra("position", 0);
type = intent.getStringExtra("type");
submit.setOnClickListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.new_note, menu);
return true;
}
private class UpdateNotes extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... values) {
ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("key", values[0]));
postParameters.add(new BasicNameValuePair("bId", values[1]));
postParameters.add(new BasicNameValuePair("uId", values[2]));
postParameters.add(new BasicNameValuePair("username", values[3]));
postParameters.add(new BasicNameValuePair("note", values[4]));
String response = null;
try {
response = CustomHttpClient.executeHttpPost(
"http://propclip.dev/mobile.php", postParameters);
response = response.toString();
} catch (Exception e) {
response = e.toString();
}
return null;
}
#Override
protected void onPostExecute(String response) {
Intent intent = new Intent(getApplicationContext(),
NotesActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("position", position);
intent.putExtra("type", type);
startActivity(intent);
Toast toast = Toast.makeText(getApplicationContext(),"Added note!", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
}
#Override
public void onClick(View v) {
String noteMessage = note.getText().toString();
UpdateNotes updateNotes = new UpdateNotes();
updateNotes.execute(key, bId, uId, username, noteMessage);
}
}