I am new to Android Development i am trying to sort item position in Recyclerview
i am useing Realm Database and my data-set for Adapter is RealmResults<ShoppingList>
here is my Adapter
please take look my moveItemDown
and updateItemPosition
method im trying to update item position in updateItemPosition Method but it's not working. i also attached my view below the adapter
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
private RealmResults<ShoppingList> dataList;
private Realm mRealm;
private LayoutInflater mInflater;
public RecyclerAdapter(Context context, RealmResults<ShoppingList> data, Realm reamDatabaseInstence){
this.dataList = data;
this.mInflater = LayoutInflater.from(context);
mRealm = reamDatabaseInstence;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.i("Recycler", "onCreateViewHolder");
View view = mInflater.inflate(R.layout.shopping_list_item, parent,false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
@Override
public int getItemCount() {
return dataList.size();
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Log.i("Recycler", "onBindViewHolder " + position);
ShoppingList currentItem = dataList.get(position);
holder.setData(currentItem, position);
holder.setListener();
}
public void moveItemDown(int position){
if( position == (dataList.size()-1) ) { return; }
int oi = position;
int ni = position+1;
updateItemPosition(oi, ni);
notifyDataSetChanged();
}
public void moveItemUp(int position){
// Need to implement after down sort work
}
private void updateItemPosition(final int pos, final int new_pos){
mRealm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
ShoppingList old_item = realm.where(ShoppingList.class)
.equalTo("position", pos)
.findFirst();
old_item.setPosition(new_pos);
Log.d("UpdateData: ",old_item.getTitle()+" "+old_item.getPosition());
ShoppingList new_item = realm.where(ShoppingList.class)
.equalTo("position", new_pos)
.findFirst();
new_item.setPosition(pos);
Log.d("UpdateData: ",new_item.getTitle()+" "+new_item.getPosition());
}
});
}
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView title;
ImageButton up, down;
ImageView image;
int position;
ShoppingList current;
MyViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.shopping_card_view_title);
image = (ImageView) itemView.findViewById(R.id.shopping_card_view_image);
up = (ImageButton) itemView.findViewById(R.id.shopping_card_view_up_btn);
down = (ImageButton) itemView.findViewById(R.id.shopping_card_view_down_btn);
}
void setData(ShoppingList i, int position) {
title.setText( i.getTitle() );
image.setImageResource(i.getImageId());
this.position = position;
this.current = i;
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.shopping_card_view_up_btn:
moveItemUp(position);
break;
case R.id.shopping_card_view_down_btn:
moveItemDown(position);
break;
}
}
void setListener() {
up.setOnClickListener(MyViewHolder.this);
down.setOnClickListener(MyViewHolder.this);
}
}
}
To get automatic updates, you should use RealmRecyclerViewAdapter
from https://github.com/realm/realm-android-adapters
public class RecyclerAdapter extends RealmRecyclerViewAdapter<ShoppingList, RecyclerAdapter.MyViewHolder> { // <-- !
private Realm mRealm;
private LayoutInflater mInflater;
public RecyclerAdapter(Context context, RealmResults<ShoppingList> data, Realm realm){
super(data, true);
this.mInflater = LayoutInflater.from(context);
mRealm = realm;
}
and replace dataList
with getData()
It's late reply by it would help to you and this is the combination of both answer EpicPandaForce
give a great example to work with RealmRecyclerViewAdapter
and make your Recyclerview automated.
Second Option
this is to use UNIQUE ID FIELD
in order to make changes in list item.
Here is the problem happening in you Code
Basically when you get an item by it's position for instance position=1;
and you updated to position 2 right? notice now you have two item with same position = 2
and now when you try to get first item with position = 2
Realm return the same item that you updated from position 1 to 2 now what happening here you updated dated position back to position=1
;
taman neupane
give you good idea but he is not describe much.
Please TRY THIS
private void updateItemPosition(final int pos, final int new_pos){
final String current_item_id = dataList.get(pos).get_id();
final String new_item_id = dataList.get(new_pos).get_id();
mRealm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
// Try to find the result with unique id replace this .equalTo("Your Unique ID Field name", current_item_id)
ShoppingList old_item = realm.where(ShoppingList.class).equalTo("position", pos).findFirst();
old_item.setPosition(new_pos);
// Also here Try to find the result with unique id replace this .equalTo("Your Unique ID Field name", new_item_id)
ShoppingList new_item = realm.where(ShoppingList.class).equalTo("position", new_pos).findFirst();
new_item.setPosition(pos);
//new you can tell you adapter about the changes in dataset.
notifyItemMoved(pos, new_pos);
notifyItemRangeChanged(pos, dataList.getSize());
}
});
}
and then update your both function with that
public void moveItemDown(int position){
if( position == (dataList.size()-1) ) { return; }
int oi = position;
int ni = position+1;
updateItemPosition(oi, ni);
}
public void moveItemUp(int position){
if( position == 0 ) { return; }
int oi = position;
int ni = position-1;
updateItemPosition(ni, oi);
}
And That's it. If anyone want to modify my explanation i will appreciate because i am not good in english.
Happy Coding.
I think your ShoppingList item has unique id for all. Just make id field primary and use realmInsertorUpdate feature . You don't have to check for any thing else. If the id is available it will update the database and if id is not available it will just insert.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.