I have the following code from my app where I am trying to retrieve expenses' items that happened today's day (dd) in the past, more than 2 times, I want to populate those items in a recyclerview.
I get the expected result but only one item at the time, the recyclerview is not showing the list as expected.
I use realtime database.
I am looking for some ideas, please see my code;
//suggestions
databaseReference.addValueEventListener(new ValueEventListener() {
#SuppressLint("NotifyDataSetChanged")
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
suggestions.clear();
int occurrences = 0;
Expense expense1 = new Expense();
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Expense expense = dataSnapshot.getValue(Expense.class);
assert expense != null;
if (expense.getDate().substring(0, 2).equals(day) && expense.getDate().substring(6, 10).equals(year)) {
for (Expense e : all_expenses) {
if (!today_expenses.contains(e)) {
suggestions_title.setVisibility(View.VISIBLE);
occurrences = Collections.frequency(all_expenses, e);
expense1 = e;
}
}
}
}
if (occurrences > 2) suggestions.add(expense1);
suggestionsAdapter.notifyDataSetChanged();
if (suggestionsAdapter.getItemCount() == 0) {
suggestions_title.setVisibility(View.INVISIBLE);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
and this below is my adapter class;
public class SuggestionsAdapter extends RecyclerView.Adapter<SuggestionsAdapter.ViewHolder> {
Activity activity;
private final ArrayList<Expense> suggestions;
private String item;
private String category;
private int amount;
FirebaseAuth mAuth;
int totalMonth;
public SuggestionsAdapter(Activity activity, ArrayList<Expense> suggestions) {
this.activity = activity;
this.suggestions = suggestions;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(activity).inflate(R.layout.suggestions, parent, false);
mAuth = FirebaseAuth.getInstance();
monthTotalLimit();
return new ViewHolder(view);
}
#SuppressLint("SetTextI18n")
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, #SuppressLint("RecyclerView") int position) {
final Expense expense = suggestions.get(position);
holder.expense.setText("" + expense.getItem());
holder.add.setOnClickListener(view -> {
item = expense.getItem();
category = expense.getCategory();
amount = expense.getAmount();
updateExpense();
});
}
#Override
public int getItemCount() {
return suggestions.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView expense;
private final TextView add;
public ViewHolder(#NonNull View itemView) {
super(itemView);
expense = itemView.findViewById(R.id.expense);
add = itemView.findViewById(R.id.add_suggestion);
}
}
//saving amount for limit check
private void monthTotalLimit() {
final Calendar c = Calendar.getInstance();
#SuppressLint("SimpleDateFormat") DateFormat dateFormat = new SimpleDateFormat("MM");
String month = dateFormat.format(c.getTime());
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference().child("Expenses").child(Objects.requireNonNull(mAuth.getCurrentUser()).getUid());
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
int totalAmount = 0;
for (DataSnapshot ds : snapshot.getChildren()) {
Expense expense = ds.getValue(Expense.class);
//dd-MM-yyyy
assert expense != null;
if (expense.getDate().substring(3, 5).equals(month)) {
totalAmount += expense.getAmount();
totalMonth = totalAmount;
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
private void updateExpense() {
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference().child("Expenses").child(Objects.requireNonNull(FirebaseAuth.getInstance().getCurrentUser()).getUid());
AlertDialog.Builder myDialog = new AlertDialog.Builder(activity);
LayoutInflater inflater = LayoutInflater.from(activity);
View myView = inflater.inflate(R.layout.input_layout, null);
myDialog.setView(myView);
final AlertDialog dialog = myDialog.create();
dialog.setCancelable(false);
final EditText mItem = myView.findViewById(R.id.item);
final TextView mDate = myView.findViewById(R.id.date);
final EditText mAmount = myView.findViewById(R.id.amount);
final Calendar c = Calendar.getInstance();
#SuppressLint("SimpleDateFormat") DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
String date = dateFormat.format(c.getTime());
mItem.setText(item);
mDate.setText(date);
mAmount.setText(String.valueOf(amount));
final Spinner categorySpinner = myView.findViewById(R.id.spinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(activity, R.array.Category, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
categorySpinner.setAdapter(adapter);
int spinnerPosition = adapter.getPosition(category);
categorySpinner.setSelection(spinnerPosition);
final Button cancel_btn = myView.findViewById(R.id.cancel_btn);
final Button save_btn = myView.findViewById(R.id.save_btn);
mDate.setOnClickListener(view -> datePicker(mDate));
save_btn.setOnClickListener(view -> {
String itemString = mItem.getText().toString();
String amountString = mAmount.getText().toString();
String spinnerString = categorySpinner.getSelectedItem().toString();
String userInputDate = mDate.getText().toString();
int amountInt;
if (itemString.isEmpty()) {
mItem.setError(activity.getString(R.string.name_required));
mItem.requestFocus();
return;
}
if (amountString.equals("") || amountString.equals("0")) {
mAmount.setError(activity.getString(R.string.amount_required));
mAmount.requestFocus();
return;
} else {
amountInt = Integer.parseInt(amountString);
}
if ((totalMonth + amountInt) > 2000000000) {
mAmount.setError(activity.getString(R.string.monthly_limit));
mAmount.requestFocus();
return;
}
if (spinnerString.equals(activity.getString(R.string.category))) {
Toast.makeText(activity, R.string.category_required, Toast.LENGTH_SHORT).show();
return;
} else {
String id = databaseReference.push().getKey();
Expense expense = new Expense(itemString.toUpperCase(Locale.ROOT), spinnerString, userInputDate, id, amountInt);
assert id != null;
databaseReference.child(id).setValue(expense).addOnCompleteListener(task -> {
if (!task.isSuccessful()) {
Toast.makeText(activity, activity.getString(R.string.input_error) + task.getException(), Toast.LENGTH_SHORT).show();
}
});
}
dialog.dismiss();
});
cancel_btn.setOnClickListener(view -> dialog.dismiss());
dialog.show();
}
private void datePicker(TextView textView) {
Calendar calendar = Calendar.getInstance();
// Get current time
int currentYear = calendar.get(Calendar.YEAR);
int currentMonth = calendar.get(Calendar.MONTH);
int currentDay = calendar.get(Calendar.DAY_OF_MONTH);
// Create listener
#SuppressLint("SetTextI18n") DatePickerDialog.OnDateSetListener listener = (view, year, month, day) -> {
#SuppressLint("DefaultLocale") String dayS = String.format("%02d", day);
#SuppressLint("DefaultLocale") String monthS = String.format("%02d", month + 1);
textView.setText(dayS + "-" + monthS + "-" + year);
};
// Move day as today
calendar.set(Calendar.DAY_OF_MONTH, currentDay);
// Min = time after changes
long minTime = calendar.getTimeInMillis();
// Move day as first day of the month
calendar.set(Calendar.DAY_OF_MONTH, 1);
// Move to next month
calendar.add(Calendar.MONTH, +1);
// Go back one day (so last day of current month)
calendar.add(Calendar.DAY_OF_MONTH, -1);
// Max = current
long maxTime = calendar.getTimeInMillis();
// Create dialog
DatePickerDialog datePickerDialog = new DatePickerDialog(activity,
listener,
currentYear,
currentMonth,
currentDay);
// Set dates
datePickerDialog.getDatePicker().setMinDate(minTime);
datePickerDialog.getDatePicker().setMaxDate(maxTime);
// Show dialog
datePickerDialog.show();
}
}
Your code looks fine and must be fetching multiple items from the firebase database but only one is displayed on the whole screen because in the adapter layout, the height of the parent would be match_parent instead of wrap_content, that's why one item is taking up the whole screen and you can't see the rest of the items. If you even scroll your screen vertically, you will see the other items as well. Just change it to wrap_content and everything will be good to go :)
Related
I am trying to pass the value from spinner.setOnItemSelectedListener to a string that contains date string. I have two spinners month and year, here I am showing only for month spinner because if I get the solution for month spinner then it will be same for year as well.
month_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (parent.getId() == R.id.month_spinner){
seltmont = parent.getSelectedItem().toString();
Toast.makeText(MainActivity.this, "Selected Month: " + seltmont, Toast.LENGTH_SHORT).show();
textviewMonth.setText(seltmont);
setMonthView();
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
I have tried to access the spinner value like this:- String month = month_spinner.getSelectedItem().toString();
and try to pass the spinner onItemSelectListener value to combinedString string variable like this:-
combinedString = "01/" + month + "/" + year ;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MMMM/yyyy");
selectdate = LocalDate.parse(combinedString, formatter);
I get the default value in the combined string that is already preselected in the spinner but
when user try to change the default value that is shown in spinner it does not change the value. It gives null value in the combinedString.
Can anyone help me How to pass the value from onItemSelectListener to combinedString
Is it because of the scope of a method (' { } ') or is it because of private or public variable declaration.
Please help.
By the way whole code is in JAVA.
Here is complete code:-
public class MainActivity extends AppCompatActivity implements CalendarAdapter.OnItemListener {
TextView monthYearText, textviewMonth,textviewYear,textviewYearnMonth;
RecyclerView calendarReyclerView;
LocalDate selectdate;
private Spinner month_spinner,spinYear;
String [] months;
String combinedString;
String selectedMonth;
String seltmont;
String selctYear;
#SuppressLint("SetTextI18n")
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textviewMonth = findViewById(R.id.textviewMonth);
textviewYear = findViewById(R.id.textviewYear);
//for testing
textviewYearnMonth = findViewById(R.id.textviewYearnMonth);
month_spinner = findViewById(R.id.month_spinner);
spinYear = findViewById(R.id.yearspin);
populateSpinnerMonth();
populateSpinnerYear();
initWidget();
selectdate = LocalDate.now();
setMonthView();
//---- on click listener ---//
month_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (parent.getId() == R.id.month_spinner){
seltmont = parent.getSelectedItem().toString();
Toast.makeText(MainActivity.this, "Selected Month: " + seltmont, Toast.LENGTH_SHORT).show();
textviewMonth.setText(seltmont);
setMonthView();
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
spinYear.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (parent.getId() == R.id.yearspin){
selctYear = parent.getSelectedItem().toString();
Toast.makeText(MainActivity.this, "Selected Year" + selctYear, Toast.LENGTH_SHORT).show();
textviewYear.setText(selctYear);
setMonthView();
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
// ---- on click listener ---//
String month = month_spinner.getSelectedItem().toString();
String year= spinYear.getSelectedItem().toString();
// String month = textviewMonth.getText().toString();
//String year = textviewYear.getText().toString();
//combinedString = "16/09/2019";
combinedString = "01/" + month + "/" + year ;
// combinedString = "01/" + mon + "/" + year ;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MMMM/yyyy");
selectdate = LocalDate.parse(combinedString, formatter);
/* //not working
String mon = textviewMonth.getText().toString();
Log.d("month","code is going here");
textviewYearnMonth.setText(mon);
Log.d("month","code cross the textviewYearnMonth"); */
// textviewYearnMonth.setText(seltmont);
}
private void populateSpinnerYear() {
ArrayList<String> years = new ArrayList<String>();
int thisYear = Calendar.getInstance().get(Calendar.YEAR);
for (int i = 1950; i <= thisYear; i++){
years.add(Integer.toString(i));
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,years);
spinYear.setAdapter(adapter);
}
private void populateSpinnerMonth() {
months = new DateFormatSymbols().getMonths();
ArrayAdapter<String> monthAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item,months);
monthAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
month_spinner.setAdapter(monthAdapter);
}
#RequiresApi(api = Build.VERSION_CODES.O)
private void setMonthView() {
monthYearText.setText(monthYearFromDate(selectdate));
ArrayList<String> daysInMonth = daysInMonthArray(selectdate);
CalendarAdapter calendarAdapter = new CalendarAdapter(daysInMonth, this);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(),7); //for calendar columns
calendarReyclerView.setLayoutManager(layoutManager);
calendarReyclerView.setAdapter(calendarAdapter);
}
#RequiresApi(api = Build.VERSION_CODES.O)
private ArrayList<String> daysInMonthArray(LocalDate date) {
ArrayList<String> daysInMonthArray = new ArrayList<>();
YearMonth yearMonth = YearMonth.from(date);
int daysInMonth = yearMonth.lengthOfMonth();
LocalDate firstOfMonth = selectdate.withDayOfMonth(1);
int dayOfWeek = firstOfMonth.getDayOfWeek().getValue();
for(int i = 1; i <= 42; i++)
{
if(i <= dayOfWeek || i > daysInMonth + dayOfWeek)
{
daysInMonthArray.add("");
}
else
{
daysInMonthArray.add(String.valueOf(i - dayOfWeek));
}
}
return daysInMonthArray;
}
#RequiresApi(api = Build.VERSION_CODES.O)
private String monthYearFromDate(LocalDate date){
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM yyyy");
return date.format(formatter);
}
private void initWidget() {
calendarReyclerView = findViewById(R.id.calendarRecyclerView);
monthYearText = findViewById(R.id.monthYearTV);
}
#RequiresApi(api = Build.VERSION_CODES.O)
public void previousMonthAction(View view) {
selectdate = selectdate.minusMonths(1);
setMonthView();
}
#RequiresApi(api = Build.VERSION_CODES.O)
public void nextMonthAction(View view) {
selectdate = selectdate.plusMonths(1);
setMonthView();
}
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onItemClick(int position, String dayText) {
if(!dayText.equals(""))
{
String message = "Selected Date " + dayText + " " + monthYearFromDate(selectdate);
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
}
I have attached two images of the output:
Initial Stage at first launch ->Image 1
After I changed the spinners value ->Image 2
Declare selectdate as static public static LocalDate selectdate;
Create a method named getSelectDate and call it to get changed value , such as inside onCreate, inside onItemSelected of month_spinner and spinYear.
private void getSelectDate() {
//added
String month = month_spinner.getSelectedItem().toString();
String year = spinYear.getSelectedItem().toString();
//String month = textviewMonth.getText().toString();
//String year = textviewYear.getText().toString();
//combinedString = "16/09/2019";
combinedString = "01/" + month + "/" + year;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MMMM/yyyy");
selectdate = LocalDate.parse(combinedString, formatter);
//
}
This will fix your button issue also. All is well . setMonthView roll backed to your old code . Here yours Class-
public class MainActivity extends AppCompatActivity implements CalendarAdapter.OnItemListener {
TextView monthYearText, textviewMonth, textviewYear, textviewYearnMonth;
RecyclerView calendarReyclerView;
public static LocalDate selectdate;
private Spinner month_spinner, spinYear;
String[] months;
String combinedString;
String selectedMonth;
String seltmont;
String selctYear;
#SuppressLint("SetTextI18n")
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textviewMonth = findViewById(R.id.textviewMonth);
textviewYear = findViewById(R.id.textviewYear);
//for testing
textviewYearnMonth = findViewById(R.id.textviewYearnMonth);
month_spinner = findViewById(R.id.month_spinner);
spinYear = findViewById(R.id.yearspin);
populateSpinnerMonth();
populateSpinnerYear();
initWidget();
// selectdate = LocalDate.now();
getSelectDate();
setMonthView();
//---- on click listener ---//
month_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (parent.getId() == R.id.month_spinner) {
seltmont = parent.getSelectedItem().toString();
Toast.makeText(MainActivity.this, "Selected Month: " + seltmont, Toast.LENGTH_SHORT).show();
textviewMonth.setText(seltmont);
//added
getSelectDate();
updateView();
setMonthView();
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
spinYear.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (parent.getId() == R.id.yearspin) {
selctYear = parent.getSelectedItem().toString();
Toast.makeText(MainActivity.this, "Selected Year" + selctYear, Toast.LENGTH_SHORT).show();
textviewYear.setText(selctYear);
getSelectDate();
updateView();
setMonthView();
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
// ---- on click listener ---//
}
#RequiresApi(api = Build.VERSION_CODES.O)
private void getSelectDate() {
//added
String month = month_spinner.getSelectedItem().toString();
String year = spinYear.getSelectedItem().toString();
//String month = textviewMonth.getText().toString();
//String year = textviewYear.getText().toString();
//combinedString = "16/09/2019";
combinedString = "01/" + month + "/" + year;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MMMM/yyyy");
selectdate = LocalDate.parse(combinedString, formatter);
//
}
//added
private void updateView() {
// combinedString = "01/" + mon + "/" + year ;
//not working
String mon = textviewMonth.getText().toString();
// Log.d("month","code is going here");
// textviewYearnMonth.setText(mon);
// Log.d("month","code cross the textviewYearnMonth");
textviewYearnMonth.setText(mon);
}
private void populateSpinnerYear() {
ArrayList<String> years = new ArrayList<String>();
int thisYear = Calendar.getInstance().get(Calendar.YEAR);
for (int i = 1950; i <= thisYear; i++) {
years.add(Integer.toString(i));
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, years);
spinYear.setAdapter(adapter);
}
private void populateSpinnerMonth() {
months = new DateFormatSymbols().getMonths();
ArrayAdapter<String> monthAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, months);
monthAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
month_spinner.setAdapter(monthAdapter);
}
#RequiresApi(api = Build.VERSION_CODES.O)
private void setMonthView() {
monthYearText.setText(monthYearFromDate(selectdate));
ArrayList<String> daysInMonth = daysInMonthArray(selectdate);
CalendarAdapter calendarAdapter = new CalendarAdapter(daysInMonth, this);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(), 7); //for calendar columns
calendarReyclerView.setLayoutManager(layoutManager);
calendarReyclerView.setAdapter(calendarAdapter);
}
#RequiresApi(api = Build.VERSION_CODES.O)
private ArrayList<String> daysInMonthArray(LocalDate date) {
ArrayList<String> daysInMonthArray = new ArrayList<>();
YearMonth yearMonth = YearMonth.from(date);
int daysInMonth = yearMonth.lengthOfMonth();
LocalDate firstOfMonth = selectdate.withDayOfMonth(1);
int dayOfWeek = firstOfMonth.getDayOfWeek().getValue();
for (int i = 1; i <= 42; i++) {
if (i <= dayOfWeek || i > daysInMonth + dayOfWeek) {
daysInMonthArray.add("");
} else {
daysInMonthArray.add(String.valueOf(i - dayOfWeek));
}
}
return daysInMonthArray;
}
#RequiresApi(api = Build.VERSION_CODES.O)
private String monthYearFromDate(LocalDate date) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM yyyy");
return date.format(formatter);
}
private void initWidget() {
calendarReyclerView = findViewById(R.id.calendarRecyclerView);
monthYearText = findViewById(R.id.monthYearTV);
}
#RequiresApi(api = Build.VERSION_CODES.O)
public void previousMonthAction(View view) {
selectdate = selectdate.minusMonths(1);
setMonthView();
}
#RequiresApi(api = Build.VERSION_CODES.O)
public void nextMonthAction(View view) {
selectdate = selectdate.plusMonths(1);
setMonthView();
}
#RequiresApi(api = Build.VERSION_CODES.O)
public void onItemClick(int position, String dayText) {
if (!dayText.equals("")) {
String message = "Selected Date " + dayText + " " + monthYearFromDate(selectdate);
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
}
}
To get "dd/MM/yyyy" this format use DateTimeFormatter.ofPattern("dd/MM/yyyy", Locale.ENGLISH).format(selectdate); , no other changes need .
To test -
#RequiresApi(api = Build.VERSION_CODES.O)
private void updateView() {
// combinedString = "01/" + mon + "/" + year ;
//not working
String mon = textviewMonth.getText().toString();
// Log.d("month","code is going here");
// textviewYearnMonth.setText(mon);
// Log.d("month","code cross the textviewYearnMonth");
textviewYearnMonth.setText(DateTimeFormatter.ofPattern("dd/MM/yyyy", Locale.ENGLISH).format(selectdate));
}
In the onItemSelected callbacks, just use the data sources with the position variable and you'll get it. For example for months spinner:
month_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (parent.getId() == R.id.month_spinner){
seltmont = months[position]; // ATTENTION HERE
Toast.makeText(MainActivity.this, "Selected Month: " + seltmont, Toast.LENGTH_SHORT).show();
textviewMonth.setText(seltmont);
setMonthView();
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
Do the same for all the spinner listeners.
I have some error in android studio.
When i try to add symbol ('*') to special item, it also add the symbol to the item that placed in +14 from the first.
I will glad if someone have solution for this problem.
For more information you can check this link, where i describe the problem.
https://youtu.be/CJFkt-Cck1A
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {
private static final String TAG = "RecyclerViewAdapter";
private Context context;
private List<WorkDayItem> workDayItemList;
//Complete
public RecyclerViewAdapter(Context context, List<WorkDayItem> workDayItemList) {
this.context = context;
this.workDayItemList = workDayItemList;
}
//Complete
//Here we create view- itemWorkday and inflate it by layout- item_one_work_day
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemWorkDay = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_one_work_day, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(itemWorkDay);
return myViewHolder;
}
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder: called." + (position + 1) + "\n" + workDayItemList.get(position).toString());
final WorkDayItem workDayItem = workDayItemList.get(position);
String dateStart = (String) DateFormat.format("dd.MM", workDayItem.getDateStart());
String timeStart = (String) DateFormat.format("HH:mm", workDayItem.getDateStart());
String timeEnd = (String) DateFormat.format("HH:mm", workDayItem.getDateEnd());
//Convert data from firebase String format to int hours and minutes format.
Double convertingDataFromFirebase;
try {
convertingDataFromFirebase = Double.parseDouble(new DecimalFormat("##.##").format(workDayItem.getCount_hours()));
} catch (NumberFormatException e) {
convertingDataFromFirebase = 0.0;
}
int hours = convertingDataFromFirebase.intValue();
convertingDataFromFirebase = (convertingDataFromFirebase - convertingDataFromFirebase.intValue()) * 60;
int minutes = convertingDataFromFirebase.intValue();
//Check if current item have description
if (workDayItemList.get(position).getDesc().length() > 2) {
Log.i(TAG, "TESTER: desc dote added");
holder.doteOfDesc.setVisibility(View.VISIBLE);
}
holder.dayPosition.setText((position + 1) + "");
holder.dateStart.setText(dateStart);
holder.timeStart.setText(timeStart);
holder.timeEnd.setText(timeEnd);
holder.countOfHours.setText(hours + ":" + minutes);
//On click on current hold open alert dialog with some functions
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
initializeAlertDialogForItem(workDayItem, holder);
}
});
}
//initialize data about current work day and have button for changing information
private void initializeAlertDialogForItem(final WorkDayItem workDayItem, final MyViewHolder holder) {
//Initialize alert dialog
final AlertDialog alertDialog = new AlertDialog.Builder(context).create();
View itemWork = LayoutInflater.from(context)
.inflate(R.layout.ad_item_desc, null, false);
alertDialog.setView(itemWork);
alertDialog.show();
//initialize alert dialog buttons and views
final ImageButton change = alertDialog.findViewById(R.id.itemAD_Edit);
final ImageButton delete = alertDialog.findViewById(R.id.itemAD_Delete);
TextView description = alertDialog.findViewById(R.id.itemADDescription);
TextView date = alertDialog.findViewById(R.id.itemADDate);
TextView from = alertDialog.findViewById(R.id.itemADFrom);
TextView to = alertDialog.findViewById(R.id.itemADTO);
String timeStart = (String) (DateFormat.format("HH:mm", workDayItem.getDateStart()));
String timeEnd = (String) (DateFormat.format("HH:mm", workDayItem.getDateEnd()));
String dateStart = (String) (DateFormat.format("dd.MM.yyyy", workDayItem.getDateStart()));
date.setText(dateStart);
from.setText(timeStart);
to.setText(timeEnd);
description.setText(workDayItem.getDesc());
//Change button
change.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onClick(View v) {
AlertDialogReport userReport = new AlertDialogReport(context, "replace-remove", workDayItem);
userReport.initializeAlertDialog();
alertDialog.dismiss();
}
});
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Delete data from firebase
Login.fc.databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
String itemTime = "" + workDayItem.getDateStart().getTime();
String firebaseTime = "" + snapshot.child("dateStart").child("time").getValue();
if (itemTime.equals(firebaseTime)) {
Login.fc.databaseReference.child(snapshot.getKey()).removeValue();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
//Delete data from SqLiteDatabase
MySQLDataBase dataBase = new MySQLDataBase(context);
dataBase.deleteItem(workDayItem);
//Finish with alert dialog and notify user
alertDialog.dismiss();
Toast.makeText(context, R.string.item_deleted, Toast.LENGTH_SHORT).show();
holder.parentLayout.removeAllViews();
}
});
}
//Complete
#Override
public int getItemCount() {
return workDayItemList.size();
}
//Complete
//Here we catch our view and getting reference between view and our objects
public class MyViewHolder extends RecyclerView.ViewHolder {
private LinearLayout parentLayout;
private TextView doteOfDesc, dayPosition, dateStart, timeStart, timeEnd, countOfHours;
public MyViewHolder(View view) {
super(view);
doteOfDesc = view.findViewById(R.id.itemDote);
dayPosition = view.findViewById(R.id.itemDayPosition);
dateStart = view.findViewById(R.id.itemDateStart);
timeStart = view.findViewById(R.id.itemStartHour);
timeEnd = view.findViewById(R.id.itemEndHour);
countOfHours = view.findViewById(R.id.itemCountOfHours);
parentLayout = view.findViewById(R.id.itemWorkDay);
}
}
}
Try adding this:
//Check if current item have description
if (workDayItemList.get(position).getDesc().length() > 2) {
Log.i(TAG, "TESTER: desc dote added");
holder.doteOfDesc.setVisibility(View.VISIBLE);
}
else if( workDayItemList.get(position).getDesc().length() < 2
&& holder.doteOfDesc.getVisibility()== View.VISIBLE ){
holder.doteOfDesc.setVisibility(View.GONE);
}
The reason why this is happening is that RecyclerView creates as many ViewHolders as its needed to cover a whole screen plus few extra ( 12 in your case) then reuses them via rebinding values to views. And you set doteOfDescto View.VISIBLE in 2. ViewHolder, but never set it back to View.GONE, thats why every time that ViewHolder is reused it will have doteOfDesc visible.
The Prettier version:
Boolean hasDescription = workDayItemList.get(position).getDesc().length() > 2;
holder.doteOfDesc.setVisibility( hasDescription ? View.VISIBLE : View.GONE);
Check updates below.
I am making an app for a stair climbing challenge that tracks the date and number of steps taken (user input, not automatic). I have an ArrayList that stored objects containing the following three variables:
String date
Int steps
Instant timeStamp
The app has two input buttons, one for integer step input, and one for date selection. There is a simple method created to filter the visible list by the selected date and a couple of visual indicators of your daily progress vs. the daily goal for flights of stairs for the day.
App screenshot
I am using the Instant variable as a timestamp to try to get around the issue of the OnClickListener selecting the position of the item from the filtered list instead of the corresponding item in the unfiltered list. I do this by using the position reported from the OnClickListener to fetch the timeStamp variable from the associated item in the filtered ArrayList, then compare that timeStamp to the items in the unfiltered ArrayList and fetch the indexOf the matching item.
All filtered ArrayLists show properly in the RecyclerView when you select a date.
The problem comes in removing items. If I add items only to one date, then you can remove and add items as you'd expect.
App function without date change (gif)
If I add to one date, then another, while they display properly, the items will be removed from the correct position but in the date you first added items, regardless of whether that is the currently selected date or not.
App function with changing date (gif)
I feel like I'm missing something relatively simple here and my brain is just too saturated with this project to see it.
Main Activity:
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private ExampleAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
Date temp_curr_date = Calendar.getInstance().getTime();
SimpleDateFormat df = new SimpleDateFormat("dd-MMM-yyyy");
String sel_date = df.format(temp_curr_date);
String curr_date = df.format(temp_curr_date);
double daily_total;
int progress = 0;
double daily_goal = 7.5;
TextView textView1;
TextView textView2;
TextView textViewFlights;
ProgressBar pb;
List<ExampleItem> mExampleList;
List<ExampleItem> filteredList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ----- LOAD SAVED ARRAY LIST -----
loadData();
// ----- SET VARIABLES -----
daily_total = totalOutput(mExampleList, sel_date);
textView1 = findViewById(R.id.total);
textView1.setText(String.valueOf(daily_total));
textViewFlights = findViewById(R.id.flights);
pb = findViewById(R.id.progress_bar);
pb.setProgress(getProgress(mExampleList, sel_date), true);
// ----- BUILD RECYCLERVIEW -----
buildRecyclerView();
filter(sel_date);
// ----- ADD STEPS DIALOGUE -----
setAddStepButton();
// ----- CALENDAR DIALOGUE -----
setDateChangeButton();
}
public double totalOutput(List<ExampleItem> steps, String date) {
try{
int temp_total = 0;
double flight_total;
for (int a = 0; a < steps.size(); a++) {
if (date.equals(steps.get(a).getText1()))
temp_total += steps.get(a).getText2();
}
flight_total = round(temp_total / 16.0, 2);
return flight_total;
} catch (Exception e){
return 0.0;
}
}
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
public static int toInt(double value) {
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(0, RoundingMode.HALF_UP);
return bd.intValue();
}
public static Date getDate(int year, int month, int day) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month);
cal.set(Calendar.DAY_OF_MONTH, day);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
private void saveData(){
SharedPreferences sharedPreferences = getSharedPreferences("shared preferences", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
Gson gson = new Gson();
String json = gson.toJson(mExampleList);
editor.putString("task list", json);
editor.apply();
}
private void loadData(){
SharedPreferences sharedPreferences = getSharedPreferences("shared preferences", MODE_PRIVATE);
Gson gson = new Gson();
String json = sharedPreferences.getString("task list", null);
Type type = new TypeToken<ArrayList<ExampleItem>>() {}.getType();
mExampleList = gson.fromJson(json, type);
if (mExampleList == null){
mExampleList = new ArrayList<>();
}
}
private int getProgress(List<ExampleItem> steps, String date){
int daily_progress_int;
try{
int temp_progress = 0;
double flight_total;
for (int a = 0; a < steps.size(); a++) {
if (date.compareTo(steps.get(a).getText1()) == 0)
temp_progress += steps.get(a).getText2();
}
flight_total = round(temp_progress / 16.0, 2);
daily_progress_int = toInt((flight_total/daily_goal)*100);
return daily_progress_int;
} catch (Exception e){
return 0;
}
}
private void addProgress(double x, int prog){
int daily_progress_int = toInt((x/daily_goal)*100);
if (progress <= 100-daily_progress_int){
progress = progress + prog;
pb = findViewById(R.id.progress_bar);
pb.setProgress(daily_progress_int, true);
} else if (progress + daily_progress_int > 100){
pb = findViewById(R.id.progress_bar);
pb.setProgress(100, true);
}
}
private void removeProgress(double x, int prog){
int daily_progress_int = toInt((x/daily_goal)*100);
progress = progress - prog;
if (progress <= 100) {
pb = findViewById(R.id.progress_bar);
pb.setProgress(daily_progress_int, true);
} else {
pb = findViewById(R.id.progress_bar);
pb.setProgress(0, true);
}
}
public void addItem(String date, int steps, Instant ts){
mExampleList.add(new ExampleItem(date, steps, ts));
filter(sel_date);
}
public void removeItem(final int position){
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
View viewInflated = LayoutInflater.from(MainActivity.this).inflate(R.layout.confirm, (ViewGroup) findViewById(android.R.id.content), false);
builder.setCancelable(true);
builder.setView(viewInflated);
builder.setPositiveButton("Yup",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
mExampleList.remove(position);
mAdapter.notifyDataSetChanged(position);
filter(sel_date);
daily_total = totalOutput(mExampleList, sel_date);
textView1 = findViewById(R.id.total);
textView1.setText(String.valueOf(daily_total));
removeProgress(daily_total,progress);
if (daily_total == 1.0){
textViewFlights.setText("flight");
} else {
textViewFlights.setText("flights");
}
saveData();
}
});
builder.setNegativeButton("Nope", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
public void buildRecyclerView(){
mRecyclerView = findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mAdapter = new ExampleAdapter(mExampleList);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new ExampleAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position) {
Instant test = filteredList.get(position).getTimeStamp();
for (ExampleItem item : mExampleList){
if (test.compareTo(item.getTimeStamp()) == 0){
removeItem(mExampleList.indexOf(item));
}
});
}
public void filter(String text){
filteredList = new ArrayList<>();
for (ExampleItem item : mExampleList){
if (item.getText1().toLowerCase().contains(text.toLowerCase())){
filteredList.add(item);
}
}
mAdapter.filterList(filteredList);
}
public void setAddStepButton(){
FloatingActionButton fab = findViewById(R.id.addSteps);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
View viewInflated = LayoutInflater.from(MainActivity.this).inflate(R.layout.add_steps, (ViewGroup) findViewById(android.R.id.content), false);
// Step input
final EditText input = viewInflated.findViewById(R.id.input);
builder.setView(viewInflated);
// OK Button
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (input.getText().length() != 0) {
try {
int in = Integer.parseInt(String.valueOf(input.getText()));
if (in > 0) {
Instant timeStamp = Instant.now();
addItem(sel_date, in, timeStamp);
dialog.dismiss();
} else {
dialog.cancel();
}
} catch (Exception e) {
dialog.cancel();
}
daily_total = totalOutput(mExampleList, sel_date);
textView1 = findViewById(R.id.total);
textView1.setText(String.valueOf(daily_total));
addProgress(daily_total, progress);
mAdapter.notifyDataSetChanged();
filter(sel_date);
if (daily_total == 1.0){
textViewFlights.setText("flight");
} else {
textViewFlights.setText("flights");
}
saveData();
} else{
dialog.cancel();
}
}
});
// Cancel Button
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
}
});
}
public void setDateChangeButton(){
FloatingActionButton fabcal = findViewById(R.id.calendarButton);
fabcal.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
LayoutInflater inflater = (LayoutInflater)getApplicationContext().getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout ll= (LinearLayout)inflater.inflate(R.layout.calendar, null, false);
CalendarView cv = (CalendarView) ll.getChildAt(0);
long milliseconds = 0;
try {
Date d = df.parse(sel_date);
milliseconds = d.getTime();
} catch (ParseException e) {
e.printStackTrace();
}
cv.setDate(milliseconds);
cv.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
#Override
public void onSelectedDayChange(
#NonNull CalendarView view,
int year,
int month,
int dayOfMonth)
{
Date temp_sel_date = getDate(year, month, dayOfMonth);
sel_date = df.format(temp_sel_date);
textView2 = findViewById(R.id.daily_total);
if (sel_date.equals(curr_date)){
textView2.setText("Today");
} else {
String dt_day = (String) DateFormat.format("dd", temp_sel_date);
String dt_month = (String) DateFormat.format("MMM", temp_sel_date);
textView2.setText(dt_month + " " + dt_day);
}
daily_total = totalOutput(mExampleList, sel_date);
textView1 = findViewById(R.id.total);
textView1.setText(String.valueOf(daily_total));
pb = findViewById(R.id.progress_bar);
pb.setProgress(getProgress(mExampleList, sel_date), true);
mAdapter.notifyDataSetChanged();
filter(sel_date);
}
});
new AlertDialog.Builder(MainActivity.this)
.setView(ll)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
}
).show();
}
});
}
}
Adapter Class:
public class ExampleAdapter extends RecyclerView.Adapter<ExampleAdapter.ExampleViewHolder> {
private static List<ExampleItem> mExampleList;
private static List<ExampleItem> exampleListFull;
private OnItemClickListener mListener;
public interface OnItemClickListener{
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
public static class ExampleViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView1;
public ImageView mDeleteImage;
public ExampleViewHolder(View itemView, final OnItemClickListener listener) {
super(itemView);
mTextView1 = itemView.findViewById(R.id.textView);
mDeleteImage = itemView.findViewById(R.id.image_delete);
mDeleteImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null){
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION){
Instant test = mExampleList.get(position).getTimeStamp();
for (ExampleItem item : exampleListFull){
int compare = test.compareTo(item.getTimeStamp());
if (compare == 0){
int delIndex = exampleListFull.indexOf(item);
position = delIndex;
}
}
listener.onItemClick(position);
}
}
}
});
}
}
public ExampleAdapter(List<ExampleItem> exampleList){
this.mExampleList = exampleList;
exampleListFull = new ArrayList<>(exampleList);
}
#NonNull
#Override
public ExampleViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.example_item, parent, false);
ExampleViewHolder evh = new ExampleViewHolder(v, mListener);
return evh;
}
#Override
public void onBindViewHolder(#NonNull ExampleViewHolder holder, int position) {
ExampleItem currentItem = mExampleList.get(position);
if (currentItem.getText2() == 1.0){
holder.mTextView1.setText(currentItem.getText2() + " step");
} else {
holder.mTextView1.setText(currentItem.getText2() + " steps");
}
}
#Override
public int getItemCount() {
return mExampleList.size();
}
public void filterList(List<ExampleItem> filteredList){
mExampleList = filteredList;
notifyDataSetChanged();
}
}
If anyone out there has any ideas, I'd love to hear from you!
UPDATE: The included code now reflects the changes suggested by users and is fully functional.
You should use
mAdapter.notifyDataSetChanged();
Instead of
mAdapter.notifyItemRemoved(position);
For more details Visit
this.
I figured it out, for those interested. Comparing the timestamps was working fine, but I put it in the wrong part of the OnClickListener cycle. It needed to be placed in the MainActivity buildRecyclerView method in the setOnClickListener override. I've updated original code to reflect this change.
Thank you anyone that took the time to look at my post.
maybe it could be better to place the onClickListner in Your adpater-class..so You can control every single card if it should be clickable or not...or if You want to place any Ads between the cards
GGK
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.calendar);
Locale.setDefault(Locale.US);
test1 = "2014-11-08";
test2 = "2014-11-07";
test3 = "2014-12-08";
test4 = "2014-12-04";
rLayout = (LinearLayout) findViewById(R.id.text);
tvView = (TextView)findViewById(R.id.tvView);
tvView1 = (TextView)findViewById(R.id.tvView1);
tvView2 = (TextView)findViewById(R.id.tvView2);
tvView3 = (TextView)findViewById(R.id.tvView3);
tvView4 = (TextView)findViewById(R.id.tvView4);
tvView5 = (TextView)findViewById(R.id.tvView5);
tvView3.setVisibility(View.GONE);
tvView4.setVisibility(View.GONE);
tvView5.setVisibility(View.GONE);
month = (GregorianCalendar) Calendar.getInstance();
itemmonth = (GregorianCalendar) month.clone();
items = new ArrayList<String>();
adapter = new CalendarAdapter(this, month);
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(adapter);
handler = new Handler();
handler.post(calendarUpdater);
TextView title = (TextView) findViewById(R.id.title);
title.setText(android.text.format.DateFormat.format("MMMM yyyy", month));
RelativeLayout previous = (RelativeLayout) findViewById(R.id.previous);
previous.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
setPreviousMonth();
refreshCalendar();
tvView.setVisibility(View.GONE);
}
});
RelativeLayout next = (RelativeLayout) findViewById(R.id.next);
next.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
setNextMonth();
refreshCalendar();
tvView.setVisibility(View.GONE);
}
});
gridview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
TextView cdate = (TextView)v.findViewById(R.id.date);
if(cdate instanceof TextView && !cdate.getText().equals(""))
{
TextView title = (TextView) findViewById(R.id.title);
title.setText(android.text.format.DateFormat.format("MMMM yyyy", month));
testMonth=title.getText().toString();
String day = cdate.getText().toString();
Toast.makeText(getApplicationContext(),day+" "+testMonth,Toast.LENGTH_SHORT).show();
}
// removing the previous view if added
if (rLayout.getChildCount() > 0) {
// rLayout.removeAllViews();
}
desc = new ArrayList<String>();
date = new ArrayList<String>();
((CalendarAdapter) parent.getAdapter()).setSelected(v);
String selectedGridDate = CalendarAdapter.dayString
.get(position);
tvView.setVisibility(View.VISIBLE);
tvView3.setVisibility(View.VISIBLE);
tvView4.setVisibility(View.VISIBLE);
tvView5.setVisibility(View.VISIBLE);
if(test1.equals(selectedGridDate))
{
tvView.setText("My Goal");
tvView.setTextColor(Color.RED);
tvView1.setText("");
tvView1.setTextColor(Color.CYAN);
tvView2.setText("");
}
else if(test2.equals(selectedGridDate))
{
tvView.setText("Passion of a Student");
tvView.setTextColor(Color.RED);
tvView1.setText("Creating my own Goal");
tvView1.setTextColor(Color.CYAN);
tvView2.setText("Circular Task");
tvView2.setTextColor(Color.GREEN);
}
else if(test3.equals(selectedGridDate))
{
tvView.setText("My test Passion");
tvView.setTextColor(Color.RED);
tvView1.setText("");
tvView1.setTextColor(Color.CYAN);
tvView2.setText("");
}
else if(test3.equals(selectedGridDate))
{
tvView.setText("My test Task");
tvView.setTextColor(Color.RED);
}
else
{
tvView.setText("No task found");
tvView.setTextColor(Color.MAGENTA);
tvView1.setText("");
tvView1.setTextColor(Color.CYAN);
tvView2.setText("");
tvView2.setTextColor(Color.GREEN);
tvView3.setVisibility(View.GONE);
tvView4.setVisibility(View.GONE);
tvView5.setVisibility(View.GONE);
}
String[] separatedTime = selectedGridDate.split("-");
String gridvalueString = separatedTime[2].replaceFirst("^0*",
"");// taking last part of date. ie; 2 from 2012-12-02.
int gridvalue = Integer.parseInt(gridvalueString);
// navigate to next or previous month on clicking offdays.
if ((gridvalue > 10) && (position < 8)) {
setPreviousMonth();
refreshCalendar();
} else if ((gridvalue < 7) && (position > 28)) {
setNextMonth();
refreshCalendar();
}
((CalendarAdapter) parent.getAdapter()).setSelected(v);
for (int i = 0; i < Utility.startDates.size(); i++) {
if (Utility.startDates.get(i).equals(selectedGridDate)) {
desc.add(Utility.nameOfEvent.get(i));
}
}
if (desc.size() > 0) {
for (int i = 0; i < desc.size(); i++) {
TextView rowTextView = new TextView(CalendarView.this);
// set some properties of rowTextView or something
rowTextView.setText("Event:" + desc.get(i));
rowTextView.setTextColor(Color.BLACK);
// add the textview to the linearlayout
rLayout.addView(rowTextView);
}
}
desc = null;
}
});
}
protected void setNextMonth() {
if (month.get(Calendar.MONTH) == month
.getActualMaximum(Calendar.MONTH)) {
month.set((month.get(Calendar.YEAR) + 1),
month.getActualMinimum(Calendar.MONTH), 1);
} else {
month.set(Calendar.MONTH,
month.get(Calendar.MONTH) + 1);
}
}
protected void setPreviousMonth() {
if (month.get(Calendar.MONTH) == month
.getActualMinimum(Calendar.MONTH)) {
month.set((month.get(Calendar.YEAR) - 1),
month.getActualMaximum(Calendar.MONTH), 1);
} else {
month.set(Calendar.MONTH,
month.get(Calendar.MONTH) - 1);
}
}
protected void showToast(String string) {
Toast.makeText(this, string, Toast.LENGTH_SHORT).show();
}
public void refreshCalendar() {
TextView title = (TextView) findViewById(R.id.title);
adapter.refreshDays();
adapter.notifyDataSetChanged();
handler.post(calendarUpdater); // generate some calendar items
title.setText(android.text.format.DateFormat.format("MMMM yyyy", month));
}
public Runnable calendarUpdater = new Runnable() {
#Override
public void run() {
items.clear();
// Print dates of the current week
DateFormat df = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
String itemvalue;
event = Utility.readCalendarEvent(CalendarView.this);
Log.d("=====Event====", event.toString());
Log.d("=====Date ARRAY====", Utility.startDates.toString());
for (int i = 0; i < Utility.startDates.size(); i++) {
itemvalue = df.format(itemmonth.getTime());
itemmonth.add(Calendar.DATE, 1);
items.add(Utility.startDates.get(i).toString());
}
adapter.setItems(items);
adapter.notifyDataSetChanged();
}
};
here I able to see all events while clicking on a particular date,but my requirement is also show the dates with bold style or any other color view that containing events without clicking gridview items.My adapter class as follows:::
public class CalendarAdapter extends BaseAdapter {
private Context mContext;
private java.util.Calendar month;
public GregorianCalendar pmonth;
public GregorianCalendar pmonthmaxset;
private GregorianCalendar selectedDate;
int firstDay;
int maxWeeknumber;
int maxP;
int calMaxP;
int lastWeekDay;
int leftDays;
int mnthlength;
String itemvalue, curentDateString;
DateFormat df;
private ArrayList<String> items;
public static List<String> dayString;
private View previousView;
public CalendarAdapter(Context c, GregorianCalendar monthCalendar) {
CalendarAdapter.dayString = new ArrayList<String>();
Locale.setDefault(Locale.US);
month = monthCalendar;
selectedDate = (GregorianCalendar) monthCalendar.clone();
mContext = c;
month.set(Calendar.DAY_OF_MONTH, 1);
this.items = new ArrayList<String>();
df = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
curentDateString = df.format(selectedDate.getTime());
refreshDays();
}
public void setItems(ArrayList<String> items) {
for (int i = 0; i != items.size(); i++) {
if (items.get(i).length() == 1) {
items.set(i, "0" + items.get(i));
}
}
this.items = items;
}
#Override
public int getCount() {
return dayString.size();
}
#Override
public Object getItem(int position) {
return dayString.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
// create a new view for each item referenced by the Adapter
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
TextView dayView;
if (convertView == null) { // if it's not recycled, initialize some
// attributes
LayoutInflater vi = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.calendar_layout, null);
}
dayView = (TextView) v.findViewById(R.id.date);
// separates daystring into parts.
String[] separatedTime = dayString.get(position).split("-");
// taking last part of date. ie; 2 from 2012-12-02
String gridvalue = separatedTime[2].replaceFirst("^0*", "");
// checking whether the day is in current month or not.
if ((Integer.parseInt(gridvalue) > 1) && (position < firstDay)) {
// setting offdays to white color.
dayView.setTextColor(Color.WHITE);
dayView.setClickable(false);
dayView.setFocusable(false);
} else if ((Integer.parseInt(gridvalue) < 7) && (position > 28)) {
dayView.setTextColor(Color.WHITE);
dayView.setClickable(false);
dayView.setFocusable(false);
} else {
// setting curent month's days in blue color.
dayView.setTextColor(Color.BLUE);
}
if (dayString.get(position).equals(curentDateString)) {
setSelected(v);
previousView = v;
} else {
v.setBackgroundResource(R.drawable.list_item_background);
}
dayView.setText(gridvalue);
// create date string for comparison
String date = dayString.get(position);
if (date.length() == 1) {
date = "0" + date;
}
String monthStr = "" + (month.get(Calendar.MONTH) + 1);
if (monthStr.length() == 1) {
monthStr = "0" + monthStr;
}
// show icon if date is not empty and it exists in the items array
ImageView iw = (ImageView) v.findViewById(R.id.date_icon);
if (date.length() > 0 && items != null && items.contains(date)) {
iw.setVisibility(View.VISIBLE);
} else {
iw.setVisibility(View.INVISIBLE);
}
return v;
}
public View setSelected(View view) {
if (previousView != null) {
previousView.setBackgroundResource(R.drawable.list_item_background);
}
previousView = view;
view.setBackgroundResource(R.drawable.calendar_cel_selectl);
return view;
}
public void refreshDays() {
// clear items
items.clear();
dayString.clear();
Locale.setDefault(Locale.US);
pmonth = (GregorianCalendar) month.clone();
// month start day. ie; sun, mon, etc
firstDay = month.get(Calendar.DAY_OF_WEEK);
// finding number of weeks in current month.
maxWeeknumber = month.getActualMaximum(Calendar.WEEK_OF_MONTH);
// allocating maximum row number for the gridview.
mnthlength = maxWeeknumber * 7;
maxP = getMaxP(); // previous month maximum day 31,30....
calMaxP = maxP - (firstDay - 1);// calendar offday starting 24,25 ...
/**
* Calendar instance for getting a complete gridview including the three
* month's (previous,current,next) dates.
*/
pmonthmaxset = (GregorianCalendar) pmonth.clone();
/**
* setting the start date as previous month's required date.
*/
pmonthmaxset.set(Calendar.DAY_OF_MONTH, calMaxP + 1);
/**
* filling calendar gridview.
*/
for (int n = 0; n < mnthlength; n++) {
itemvalue = df.format(pmonthmaxset.getTime());
pmonthmaxset.add(Calendar.DATE, 1);
dayString.add(itemvalue);
}
}
private int getMaxP() {
int maxP;
if (month.get(Calendar.MONTH) == month
.getActualMinimum(Calendar.MONTH)) {
pmonth.set((month.get(Calendar.YEAR) - 1),
month.getActualMaximum(Calendar.MONTH), 1);
} else {
pmonth.set(Calendar.MONTH,
month.get(Calendar.MONTH) - 1);
}
maxP = pmonth.getActualMaximum(Calendar.DAY_OF_MONTH);
return maxP;
}
}
Atlast I had already solved my problem changing my Runnable calendar updater as follows:
public Runnable calendarUpdater = new Runnable() {
#Override
public void run()
{
items.clear();
// Print dates of the current week
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String itemvalue;
for (int i = 0; i < 7; i++)
{
itemvalue = df.format(itemmonth.getTime());
itemmonth.add(Calendar.DATE, 1);
items.add("2014-12-08");
items.add("2014-12-04");
items.add("2014-11-07");
items.add("2014-11-08");
}
adapter.setItems(items);
adapter.notifyDataSetChanged();
}
};
Now I can see the events without clicking gridView items what I want.Thanx all of you guys for your kind cooperation in this regard. but now issue is how can I also show this event on android google calendar.
In my Android application i have a tracker activity in which i retrieve the exercises information(name , period , burned calories) from the sqlite data base based on the selected date and display these information in a linear layout , and my problem that as the user select new date the retrieved data are displayed in another "new " layout appear above the old one but what actually i want to do is to display the new retrieved data on the same layout " change the layout content with the new retrieved data ", i have tried the remove all views method but it didn't work since the data appear for few minutes then dis appear
How i can do this: when the user select a new date the new retrieved data displayed on the same layout " refresh the old data by the new one " not to display them in anew layout . how i can do that ? please help me...
java code
public class Tracker extends BaseActivity
{
private Button date_btn;
private ImageButton left_btn;
private ImageButton right_btn;
private ImageView nodata;
private TextView ex_name;
private TextView ex_BCals;
private LinearLayout excercises_LL;
private LinearLayout content_LL ;
private LinearLayout notes;
private LinearLayout details;
private int year,month,day;
private double tot_excals_burned;
private Calendar localCalendar;
private static final int DATE_DIALOG_ID=0;
private boolean has_ex_details;
private boolean has_meal_details=false;
private Cursor exercises_cursor;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.tracker);
date_btn=(Button)findViewById(R.id.btn_date);
date_btn.setText(FormatDate());
date_btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
localCalendar = Calendar.getInstance();
year = localCalendar.get(1);
month= localCalendar.get(2);
day = localCalendar.get(5);
showDialog(DATE_DIALOG_ID);
}
});
left_btn=(ImageButton)findViewById(R.id.btn_left);
left_btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
localCalendar.add(5, -1);
date_btn.setText(FormatDate(localCalendar,"EEEE, d/MMM/yyyy"));
RefreshExercisesData();
RefreshNoDataImage();
}
});
right_btn=(ImageButton)findViewById(R.id.btn_right) ;
right_btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
localCalendar.add(5, 1);
date_btn.setText(FormatDate(localCalendar,"EEEE, d/MMM/yyyy"));
RefreshExercisesData();
RefreshNoDataImage();
}
});
details=(LinearLayout)findViewById(R.id.ll_details);
notes=(LinearLayout)findViewById(R.id.ll_notes);
excercises_LL=(LinearLayout)findViewById(R.id.ll_exercises);
nodata=(ImageView)findViewById(R.id.nodata_imgV);
RefreshExercisesData();
RefreshNoDataImage();
}
private String FormatDate()
{
localCalendar = Calendar.getInstance();
return new SimpleDateFormat("EEEE, d/MMM/yyyy").format(localCalendar.getTime());
}
private String FormatDate(int year, int month, int day)
{
localCalendar = Calendar.getInstance();
localCalendar.set(year, month, day);
return new SimpleDateFormat("EEEE, d/MMM/yyyy").format(localCalendar.getTime());
}
private String FormatDate(Calendar calendar , String format)
{
return new SimpleDateFormat(format).format(calendar.getTime());
}
private void RefreshExercisesData()
{
tot_excals_burned=0;
DBAdapter db = new DBAdapter(this);
db.open();
String selected_date= date_btn.getText().toString();
Log.e("date", selected_date);
exercises_cursor = db.getExerciseInfo(selected_date);
if(exercises_cursor.getCount() !=0 )
{
has_ex_details=true;
details.setVisibility(0);
nodata.setVisibility(8);
notes.setVisibility(0);
//excercises_LL.removeAllViews();
excercises_LL.setWeightSum(1.0F);
excercises_LL.setVisibility(0);
excercises_LL.setOrientation(LinearLayout.VERTICAL);
LayoutInflater exc_LayoutInflater = (LayoutInflater)getApplicationContext().getSystemService("layout_inflater");
LinearLayout layout = (LinearLayout)exc_LayoutInflater.inflate(R.layout.tracker_header_item,null);
TextView tot_ex_cals_value=((TextView)(layout).findViewById(R.id.tv_tot_cals_value));
TextView exs_title=((TextView)(layout).findViewById(R.id.tv_item_title)) ;
exs_title.setText("Exercises ");
(layout).setPadding(0, 36, 0, 0);
excercises_LL.addView((View)layout, 0);
int i = 1;
if (exercises_cursor.moveToFirst())
{
do
{
content_LL=new LinearLayout(this);
ex_name=new TextView(this);
ex_name.setText( exercises_cursor.getFloat(1)+"," +exercises_cursor.getString(0) + "min ");
ex_name.setTextColor(R.color.black);
content_LL.addView(ex_name,0);
ex_BCals=new TextView(this);
ex_BCals.setText(Round(exercises_cursor.getFloat(2)) +" ");
ex_BCals.setTextColor(R.color.color_black);
content_LL.addView(ex_BCals,1);
tot_excals_burned = tot_excals_burned+exercises_cursor.getFloat(2);
excercises_LL.addView(content_LL, i);
i++;
}
while (exercises_cursor.moveToNext());
}
tot_ex_cals_value.setText(Round(tot_excals_burned) );
}
else if(exercises_cursor.getCount()==0 ||tot_excals_burned==0)
{
has_ex_details=false;
RefreshNoDataImage();
}
exercises_cursor.close();
exercises_cursor.deactivate();
db.close();
}
private void RefreshNoDataImage()
{
if(has_ex_details==false && has_meal_details==false)
{
notes.setVisibility(8);
excercises_LL.setVisibility(8);
nodata.setImageResource(R.drawable.bg_nodata);
nodata.setVisibility(View.VISIBLE);
}
else
nodata.setVisibility(8);
}
protected Dialog onCreateDialog(int id)
{
switch (id) {
case DATE_DIALOG_ID:
return new DatePickerDialog(this, mDateSetListener, this.year, this.month, this.day);
}
return null;
}
private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener()
{
public void onDateSet(DatePicker paramDatePicker, int year, int monthofYear, int dayofMonth)
{
Tracker.this.year=year;
month=monthofYear;
day=dayofMonth;
date_btn.setText(FormatDate(year,month,day));
RefreshExercisesData();
RefreshNoDataImage();
}
};
private String Round(double num) {
return String.format("%.1f%n", num);
}}
Its because you defined these variables as static:
public static int icon;
public static String data_text;
public static String text;
As a result only one instance of those variables are created for all instances of that class. So when you create a new Profile each time, they are overwritten with new values. You need to remove the static keyword from variable declarations:
public int icon;
public String data_text;
public String text;
Then you cannot access them as static so you need to access like this:
Profile pli = data[position];
holder.imgIcon.setImageResource(pli.icon);
holder.Datatxt.setText(pli.data_text);
holder.txt.setText(pli.text);
Check out this if you want to learn more about static: http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html