Paging in RecyclerView Android Java - java

Currently had a listview where I showed:
moves
That works fine.
The problem is that now I would like to add pagination, so I show 10 "moves", and then, with an arrow or something, link to the next 10 "moves".
This is my ListView:
RecyclweView Java:
RecyclerView lstMovsWallet = (RecyclerView) findViewById(R.id.lstMovsWallet);
lstMovsWallet.setLayoutManager(new
LinearLayoutManager(MovsMobileWallet.this));
AdapterCobrosPendientesListado adapter = new
AdapterCobrosPendientesListado(MovsMobileWallet.this, items);
lstMovsWallet.setAdapter(adapter);
Adapter for de RecyclerView :
public class AdapterCobrosPendientesListado extends RecyclerView.Adapter<AdapterCobrosPendientesListado.ViewHolder> {
private LayoutInflater mInflater;
protected List<MovimientoCuenta> items;
public AdapterCobrosPendientesListado(Context context, List<MovimientoCuenta> data) {
this.mInflater = LayoutInflater.from(context);
this.items = data;
}
#Override
public AdapterCobrosPendientesListado.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.activity_adapter_billings_listhistory, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(AdapterCobrosPendientesListado.ViewHolder holder, int position) {
DecimalFormat formater = new DecimalFormat("###.00");
String numero = items.get(position).getNumber();
String cantidad = items.get(position).getMonto();
String fecha = items.get(position).getFecha();
String referencia = items.get(position).getReferencia();
String debitoCredito = items.get(position).getDebitoCredito();
holder.number.setText(numero);
holder.mount.setText(cantidad);
holder.date.setText(fecha);
holder.ref.setText(referencia);
if(debitoCredito.compareTo("DBT")==0){
holder.title.setText("Pago");
holder.auxBilling.setImageResource(R.mipmap.signonegativo);
}
else {
holder.title.setText("Cobro");
holder.auxBilling.setImageResource(R.mipmap.signomas);
}
}
#Override
public int getItemCount() {
return items.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView number;
public TextView mount;
public TextView date;
public ImageView auxBilling;
public TextView ref;
public TextView title ;
public ViewHolder(View itemView) {
super(itemView);
number = itemView.findViewById(R.id.txtNumberPhoneBilling);
mount = itemView.findViewById(R.id.txtMountBillingNotifications);
date = itemView.findViewById(R.id.txtDateBillingNotifications);
auxBilling = itemView.findViewById(R.id.btnCancelBillingNotifications);
ref = itemView.findViewById(R.id.txtDateBillingRef);
title = itemView.findViewById(R.id.TitleMovs);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
// if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
/* // convenience method for getting data at click position
public String getItem(int id) {
return mData.get(id);
}
// allows clicks events to be caught
public void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}*/
}
Here I leave the class of movements to replicate:
public class MovimientoCuenta {
private String number;
private String monto;
private String moneda;
private String fecha;
private String ID;
private String referencia ;
private String filtro ;
private String debitoCredito ;
private String nombreMov;
public MovimientoCuenta(String number, String monto, String moneda, String fecha, String ID, String referencia, String filtro, String debitoCredito,String nombreMov) {
this.number = number;
this.monto = monto;
this.moneda = moneda;
this.fecha = fecha;
this.ID = ID ;
this.filtro =filtro;
this.referencia=referencia;
this.debitoCredito =debitoCredito;
this.nombreMov =nombreMov;
}
Any help will be welcome from now thanks.

You can try adding another data model in your list at the end of the current list. Have the view type of this model be a button. On clicking this, you can fetch the next set of moves from your server using offset and limit in your query.
Make the list of a generic type say Parcelable and have all the elements in the list be child via either extending or implementing the parent type.
Eg the list can be of type class A
ArrayList<A>
And the elements in it can be of types
Class B extends A
Class C extends A
Now in your getView , check the type of data using instance of operator and inflate the correct view layout
If(yourlist.get(positionpassedingetview) instanceof B){
//Inflate the view for B item if not already inflated
}else{
//Inflate view of type C
}
For every click on the above said load more item button, use the offset as the current length of list minus one and the limit will always be 10. For the first ever query, use offset as 0 or the sql will throw an exception, rest subsequent queries will have the offset = list size minus one (minus one because the last element of the list is a load more button and not the actual data)
Eg in mysql, this could be:
Select * from yourtable where yourcondition order by yourorder limit youroffset,10;
If there's no more data, just update the model of the load more saying no more items and disabling the button. If you find more items, insert them at the poisition above the last element which is the load more button and notify the list adapter.
You will have to find a tutorial for such a heterogenous list view with more than one viewtypes and viewholders. This is a general idea of how to do it, i myself use this approach with a recyclerview with a similar logic

Related

Saving State of RecyclerView Checkbox

I'm a bit new to Android development.
I was wondering how I can save state of checkboxes in a RecyclerView. I know there are existing solutions for this, but I have a list of items in another RecyclerView that uses the same set of checkboxes. When you click an item, it should show all checkboxes and check those previously checked checkboxes for that item.
I have seen posts using SharedPreferences to save the state but I have different checkboxes states for different item click in another RecyclerView and I do not know how to save these different states.
This is the Adapter class for the list of checkboxes named CurrentAddonAdapter.java:
public class CurrentAddonAdapter extends RecyclerView.Adapter<CurrentAddonAdapter.ViewHolder17> {
private Context context;
private ArrayList items3,price3;
private List<AddonList> addonlist1;
private OnItemClickListener17 mOnItemClickListener17;
CurrentAddonAdapter(Context context, ArrayList items3, ArrayList price3,List addonlist1,OnItemClickListener17 onItemClickListener17){
this.context = context;
this.items3 = items3;
this.price3 = price3;
this.addonlist1 = addonlist1;
this.mOnItemClickListener17 = onItemClickListener17;
}
#NonNull
#Override
public ViewHolder17 onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.addoncard,parent,false);
return new ViewHolder17(view,mOnItemClickListener17);
}
private SparseBooleanArray selecteditems = new SparseBooleanArray();
#Override
public void onBindViewHolder(#NonNull final CurrentAddonAdapter.ViewHolder17 holder, int position) {
holder.item1.setText(String.valueOf(items3.get(position)));
holder.price1.setText(String.valueOf(price3.get(position)));
final AddonList currentaddon = addonlist1.get(position);
holder.item1.setChecked(selecteditems.get(position));
holder.item1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(holder.item1.isChecked()){
holder.item1.setChecked(true);
mOnItemClickListener17.onItemCheck(currentaddon);
}
else{
holder.item1.setChecked(false);
mOnItemClickListener17.onItemUncheck(currentaddon);
}
}
});
}
#Override
public int getItemCount() {
return items3.size();
}
public class ViewHolder17 extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView price1;
CheckBox item1;
OnItemClickListener17 onItemClickListener17;
public ViewHolder17(#NonNull View itemView, final OnItemClickListener17 onItemClickListener17) {
super(itemView);
item1 = itemView.findViewById(R.id.addoncheck);
price1 = itemView.findViewById(R.id.priceadd);
this.onItemClickListener17 = onItemClickListener17;
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
onItemClickListener17.onItemClick7(getAdapterPosition());
}
}
public interface OnItemClickListener17{
void onItemClick7(int position);
void onItemCheck(AddonList addonList);
void onItemUncheck(AddonList addonList);
}
}
This is the code for the item click. It shows a dialog box with the list of all checkboxes with CardView elements array named items3 and price3
Cursor viewaddon = db.viewalladdon();
while(viewaddon.moveToNext()){
items3.add(viewaddon.getString(2));
price3.add(viewaddon.getString(3));
addonlist1.add(new AddonList(viewaddon.getString(2)));
}
addrecycler.setHasFixedSize(true);
currentAddonAdapter = new CurrentAddonAdapter(getActivity(),items3,price3,addonlist1,this);
addrecycler.setAdapter(currentAddonAdapter);
addrecycler.setLayoutManager(new LinearLayoutManager(getActivity()));
Please, help. I've been trying to find a solution for weeks and I still can't find one. I just really need this for school.

