Clear ListView if response is a empty array? - java

I have two spinners the first one for month and the second for years.I am trying to call a method send_date() if on Item Selected is called for any of the 2 spinners.
So I have two problems:- 1)send_date() gets called twice the first
time it gets the correct data as expected but the 2nd time it returns
a empty array. 2)When I select another month or year the old data does
not get removed that is the list does not refresh.
The following is my code for on Item Selected :-
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
int i = spinYear.getSelectedItemPosition();
selected_year = years.get(i);
Log.d("Selection Year",selected_year);
tv_year.setText(selected_year);
try {
send_date();
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
And for the month spinner:-
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
int j = spinMonths.getSelectedItemPosition();
selected_month = Months[j];
Date date = null;
try {
date = new SimpleDateFormat("MMMM").parse(selected_month);
} catch (ParseException e) {
e.printStackTrace();
}
Calendar cal = Calendar.getInstance();
cal.setTime(date);
tv_month.setText(String.valueOf(cal.get(Calendar.MONTH)+1));
Log.d("Selection Month",selected_month);
try {
send_date();
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
On response I call the following method for populating the list view with data:-
public void showBS(String response)
{
ParseBS_all pb = new ParseBS_all(response);
pb.parseBS();
bl = new BS_allList(getActivity(),ParseBS_all.doc_no,ParseBS_all.balance,ParseBS_all.total,ParseBS_all.vat,ParseBS_all.profit);
lv_bsall.setAdapter(bl);
}
This is the code for the send_date method:-
//This method is used to send month and year
private void send_date() throws JSONException {
final String year = tv_year.getText().toString();
final String month = tv_month.getText().toString();
StringRequest stringRequest = new StringRequest(Request.Method.POST, SEND_DATE,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//display.setText("This is the Response : " + response);
String resp = response.toString().trim();
if (resp.equals("Nothing to display"))
{
Toast.makeText(getContext(), "Nothing to Display", Toast.LENGTH_SHORT).show();
// bl.clear();
lv_bsall.setAdapter(bl);
bl.notifyDataSetChanged();
}else
{
Toast.makeText(getContext(), "Response" + response, Toast.LENGTH_LONG).show();
Log.d("RESPONSE for date", response.toString().trim());
showBS(response);
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
GlobalClass gvar = (GlobalClass) getActivity().getApplicationContext();
String dbname = gvar.getDbname();
Map<String, String> params = new HashMap<>();
params.put(KEY_DBNAME, dbname);
params.put(KEY_MONTH, month);
params.put(KEY_YEAR,year);
return params;
}
};
RequestQueue requestQ = Volley.newRequestQueue(getContext());
requestQ.add(stringRequest);
}
Adapter code for list view.
public class BS_allList extends ArrayAdapter<String>
{
private String[] doc_no;
private String[] balance;
private String[] total;
private String[] vat;
private String[] profit;
private Activity context;
public BS_allList(Activity context, String[] doc_no, String[]balance, String[] total, String[] vat, String[] profit)
{
super(context, R.layout.bs_list_all, doc_no);
this.context =context;
this.doc_no= doc_no;
this.balance = balance;
this.total = total;
this.vat=vat;
this.profit = profit;
}
#Override
public View getView(int position, View listViewItem, ViewGroup parent)
{
if (null == listViewItem)
{
LayoutInflater inflater = context.getLayoutInflater();
listViewItem = inflater.inflate(R.layout.bs_list_all, null, true);
}
TextView tv_docNo = (TextView) listViewItem.findViewById(R.id.tvdoc_no);
TextView tv_balance = (TextView) listViewItem.findViewById(R.id.tv_balance);
TextView tv_tot = (TextView) listViewItem.findViewById(R.id.tv_total);
TextView tv_vat = (TextView) listViewItem.findViewById(R.id.tv_vat);
TextView tv_pf = (TextView) listViewItem.findViewById(R.id.tv_profit);
tv_docNo.setText(doc_no[position]);
tv_balance.setText(balance[position]);
tv_tot.setText(total[position]);
tv_vat.setText(vat[position]);
tv_pf.setText(profit[position]);
return listViewItem;
}
}
Also note that I have set the spinner to point to the current month and year so the first time it works properly.
I am new to programming so any help or suggestion is appreciated.Thank you.

Hi #AndroidNewBee,
As per our discussion made following changes in your code and you will get proper output and it will resolve your issues.
if (resp.equals("Nothing to display"))
{
Toast.makeText(getContext(), "Nothing to Display", Toast.LENGTH_SHORT).show();
bl = new BS_allList(getActivity(),{""},{""},{""},{""},{""});
lv_bsall.setAdapter(bl);
}
And second is check validation as below,
try {
if((selected_year != null & selected_year.length > 0 ) & (tv_month.getText().toString() != null & tv_month.getText().toString().length > 0))
{
send_date();
}
} catch (JSONException e) {
e.printStackTrace();
}

First you shouldn't be using so many String[], instead wrap them in a class
Class BSDataModel{
private String doc_no;
private String balance;
private String total;
private String vat;
private String profit;
//getters and setters
}
Now the reponse result should be added as in ,it returns List<BSDataModel>
List<BSDataModel> reponseList = new ArrayList<>();
//for example adding single response
for(int i=0;i<jsonArrayResponse.length();i++){
BSDataModel singleResponse = new BSDataModel();
singleResponse.setDocNo(jsonArrayResponse.get(i).getString("doc_no"));
singleResponse.setBalace(jsonArrayResponse.get(i).getString("balance"));
//etc..finall add that single response to responseList
reponseList.add(singleResponse);
}
BS_allList.java
public class BS_allList extends ArrayAdapter<BSDataModel>
{
private List<BSDataModel> bsList;
private Activity context;
public BS_allList(Activity context,List<BSDataModel> bsList)
{
super(context, R.layout.bs_list_all, bsList);
this.context =context;
this.bsList = bsList;
}
#Override
public View getView(int position, View listViewItem, ViewGroup parent)
{
if (null == listViewItem)
{
LayoutInflater inflater = context.getLayoutInflater();
listViewItem = inflater.inflate(R.layout.bs_list_all, null, true);
}
TextView tv_docNo = (TextView) listViewItem.findViewById(R.id.tvdoc_no);
TextView tv_balance = (TextView) listViewItem.findViewById(R.id.tv_balance);
TextView tv_tot = (TextView) listViewItem.findViewById(R.id.tv_total);
TextView tv_vat = (TextView) listViewItem.findViewById(R.id.tv_vat);
TextView tv_pf = (TextView) listViewItem.findViewById(R.id.tv_profit);
BSDataModel bsData = bsList.get(position);
tv_docNo.setText(bsData.getDoc());
tv_balance.setText(bsData.getBalance());
tv_tot.setText(bsData.getTot());
tv_vat.setText(bsData.getVat());
tv_pf.setText(bsData.getPF());
return listViewItem;
}
}
Now in your class
BS_allList bl = new BS_allList(getActivity(),responseList);//which you got above
After receiving new Response
// remove old data
responseList.clear(); // list items in the sense list of array used to populate listview
if(newresponseArray.size() > 0){
for(int i=0;i<newjsonArrayResponse.length();i++){
BSDataModel singleResponse = new BSDataModel();
singleResponse.setDocNo(newjsonArrayResponse.get(i).getString("doc_no"));
singleResponse.setBalace(newjsonArrayResponse.get(i).getString("balance"));
//etc..finall add that single response to responseList
reponseList.add(singleResponse);
}
}
//refresh listview
bl.notifyDataSetChanged();

Try this way,
1. adapter.clear();
2. Add/Remove your list Items.
3. listview.setAdapter(adapter);
4. adapter.notifyDatasetChanged();
this procedure should work.

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 ();
}

Recyclerview Out Of Memory Error (using Volley)

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);

