Lint error Do not treat position as fixed; only use immediately...
The documentation of RecyclerView.Adapter.onBindViewHolder() states:
Note that unlike ListView, RecyclerView will not call this method
again if the position of the item changes in the data set unless the
item itself is invalidated or the new position cannot be determined.
For this reason, you should only use the position parameter while
acquiring the related data item inside this method and should not keep
a copy of it. If you need the position of an item later on (e.g. in a
click listener), use getAdapterPosition() which will have the updated
adapter position
So, technically items may be re-arranged (like sorted, or moved around) and binding will not be necessary because items are not invalidated yet. This means onBindViewHolder()
may NOT be called if items show the same data, but just their position/index in a list changes. The position
variable received holds true only for the scope of bind function and will not always point to the correct position in the data set. That's why the function getAdapterPosition()
must be called every time updated position is needed.
IMHO, mLastPosition = holder.getAdapterPosition();
is still potentially wrong. Because item may be re-arranged and mLastPosition
still points to old position.
About why lint is silent, perhaps Lint's rule is not that thorough. It's only checking whether the position
parameter is being copied or not.
What is difference between holder.getAdapterPosition() and position attribute from constructor in onBindViewHolder()
The warning you get is not about using position
or getAdapterPosition()
. It is about saving the position:
holder.position = position;
You don't need to save the position in your holder, because its position can change and you can always get its position by calling holder.getAdapterPosition()
;
From the docs:
Note that unlike ListView, RecyclerView will not call this method
again if the position of the item changes in the data set unless the
item itself is invalidated or the new position cannot be determined.
For this reason, you should only use the position parameter while
acquiring the related data item inside this method and should not keep
a copy of it. If you need the position of an item later on (e.g. in a
click listener), use getAdapterPosition() which will have the updated
adapter position.
About which to use:
Both should return the same result if called inside the onBindViewHolder
method. I would recommend using position
because it is easiest and safest.
Checking checkbox to delete RecylerView row deletes other row
You are missing if(isChecked)
in OnCheckedChangeListener
You don't need to call notifyDataSetChanged(), use getAdapterPosition() instead of position.
public ProductViewHolder(View itemView) {
super(itemView);
spinner = itemView.findViewById(R.id.spinner);
editText = itemView.findViewById(R.id.editText);
textView5 = itemView.findViewById(R.id.textView5);
checkBox = itemView.findViewById(R.id.checkBox);
rootView = itemView.findViewById(R.id.linearLayout);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// makes the set disappear when checkbox is ticked.
if(isChecked){
productList.remove(getAdapterPosition());
notifyItemRemoved(getAdapterPosition());
Toast.makeText(create, "Done!", Toast.LENGTH_LONG).show();
}
}
});
}
Add your code inside ProductViewHolder
constructor
You need to create new product every time a new product added So:
floatingActionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mProduct= new Product() // **something like that which has some values, the thing is you need to create new product with new keyword**
productList.add(mProduct);
if(adapter != null)
adapter.notifyDataSetChanged();
//Handle the empty adapter here
}
});
the thing is you need to create new product with new keyword
Get spinner selected item inside RecyclerView
I think you have to try this
showSpinnerList.setOnItemSelectedListener(new
AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int
position, long id) {
// On selecting a spinner item
String item = parent.getItemAtPosition(position).toString();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// todo for nothing selected
}
});
Related Topics
Gesture Detection and Scrollview Issue
Rotate Zoom Drag Image in Android Imageview
How Do Cursorloader Automatically Updates the View Even If the App Is Inactive
Android: Onsaveinstancestate Not Being Called from Activity
How to Set an Imageview's Image from a String
Android Gridview Keep Item Selected
How to Finish Activity When Starting Other Activity in Android
Noclassdeffounderror Below Sdk 21
How to Use Tabhost.Ontabchangelistener in Android
Push Up Content When Clicking in Edit Text
Mediametadataretriever.Getframeattime() Returns Only First Frame
Install App via Usb: the Device Is Temporarily Restricted
Folder Added on Android Is Not Visible via Usb
In Espresso, How to Avoid Ambiguousviewmatcherexception When Multiple Views Match
Triggering Event When Button Is Pressed Down in Android