Perform/Add search functionality to a custom ListView

i created a custom listView of all installed apps but i don't know how to add a search functionality because it's a little complicated(..my app) can anyone help me with that?
(picture of the app )
App.java - app constructor
public class App {
private int number;
private String name;
private String version;
private Drawable drawable;
public App(int number, String name, String version, Drawable drawable){
this.number = number;
this.name = name;
this.version = version;
this.drawable = drawable;
}
//Getters & Setters...
}
AppAdapter.java - listView Adapter
public class AppAdapter extends ArrayAdapter<App> {
Context context;
List<App> objects;
public AppAdapter(Context context, int resources, int textViewResources, List<App> objects){
super(context, resources, textViewResources, objects);
this.context = context;
this.objects = objects;
}
public View getView(int position, View convertView, ViewGroup parent){
LayoutInflater layoutInflater = ((Activity)context).getLayoutInflater();
View view = layoutInflater.inflate(R.layout.custom_card,parent,false);
TextView tvName = (TextView)view.findViewById(R.id.tvName);
TextView tvVersion = (TextView)view.findViewById(R.id.tvVersion);
TextView tvNumber = (TextView)view.findViewById(R.id.tvNumber);
ImageView ivImage = (ImageView)view.findViewById(R.id.ivImage);
App current = objects.get(position);
tvName.setText(String.valueOf(current.getName()));
tvVersion.setText(String.valueOf(current.getVersion()));
tvNumber.setText(String.valueOf(current.getNumber()));
ivImage.setImageDrawable(current.getDrawable());
return view;
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
ArrayList<App> appList;
ListView lv;
AppAdapter appAdapter;
App lastSelected;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText etSearch = findViewById(R.id.etSearch);
PackageManager packageManager = getPackageManager();
List<PackageInfo> mApps = packageManager.getInstalledPackages(0);
//array strings to all packages, names and version
final String[] arrPackages = new String[mApps.size()];
final String[] arrVersion = new String[mApps.size()];
String[] arrName = new String[mApps.size()];
//array of Drawables for icons...
Drawable[] arrIcons = new Drawable[mApps.size()];
App[] arrApps = new App[mApps.size()];
appList = new ArrayList<>();
//reading all app's packages and version to the arrays
for (int i = 0; i < mApps.size(); i++){
arrVersion[i] = mApps.get(i).versionName;
arrPackages[i] = mApps.get(i).packageName;
}
for (int i = 0; i < mApps.size(); i++){
try {//getting app's names from theres packages
arrName[i] = (String) packageManager.getApplicationLabel(packageManager.getApplicationInfo(arrPackages[i], PackageManager.GET_META_DATA));
} catch (PackageManager.NameNotFoundException e) {
arrName[i] = "Unknown";
}
try {//same as names for icons
arrIcons[i] = packageManager.getApplicationIcon(arrPackages[i]);
} catch (PackageManager.NameNotFoundException e) {
arrIcons[i] = getDrawable(R.drawable.placeholder);
}
arrApps[i] = new App(i + 1, "Name: "+arrName[i], "Version: "+arrVersion[i], arrIcons[i]);
appList.add(arrApps[i]);
}
//on item click open app
appAdapter = new AppAdapter(this,0,0,appList);
lv = findViewById(R.id.lv);
lv.setAdapter(appAdapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
lastSelected = appAdapter.getItem(position);
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(arrPackages[position]);
if (launchIntent != null) {
startActivity(launchIntent);//null pointer check in case package name was not found
}
}
});
//(trying to..) Add Text Change Listener to EditText
etSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Call back the Adapter with current character to Filter
MainActivity.this.appAdapter.getFilter().filter(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
}
(when i try to search something it's gives nothing...)
exchange this line
App current = objects.get(position);
to this
App current = (App) getItem(position);
you don't need to keep List<App> objects; inside your adapter, it is passed in constructors super call (last param) and kept under the hood for you. check out ArrayAdapter source - passed ArrayList is kept as mObjects and further used in some methods, e.g. getPosition, getCount and getItem
ArrayAdapter already implements Filterable, so there is an overriden method getFilter, which returns ArrayFilter - this inner class is declared on the bottom. when you call getFilter().filter( then performFiltering gets called (in a separated thread) and iterates through local copy of your data (line 588). It is using values.get(i).toString().toLowerCase() to compare objects from array with passed String (CharSequence in fact). so in your custom App class override toString method and return in there some searchable value, e.g.
#Override
public String toString(){
return name;
}
this is not best approach, because toString may be used in a lot of mechanisms (its base method of Object) and with above toString implementation two Apps with same name, but different version or number are threated as same object, which isn't true... maybe better way would be to return name+version+number;, but still you have also Drawable in there. thats why I've suggested (in this answer before edit) to make own class extends BaseAdapter and implement own filtering or at least use ArrayAdapter, but override getFilter method and return your own Filter implementation comparing variables instead of using toString. Then won't be needed to override this class, leave it as it is. By default it returns kind-of memory address, so it is unique for every new App instance, even when created with exacly same variables
also in THIS answer you can find nice example how to implement that Filter

How can I stop my recyclerView view type from changing after scrolling?

Inside my RecyclerView Adapter class I have 2 view types to display the results of my query:
#Query("SELECT l.log_id, l.junction_id ,l.date, l.workout_id, l.total_weight_lifted,
l.reps, l.set_number FROM log_entries_table
AS l LEFT JOIN exercise_workout_junction_table AS ej
ON ej.exercise_workout_id = l.junction_id WHERE ej.exercise_id = :exerciseID
ORDER BY substr(l.date, -4) DESC, substr(l.date, -7) DESC, (l.date) DESC")
LiveData<List<Log_Entries>> getAllExerciseHistoryLogs(int exerciseID);
The first view type is used to display all logEntries in which the date is unique:
The second view type is to display the rest of the logEntries which share the same date as the above:
My current code works fine, however every time I scroll down and the recyclerView updates, all the log-Entries with 'unique' dates (which should use the first viewType) get changed to display the second view type.
How can I stop my recyclerView view type from changing?
Before scroll -> After Scroll
RecyclerView Adapter
public class ExerciseHistoryAdapter2 extends RecyclerView.Adapter {
private OnItemClickListener listener;
private List<Log_Entries> allLogEntries = new ArrayList<>();
private List<String> uniqueDates = new ArrayList<>();
String logEntryDate;
public void setExercises(List<Log_Entries> allLogEntries) {
this.allLogEntries = allLogEntries;
notifyDataSetChanged();
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view;
if (viewType == 0) {
view = layoutInflater.inflate(R.layout.exercise_history_item, parent, false);
return new ViewHolderOne(view);
}
view = layoutInflater.inflate(R.layout.exercise_history_item_two, parent, false);
return new ViewHolderTwo(view);
}
#Override
public long getItemId(int position) {
return allLogEntries.get(position).getLog_id();
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
logEntryDate = allLogEntries.get(position).getDate();
if (uniqueDates.contains(logEntryDate)) {
// bindViewHolder2
ViewHolderTwo viewHolderTwo = (ViewHolderTwo) holder;
viewHolderTwo.textViewWeight.setText(String.valueOf(allLogEntries.get(position).getTotal_weight_lifted()));
viewHolderTwo.textViewReps.setText(String.valueOf(allLogEntries.get(position).getReps()));
} else {
uniqueDates.add(logEntryDate);
//bind viewholder1
ViewHolderOne viewHolderOne = (ViewHolderOne) holder;
viewHolderOne.textViewDate.setText(allLogEntries.get(position).getDate());
viewHolderOne.textViewWeight.setText(String.valueOf(allLogEntries.get(position).getTotal_weight_lifted()));
viewHolderOne.textViewReps.setText(String.valueOf(allLogEntries.get(position).getReps()));
}
}
#Override
public int getItemCount() {
return allLogEntries.size();
}
#Override
public int getItemViewType(int position) {
logEntryDate = allLogEntries.get(position).getDate();
if (uniqueDates.contains(logEntryDate)) {
return 1;
}
return 0;
}
class ViewHolderOne extends RecyclerView.ViewHolder {
private TextView textViewDate;
private TextView textViewWeight;
private TextView textViewReps;
public ViewHolderOne(#NonNull View itemView) {
super(itemView);
textViewDate = itemView.findViewById(R.id.textView_dateH);
textViewWeight = itemView.findViewById(R.id.textView_weightH);
textViewReps = itemView.findViewById(R.id.textView_repss);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = getAdapterPosition();
if (listener != null && position != RecyclerView.NO_POSITION) {
listener.onItemClick(allLogEntries.get(position));
}
}
});
}
}
class ViewHolderTwo extends RecyclerView.ViewHolder {
private TextView textViewWeight;
private TextView textViewReps;
public ViewHolderTwo(#NonNull View itemView) {
super(itemView);
textViewWeight = itemView.findViewById(R.id.textView_weightH2);
textViewReps = itemView.findViewById(R.id.textView_repss2);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = getAdapterPosition();
if (listener != null && position != RecyclerView.NO_POSITION) {
listener.onItemClick(allLogEntries.get(position));
}
}
});
}
}
public interface OnItemClickListener {
void onItemClick(Log_Entries log_entries);
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
}
Your getItemViewType and onBindViewHolder has some issues.
#Override
public int getItemViewType(int position) {
// type 0 = with date header
// type 1 = without date header
// if list is sorted chronologically
if (position == 0) {
return 0
}
String currentDate = allLogEntries.get(position).getDate();
String previousDate = allLogEntries.get(position - 1).getDate();
if (currentDate.equals(previousDate)) {
return 1
} else {
return 0
}
}
The first item will always have the header since the list is sorted chronologically. For the rest of the items, you need to check whether the date for the current item is the same as the previous item. Based on that condition you return the type.
You do not need to manage a list of unique dates. You have shared mutable states between the functions that are being called multiple times and are not synced. Just delete these and the references of them from onBindViewHolder
private List<String> uniqueDates = new ArrayList<>();
String logEntryDate;
I think to set holder.setIsRecyclable(false); would solve the issue, because the recycler view will then no longer recycle the items... But this is not a good solution for long lists.
EDIT:
I reviewd your code in onBindViewHolder()...
I think the problem comes with uniqueDates.add(logEntryDate); and that the onBindViewHolder method is called multiple times.
This is how the recycler view proceeds:
the first item in list will be unique because uniqueDates is empty. Therefore it will be added to the list.
the other items will be added correctly, as you see in your first screenshot
when you scroll down, the onBindViewHolder method will be executed for every item again
because the uniqueDates list already contains the first date, as it was added in step one, this item will now recognized as not-unique one
the wrong list will be displayed after scrolling as you see in your second screenshot
SOLUTION:
You will have to add a logic which identifies unique dates in another way, which is independet of the onBindViewholder method
OR
you would have to add code, that removes dates on a specific point, so that the list identifies the first item every time as unique and not just the first time.