getTag, setTag checkbox issue, how can I get my activity to post checked boxes? The other values are posting ok

I am in the process of changing someone else's code from listView to recyclerView, changing code in my activity and my adapter where required - the adapter is a big change, with OnCreateView, onBindViewHolder and so on...
As the question indicates, category, name, phone, address, comment, public_or_private are posting successfully to mySql db, but nothing for checkedContacts. I'd be very grateful if you could tell me how to fix the problem.
I am quite sure it has to do with something around this line:
//get the other data related to the selected contact - name and number
SelectPhoneContact contact = (SelectPhoneContact) checkbox.getTag();
I am not getting any errors but when I run in debug mode it gets to here and then jumps to:
} catch (Exception e) {
System.out.println("there's a problem here unfortunately");
e.printStackTrace();
}
I think it has something to do with setTag but I find it confusing and I'm not sure where it should be set (if, even, that is the problem).
I'm posting the relevant code for my activity, NewContact and the RecyclerViewAdapter, PopulistoCOntactsAdapter. Thanks for any help.
NewContact.java
//for the SAVE button
private void saveContactButton() {
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("you clicked it, save");
try {
System.out.println("we're in the try part");
int count = MatchingContactsAsArrayList.size();
for (int i = 0; i < count; i++) {
//for each Matching Contacts row in the listview
LinearLayout itemLayout = (LinearLayout)recyclerView.getChildAt(i); // Find by under LinearLayout
//for each Matching Contacts checkbox in the listview
CheckBox checkbox = (CheckBox)itemLayout.findViewById(R.id.checkBoxContact);
//get the other data related to the selected contact - name and number
SelectPhoneContact contact = (SelectPhoneContact) checkbox.getTag();
//if that checkbox is checked, then get the phone number
if(checkbox.isChecked()) {
Log.d("Item " + String.valueOf(i), checkbox.getTag().toString());
Toast.makeText(NewContact.this, contact.getPhone(), Toast.LENGTH_LONG).show();
// make each checked contact in selectPhoneContacts
// into an individual
// JSON object called checkedContact
JSONObject checkedContact = new JSONObject();
// checkedContact will be of the form {"checkedContact":"+353123456"}
checkedContact.put("checkedContact", contact.getPhone());
// Add checkedContact JSON Object to checkedContacts jsonArray
//The JSON Array will be of the form
// [{"checkedContact":"+3531234567"},{"checkedContact":"+353868132813"}]
//we will be posting this JSON Array to Php, further down below
checkedContacts.put(checkedContact);
System.out.println("NewContact: checkedcontact JSONObject :" + checkedContact);
}
}
} catch (Exception e) {
System.out.println("there's a problem here unfortunately");
e.printStackTrace();
}
//When the user clicks save
//post phoneNoofUserCheck to NewContact.php and from that
//get the user_id in the user table, then post category, name, phone etc...
//to the review table
StringRequest stringRequest = new StringRequest(Request.Method.POST, NewContact_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//response, this will show the checked numbers being posted
Toast.makeText(NewContact.this, response, Toast.LENGTH_LONG).show();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
//post these details to the NewContact.php file and do
//stuff with it
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
//post the phone number to php to get the user_id in the user table
params.put("phonenumberofuser", phoneNoofUserCheck);
//the second value, categoryname.getText().toString() etc...
// is the value we get from Android.
//the key is "category", "name" etc.
// When we see these in our php, $_POST["category"],
//put in the value from Android
params.put("category", categoryname.getText().toString());
params.put("name", namename.getText().toString());
params.put("phone", phonename.getText().toString());
params.put("address", addressname.getText().toString());
params.put("comment", commentname.getText().toString());
params.put("public_or_private", String.valueOf(public_or_private));
System.out.println("public_or_private is " + String.valueOf(public_or_private));
//this is the JSON Array of checked contacts
//it will be of the form
//[{"checkedContact":"+3531234567"},{"checkedContact":"+353868132813"}]
params.put("checkedContacts", checkedContacts.toString());
return params;
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(stringRequest);
//when saved, go back to the PopulistoListView class and update with
//the new entry
Intent j = new Intent(NewContact.this, PopulistoListView.class);
j.putExtra("phonenumberofuser", phoneNoofUserCheck);
NewContact.this.startActivity(j);
finish();
}
});
}
}
PopulistoContactsAdapter.java
public class PopulistoContactsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
//make a List containing info about SelectPhoneContact objects
public List<SelectPhoneContact> theContactsList;
Context context_type;
public class MatchingContact extends RecyclerView.ViewHolder {
//In each recycler_blueprint show the items you want to have appearing
public TextView title, phone;
public CheckBox check;
public Button invite;
public MatchingContact(final View itemView) {
super(itemView);
//title is cast to the name id, in recycler_blueprint,
//phone is cast to the id called no etc
title = (TextView) itemView.findViewById(R.id.name);
phone = (TextView) itemView.findViewById(R.id.no);
invite = (Button) itemView.findViewById(R.id.btnInvite);
check = (CheckBox) itemView.findViewById(R.id.checkBoxContact);
}
}
public class nonMatchingContact extends RecyclerView.ViewHolder {
//In each recycler_blueprint show the items you want to have appearing
public TextView title, phone;
public CheckBox check;
public Button invite;
public nonMatchingContact(final View itemView) {
super(itemView);
//title is cast to the name id, in recycler_blueprint,
//phone is cast to the id called no etc
title = (TextView) itemView.findViewById(R.id.name);
phone = (TextView) itemView.findViewById(R.id.no);
invite = (Button) itemView.findViewById(R.id.btnInvite);
check = (CheckBox) itemView.findViewById(R.id.checkBoxContact);
}
}
#Override
public int getItemViewType(int position) {
//for each row in recyclerview, get the getType_row, set in NewContact.java
return Integer.parseInt(theContactsList.get(position).getType_row());
}
public PopulistoContactsAdapter(List<SelectPhoneContact> selectPhoneContacts, Context context) {
//selectPhoneContacts = new ArrayList<SelectPhoneContact>();
theContactsList = selectPhoneContacts;
// whichactivity = activity;
context_type = context;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView;
//if getType_row is 1...
if (viewType == 1)
{
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
itemView = inflater.inflate(R.layout.recycler_blueprint, parent, false);
//itemView.setTag();
return new MatchingContact(itemView);
} else {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
itemView = inflater.inflate(R.layout.recycler_blueprint_non_matching, parent, false);
return new nonMatchingContact(itemView);
}
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, final int position) {
//bind the views into the ViewHolder
//selectPhoneContact is an instance of the SelectPhoneContact class.
//We will assign each row of the recyclerview to contain details of selectPhoneContact:
//The number of rows will match the number of phone contacts
final SelectPhoneContact selectPhoneContact = theContactsList.get(position);
if (viewHolder.getItemViewType() == 1)
{
((MatchingContact) viewHolder).title.setText(selectPhoneContact.getName());
((MatchingContact) viewHolder).phone.setText(selectPhoneContact.getPhone());
CheckBox check = ((MatchingContact) viewHolder).check;
//get the number position of the checkbox in the recyclerview
//check.setTag(position);
}
else {
((nonMatchingContact) viewHolder).title.setText(selectPhoneContact.getName());
((nonMatchingContact) viewHolder).phone.setText(selectPhoneContact.getPhone());
}
}
#Override
public int getItemCount() {
return theContactsList.size();
}
}
And here is my SelectPhoneContact class:
public class SelectPhoneContact {
String phone;
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
boolean isMatching;
public boolean isMatching(){return isMatching;}
public void setIsMatchingContact(boolean isMatching){
this.isMatching = isMatching;
}
//*****************************************
//this is for the checkbox
boolean selected = false;
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected){
this.selected = selected;
}
String type_row;
public String getType_row() {
return type_row;
}
public void setType_row(String type_row) {
this.type_row = type_row;
}
}
I figured it out. This tutorial was very helpful: https://demonuts.com/2017/07/03/recyclerview-checkbox-android/
Here is the code I used for NewContact.java:
//for the SAVE button
private void saveContactButton() {
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("you clicked it, save");
try {
System.out.println("we're in the try part");
//loop through the matching contacts
int count = MatchingContactsAsArrayList.size();
for (int i = 0; i < count; i++) {
//for matching contacts that are checked...
if (PopulistoContactsAdapter.theContactsList.get(i).getSelected()) {
Toast.makeText(NewContact.this, PopulistoContactsAdapter.theContactsList.get(i).getPhone() + " clicked!", Toast.LENGTH_SHORT).show();
// make each checked contact in selectPhoneContacts
// into an individual
// JSON object called checkedContact
JSONObject checkedContact = new JSONObject();
// checkedContact will be of the form {"checkedContact":"+353123456"}
checkedContact.put("checkedContact", PopulistoContactsAdapter.theContactsList.get(i).getPhone());
// Add checkedContact JSON Object to checkedContacts jsonArray
//The JSON Array will be of the form
// [{"checkedContact":"+3531234567"},{"checkedContact":"+353868132813"}]
//we will be posting this JSON Array to Php, further down below
checkedContacts.put(checkedContact);
System.out.println("NewContact: checkedcontact JSONObject :" + checkedContact);
}
}
} catch (Exception e) {
System.out.println("there's a problem here unfortunately");
e.printStackTrace();
}
//When the user clicks save
//post phoneNoofUserCheck to NewContact.php and from that
//get the user_id in the user table, then post category, name, phone etc...
//to the review table
StringRequest stringRequest = new StringRequest(Request.Method.POST, NewContact_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//response, this will show the checked numbers being posted
Toast.makeText(NewContact.this, response, Toast.LENGTH_LONG).show();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
//post these details to the NewContact.php file and do
//stuff with it
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
//post the phone number to php to get the user_id in the user table
params.put("phonenumberofuser", phoneNoofUserCheck);
//the second value, categoryname.getText().toString() etc...
// is the value we get from Android.
//the key is "category", "name" etc.
// When we see these in our php, $_POST["category"],
//put in the value from Android
params.put("category", categoryname.getText().toString());
params.put("name", namename.getText().toString());
params.put("phone", phonename.getText().toString());
params.put("address", addressname.getText().toString());
params.put("comment", commentname.getText().toString());
params.put("public_or_private", String.valueOf(public_or_private));
System.out.println("public_or_private is " + String.valueOf(public_or_private));
//this is the JSON Array of checked contacts
//it will be of the form
//[{"checkedContact":"+3531234567"},{"checkedContact":"+353868132813"}]
params.put("checkedContacts", checkedContacts.toString());
return params;
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(stringRequest);
//when saved, go back to the PopulistoListView class and update with
//the new entry
Intent j = new Intent(NewContact.this, PopulistoListView.class);
j.putExtra("phonenumberofuser", phoneNoofUserCheck);
NewContact.this.startActivity(j);
finish();
}
});
}
}
And my PopulistoContactsAdapter.java:
public class PopulistoContactsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
//make a List containing info about SelectPhoneContact objects
public static List<SelectPhoneContact> theContactsList;
Context context_type;
public class MatchingContact extends RecyclerView.ViewHolder {
//In each recycler_blueprint show the items you want to have appearing
public TextView title, phone;
public CheckBox check;
public Button invite;
public MatchingContact(final View itemView) {
super(itemView);
//title is cast to the name id, in recycler_blueprint,
//phone is cast to the id called no etc
title = (TextView) itemView.findViewById(R.id.name);
phone = (TextView) itemView.findViewById(R.id.no);
invite = (Button) itemView.findViewById(R.id.btnInvite);
check = (CheckBox) itemView.findViewById(R.id.checkBoxContact);
}
}
public class nonMatchingContact extends RecyclerView.ViewHolder {
//In each recycler_blueprint show the items you want to have appearing
public TextView title, phone;
public CheckBox check;
public Button invite;
public nonMatchingContact(final View itemView) {
super(itemView);
//title is cast to the name id, in recycler_blueprint,
//phone is cast to the id called no etc
title = (TextView) itemView.findViewById(R.id.name);
phone = (TextView) itemView.findViewById(R.id.no);
invite = (Button) itemView.findViewById(R.id.btnInvite);
check = (CheckBox) itemView.findViewById(R.id.checkBoxContact);
}
}
#Override
public int getItemViewType(int position) {
//for each row in recyclerview, get the getType_row, set in NewContact.java
return Integer.parseInt(theContactsList.get(position).getType_row());
}
public PopulistoContactsAdapter(List<SelectPhoneContact> selectPhoneContacts, Context context) {
//selectPhoneContacts = new ArrayList<SelectPhoneContact>();
theContactsList = selectPhoneContacts;
// whichactivity = activity;
context_type = context;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView;
//if getType_row is 1...
if (viewType == 1)
{
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
itemView = inflater.inflate(R.layout.recycler_blueprint, parent, false);
//itemView.setTag();
return new MatchingContact(itemView);
} else {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
itemView = inflater.inflate(R.layout.recycler_blueprint_non_matching, parent, false);
return new nonMatchingContact(itemView);
}
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, final int position) {
//bind the views into the ViewHolder
//selectPhoneContact is an instance of the SelectPhoneContact class.
//We will assign each row of the recyclerview to contain details of selectPhoneContact:
//The number of rows will match the number of phone contacts
final SelectPhoneContact selectPhoneContact = theContactsList.get(position);
if (viewHolder.getItemViewType() == 1)
{
((MatchingContact) viewHolder).title.setText(selectPhoneContact.getName());
((MatchingContact) viewHolder).phone.setText(selectPhoneContact.getPhone());
((MatchingContact) viewHolder).check.setText("Cheeckbox" + position);
((MatchingContact) viewHolder).check.setChecked(theContactsList.get(position).getSelected());
((MatchingContact) viewHolder).check.setTag(position);
((MatchingContact) viewHolder).check.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Integer pos = (Integer) ((MatchingContact) viewHolder).check.getTag();
Toast.makeText(context_type, theContactsList.get(pos).getPhone() + " clicked!", Toast.LENGTH_SHORT).show();
if (theContactsList.get(pos).getSelected()) {
theContactsList.get(pos).setSelected(false);
} else {
theContactsList.get(pos).setSelected(true);
}
}
});
// CheckBox check = ((MatchingContact) viewHolder).check;
//get the number position of the checkbox in the recyclerview
//check.setTag(position);
}
else {
((nonMatchingContact) viewHolder).title.setText(selectPhoneContact.getName());
((nonMatchingContact) viewHolder).phone.setText(selectPhoneContact.getPhone());
}
}
#Override
public int getItemCount() {
return theContactsList.size();
}
}