Using an Endless RecyclerView as a Calendar

I'm currently new to android development and I'm in the process of building my first app. I'm stuck on a particular tricky bit in which I'm trying to implement and Endless Recycler View.
I'm using a recycler view (currently) just to get the current dates and display them in a calendar output. There is two things that are really holding me up. One there is not much documentation out there on using an endless recycler view without a database (I do plan to but again not right now), and not knowing where/how to make it endless. The recyclerView I have Implemented is already working I just need it to load endlessly. The only examples I could find essentially required me to be using a database, or were to create one gigantic method in the onCreate method. Again I have also tried to implement my own setOnScrollListener inside the home class but alas I couldn't get it working.
Below are the desired results that I've got pictured in my head.
Link to UI picture
Here is my code so far. Ideally I would like to keep the on scroll Listener in the RecyclerAdapter as I will probably reuse it later on in other aspects of the app. Thank you in advanced.
HOME CLASS
public class Home extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
private static final String TAG = "Home Class" ;
//Recycler View Variables and myCalendarClass Variables
private myCalendarClass myCalendarObj;
private int weeksInView = 1; //will need to make this update dynamicallly based on when a user toggles the view
private ArrayList<Calendar> calendarArrayList = new ArrayList<>();
private ArrayList<Integer> iconList = new ArrayList<>();
private ArrayList<Integer> eventCounterList = new ArrayList<>();
//recycler view dynamic loading variables
private RecyclerView calendarRecyclerView;
private boolean isLoading = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
initializeNavMenuButtons();
setViewSpinner();
this.myCalendarObj = new myCalendarClass();
setAllCalendarFields(this.myCalendarObj);
getImagesAndEventCounters();
//Example of the order to call the methods when a user switches the view
//setCalendarItrToCurrentSunday();
//setCalendarArrayList();
//getImagesAndEventCounters();
}
//Recycler view code
//gets images and events to feed into the recycler view
private void getImagesAndEventCounters() {
Log.d(TAG, "initImageBitMaps: called");
ArrayList<Calendar> weekView = getCalendarArrayList();
int daysInView = this.weeksInView * 7;
System.out.println("Days in view " + daysInView + " Weeks In View " + this.weeksInView);
for (int i = 0; i < daysInView; i++) {
calendarArrayList.add(weekView.get(i));
iconList.add(R.id.fitnessIcon);
eventCounterList.add(R.string.XEventsDefault);
iconList.add(R.id.educationIcon);
eventCounterList.add(R.string.XEventsDefault);
iconList.add(R.id.workIcon);
eventCounterList.add(R.string.XEventsDefault);
iconList.add(R.id.personalIcon);
eventCounterList.add(R.string.XEventsDefault);
initRecyclerView();
}
}
//passes data to the parent recycler view and sets the view
private void initRecyclerView() {
//For one recyclerView
this.parentLayoutManager = new GridLayoutManager(this, 7);
//GridLayoutManager layoutManager = parentLayoutManager;
RecyclerView recyclerView = findViewById(R.id.calendarRecyclerView);
recyclerView.setLayoutManager(parentLayoutManager);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(this,iconList,eventCounterList,weeksInView,calendarArrayList);
recyclerView.setAdapter(adapter);
//ViewSpinner(Drop Down Menu)
private void setViewSpinner(){
Spinner viewSpinner = findViewById(R.id.ViewDropDownButton);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,R.array.Calendar_View_List, android.R.layout.simple_spinner_item);
viewSpinner.setAdapter(adapter);
viewSpinner.setOnItemSelectedListener(this);
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String text = parent.getItemAtPosition(position).toString();
myCalendarClass myCalendarObj;
if(text.equals("Week View")){
myCalendarObj = new myCalendarClass("Week View");
setAllCalendarFields(myCalendarObj);
getImagesAndEventCounters();
this.myCalendarObj = myCalendarObj;
}
else if (text.equals("Biweekly View")){
myCalendarObj = new myCalendarClass("Biweekly View");
setAllCalendarFields(myCalendarObj);
getImagesAndEventCounters();
this.myCalendarObj = myCalendarObj;
}
else if (text.equals("Month View")){
myCalendarObj = new myCalendarClass("Month View");
setAllCalendarFields(myCalendarObj);
getImagesAndEventCounters();
this.myCalendarObj = myCalendarObj;
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
//setters
//sets all the local variables needed from myCalendarClass
private void setAllCalendarFields(myCalendarClass c){
this.myCalendarObj = c;
this.calendarArrayList = c.getCalendarArrayList();
this.weeksInView = c.getWeeksInView();
}
//getters
//returns the calendar arraylist
private ArrayList<Calendar> getCalendarArrayList(){
return this.calendarArrayList;
}
RECYCLER ADAPTER
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private static final String TAG = "RecyclerViewAdapter";
//variables for creating the recyclerView cards
private ArrayList<Integer> iconList;
private ArrayList<Integer> eventCounterList;
private Context mContext;
private int itemCount;
private ArrayList<Calendar> calendarArrayList;
private ArrayList<String> dayStr;
private ArrayList<String> dayNum;
public RecyclerViewAdapter(Context context, ArrayList<Integer> imageList, ArrayList<Integer> eventArray, int weeksInView,ArrayList<Calendar> calendarArrayList){
this.iconList = imageList;
this.eventCounterList = eventArray;
this.mContext = context;
this.itemCount = weeksInView*7;
this.calendarArrayList = calendarArrayList;
setDayStrNDayNum();
}
#NonNull
#Override
//this is the method that actually inflates each individual layout
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Log.d(TAG, "onCreateViewHolder: called.");
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_listitem,parent,false);
return new ViewHolder(view);
}
#Override
//this is where we bind the data to each individual list items
//essentially all the data and stuff is actually attached in this method to each indiviual list item
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder: called");
holder.fitnessIcon.getDrawable();
holder.educationIcon.getDrawable();
holder.personalIcon.getDrawable();
holder.workIcon.getDrawable();
holder.fitnessEventCounter.setText(eventCounterList.get(position));
holder.educationEventCounter.setText(eventCounterList.get(position));
holder.workEventCounter.setText(eventCounterList.get(position));
holder.personalEventCounter.setText(eventCounterList.get(position));
holder.dayString.setText(dayStr.get(position));
holder.dayNum.setText(dayNum.get(position));
}
//returns the amount of items we wish to include in the recycler view (not the individual items within a card layout
// but instead how many cards we wish to include...probably
#Override
public int getItemCount() {
return itemCount;
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView fitnessIcon;
ImageView educationIcon;
ImageView workIcon;
ImageView personalIcon;
TextView dayString;
TextView dayNum;
TextView fitnessEventCounter;
TextView educationEventCounter;
TextView workEventCounter;
TextView personalEventCounter;
public ViewHolder(View itemView){
super(itemView);
//icons within the layout_listitem
fitnessIcon = itemView.findViewById(R.id.fitnessIcon);
educationIcon = itemView.findViewById(R.id.educationIcon);
workIcon = itemView.findViewById(R.id.workIcon);
personalIcon = itemView.findViewById(R.id.personalIcon);
//text fields within the layout_listitem
dayNum = itemView.findViewById(R.id.dayNum);
dayString = itemView.findViewById(R.id.dayStr);
fitnessEventCounter = itemView.findViewById(R.id.fitnessEventCounter);
educationEventCounter = itemView.findViewById(R.id.educationEventCounter);
workEventCounter = itemView.findViewById(R.id.workEventCounter);
personalEventCounter = itemView.findViewById(R.id.personalEventCounter);
}
}
public void setItemCount(int newItemCount){
itemCount = newItemCount;
}
//sets the dayStr arrays and the dayNum array using CalendarArrayList
// to pull the day in the month and the string value(monday,tuesday,etc.)
private void setDayStrNDayNum(){
Iterator<Calendar> itr = this.calendarArrayList.iterator();
ArrayList<String> tempDayNum = new ArrayList<>();
ArrayList<String> tempDayStr = new ArrayList<>();
int i = 0;
while(itr.hasNext()){
String dayInMonth = getDayInMonth(calendarArrayList.get(i));
String weekDayToString = weekDayToString(calendarArrayList.get(i));
tempDayNum.add(dayInMonth);
tempDayStr.add(weekDayToString);
i++;
itr.next();
}//while
this.dayNum = tempDayNum;
this.dayStr = tempDayStr;
}
//takes in a Calendar Obj, gets the int, and returns it in a String Format
private String getDayInMonth (Calendar c){
Integer temp = c.get(Calendar.DAY_OF_MONTH);
String answer = Integer.toString(temp);
return answer;
}
//takes in a Calendar Obj, gets the weekday digit from 1 to 7, and returns a String
// 1 being Su for Sunday, 2 Mo for Monday, and etc.
private String weekDayToString (Calendar x){
int temp = x.get(Calendar.DAY_OF_WEEK);
switch(temp){
case 1:
return "Su";
case 2:
return "Mo";
case 3:
return "Tu";
case 4:
return "We";
case 5:
return "Th";
case 6:
return "Fr";
case 7:
return "Sa";
}
return "null";
}//weekDayToString
}
here is an idea: in onCreate create some base list containing the next 1000 dates surrounding the current date for your recyclerview and use the following link to understand how to find out after any scrollevent at which position you are on the recyclerview. once you get close to the edges simply add an additional 1000 dates on that end of the spectrum.
Look at the following link to see how to set an onscrolllistener on a recyclerview inside of the adapter (basically you need to pass the recyclerview to the adapters constructor)
hope this helps

How to put an array in a item of RecyclerView?

I want to put an array of names(NomUser) in the first item of the RecyclerView. So I know I need to change the String of the constructor putting String[] but then how I can put the information when I do a new PendingTrajectPOJO?
I want the names of Joan and Ousmane on the first item
Like this
Here is where I put the information
listPendingTraject.add(new PendingTrajectPOJO(nomUser,"Surname","Origin","Destination",Data));
adapter = new AdapterPendingTraject(listPendingTraject);
recyclerPendingTraject.setAdapter(adapter);
This is my constructor
public PendingTrajectPOJO(String name, String surName, String origin, String destination, String date) {
Name = name;
SurName = surName;
Origin = origin;
Destination = destination;
Date = date;
}
My adapter
public class AdapterPendingTraject extends RecyclerView.Adapter<AdapterPendingTraject.ViewHolderPendingTraject>{
ArrayList<PendingTrajectPOJO> listPendingTraject;
public AdapterPendingTraject(ArrayList<PendingTrajectPOJO> listPendingTraject) {
this.listPendingTraject = listPendingTraject;
}
#Override
public ViewHolderPendingTraject onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.pending_traject_item,null,false);
return new ViewHolderPendingTraject(view);
}
#Override
public void onBindViewHolder(ViewHolderPendingTraject holder, int position) {
holder.Name.setText(listPendingTraject.get(position).getName());
holder.Surname.setText(listPendingTraject.get(position).getSurName());
holder.Origin.setText(listPendingTraject.get(position).getOrigin());
holder.Destination.setText(listPendingTraject.get(position).getDestination());
holder.Date.setText(listPendingTraject.get(position).getDate());
holder.itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Context context = v.getContext();
Intent intent = new Intent(context, Journey.class);
//intent.putExtra("FileName", list.get(position));
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return listPendingTraject.size();
}
public class ViewHolderPendingTraject extends RecyclerView.ViewHolder {
TextView Name,Surname,Origin,Destination,Date;
public ViewHolderPendingTraject(View itemView) {
super(itemView);
Name=(TextView)itemView.findViewById(R.id.tvptName);
Surname=(TextView)itemView.findViewById(R.id.tvptSurName);
Origin=(TextView)itemView.findViewById(R.id.tvptOrigin);
Destination=(TextView)itemView.findViewById(R.id.tvptDestination);
Date=(TextView)itemView.findViewById(R.id.tvptDate);
}
}
}
What you want to do is create a public method in your adapter to pass in a new item. In this method, you need to notify the adapter that you have updated the items. I would recommend using the DiffUtil to find out which items have changed like this:
public void addNewItem(PendingTrajectPOJO p) {
ArrayList<PendingTrajectPOJO> old = new ArrayList<PendingTrajectPOJO>(listPendingTraject)
this.listPendingTraject = new ArrayList<PendingTrajectPOJO>()
this.listPendingTraject.add(p)
this.listPendingTraject.addAll(old)
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new MyDiffCallback(old, this.listPendingTraject));
diffResult.dispatchUpdatesTo(this);
}
This way, when you add items, it will animate them and slide the old ones down (Since you mentioned you wanted the top item to be the new one)
Note: I have to test this later, I wrote this on the fly
In your adapter, create a custom method that accepts PendingTrajectPOJO as parameter, then update your listPendingTraject
Example:
public void addNewItem(PendingTrajectPOJO p) {
listPendingTraject.add(p);
notifyDataSetChanged();
}

Categories