Error: No adapter attached; skipping layout

I know this question has been asked so many times, but none of the solutions answered there seems to solve my problem.
Most of the solutions suggested attaching an adapter (setadapter()) and I have done that. But the problem still seems to persist.
I also checked if my listitems are empty and it isn't.
I have attached the adapter in a function loadUserAccounts().
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_accounts);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Swipe to refresh
swipeRefresh = (SwipeRefreshLayout) findViewById(R.id.userSwipeRefresh);
//Recycler View
recyclerView = (RecyclerView) findViewById(R.id.userRecyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(userAccountsActivity.this));
listItems = new ArrayList<>();
recyclerViewUserAdapter = new RecyclerViewUserAdapter(listItems, userAccountsActivity.this);
recyclerView.setAdapter(recyclerViewUserAdapter);
//Function to load the users to the recycler view
loadUserAccounts();
/*
* Sets up a SwipeRefreshLayout.OnRefreshListener that is invoked when the user
* performs a swipe-to-refresh gesture.
*/
swipeRefresh.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
Log.i("Swipe_log: ", "onRefresh called from SwipeRefreshLayout");
// This method performs the actual data-refresh operation.
// The method calls setRefreshing(false) when it's finished.
loadUserAccounts();
}
}
);
}
and this is my loadUserAccounts() function:
/**
* Function to load the user account
* into the recycler view from the log database
*/
public void loadUserAccounts(){
String tag_string_req = "req_user_acc";
clear();
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL_USER_ACCOUNTS, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jArray = new JSONArray(response);
for(int i = jArray.length()-1; i>=0; i--){
JSONObject log = jArray.getJSONObject(i);
String name = log.getString("name");
String cpfNumber = log.getString("cpfNumber");
String type = log.getString("type");
String created_at = log.getString("created_at");
Log.d("Adapter: ", name + cpfNumber + type + created_at);
ListItem_RecyclerView_User item = new ListItem_RecyclerView_User (name, cpfNumber, type, created_at);
listItems.add(item);
}
recyclerViewUserAdapter.updateDataList(responseList);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if(error!=null && error.getMessage() !=null){
Log.e(TAG,"User Accounts Error: " + error.getMessage());
Toast.makeText(getApplicationContext(),error.getMessage(), Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(getApplicationContext(),"Something went wrong",Toast.LENGTH_LONG).show();
}
}
});
//Adding request to request queue
AppController.getInstance().addToRequestQueue(stringRequest, tag_string_req);
if (swipeRefresh == null)
return;
else {
if (swipeRefresh.isRefreshing()) {
swipeRefresh.setRefreshing(false);
}
}
}
My adapter class RecyclerViewUserAdapter
public class RecyclerViewUserAdapter extends RecyclerView.Adapter<RecyclerViewUserAdapter.ViewHolder> {
private List<ListItem_RecyclerView_User> listItems;
private Context context;
public RecyclerViewUserAdapter(List<ListItem_RecyclerView_User> listItems, Context context) {
this.listItems = listItems;
this.context = context;
}
public void updateDataList(List<ListItem_RecyclerView_User> newDatas) {
listItems.clear();
listItems.addAll(newDatas);
notifyDataSetChanged();
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.users_recycler_item, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(RecyclerViewUserAdapter.ViewHolder holder, int position) {
ListItem_RecyclerView_User listItem = listItems.get(position);
holder.txtUserName.setText(listItem.getTxtUserName());
holder.txtUserCpf.setText(listItem.getTxtUserCpf());
holder.txtAccountType.setText(listItem.getTxtAccountType());
try {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = null;
date = df.parse(listItem.getTxtCreatedDate());
SimpleDateFormat sdf = new SimpleDateFormat("h:mm a");
String loginTime = sdf.format(date);
holder.txtCreatedDate.setText(loginTime);
} catch (ParseException e) {
e.printStackTrace();
}
}
#Override
public int getItemCount() {
return 0;
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView txtUserName;
private TextView txtUserCpf;
private TextView txtAccountType;
private TextView txtCreatedDate;
public ViewHolder(View itemView) {
super(itemView);
txtUserName = (TextView) itemView.findViewById(R.id.txtUserName);
txtUserCpf = (TextView) itemView.findViewById(R.id.txtUserCpf);
txtAccountType = (TextView) itemView.findViewById(R.id.txtAccountType);
txtCreatedDate = (TextView) itemView.findViewById(R.id.txtCreatedDate);
}
}
}
Try this...
modify that getItemCount() to like this.
#Override
public int getItemCount() {
return listItems.size();
}
Try this
Create your adapter with empty list data
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
// your normal code
recyclerView = (RecyclerView) findViewById(R.id.userRecyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(userAccountsActivity.this));
listItems = new ArrayList<>();
// create new adapter
recyclerViewUserAdapter = new RecyclerViewUserAdapter(new ArrayList<>(), userAccountsActivity.this);
recyclerView.setAdapter(recyclerViewUserAdapter);
//your normal code
}
In your response
#Override
public void onResponse(String response) {
try {
List<ListItem_RecyclerView_User> responseList = new ArrayList<>();
JSONArray jArray = new JSONArray(response);
for(int i = jArray.length()-1; i>=0; i--){
JSONObject log = jArray.getJSONObject(i);
String name = log.getString("name");
String cpfNumber = log.getString("cpfNumber");
String type = log.getString("type");
String created_at = log.getString("created_at");
Log.d("Adapter: ", name + cpfNumber + type + created_at);
ListItem_RecyclerView_User item = new ListItem_RecyclerView_User (name, cpfNumber, type, created_at);
responseList.add(item);
}
/*recyclerViewUserAdapter = new RecyclerViewUserAdapter(listItems, userAccountsActivity.this);
recyclerView.setAdapter(recyclerViewUserAdapter);*/
// write method to update your data
recyclerViewUserAdapter.updateDataList(responseList);
} catch (JSONException e) {
e.printStackTrace();
}
}
In your adapter create method
public void updateDataList(List<ListItem_RecyclerView_User> newDatas) {
listItems.clear();
listItems.addAll(newDatas);
notifyDataSetChanged():
}

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