当上下文菜单中的用户 select 选项时,RecyclerView 无法获得正确的位置来执行任务

RecyclerView cannot get corrrect position to perform the task when user select option from contextmenu

我的应用程序无法获得正确的位置来执行用户从上下文菜单中选择的任务。

MainActivity.java

public class Main3Activity extends AppCompatActivity {

private RecyclerView recyclerView;
private List<foodmodel> result;
private foodadapter adapter;

private FirebaseDatabase database;
private DatabaseReference ref;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main3);

    database = FirebaseDatabase.getInstance();
    ref = database.getReference("Food");

    result = new ArrayList<>();

    recyclerView = (RecyclerView)findViewById(R.id.food_list);
    recyclerView.setHasFixedSize(true);
    LinearLayoutManager lim = new LinearLayoutManager(this);
    lim.setOrientation(LinearLayoutManager.VERTICAL);

    recyclerView.setLayoutManager(lim);


    adapter = new foodadapter(result);
    recyclerView.setAdapter(adapter);

    updateList();
}

@Override
public boolean onContextItemSelected(MenuItem item) {

    switch (item.getItemId())
    {
        case 0:
            removeFood(item.getItemId());
            break;

        case 1:
            changeFood(item.getItemId());
            break;

    }
    return super.onContextItemSelected(item);
}


private void updateList()
{
    ref.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            result.add(dataSnapshot.getValue(foodmodel.class));
            adapter.notifyDataSetChanged();
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {
            foodmodel food = dataSnapshot.getValue(foodmodel.class);

            int index = getItemIndex(food);

            result.set(index,food);
            adapter.notifyItemChanged(index);
        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {
            foodmodel food = dataSnapshot.getValue(foodmodel.class);

            int index = getItemIndex(food);

            result.remove(index);
            adapter.notifyItemRemoved(index);
        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

private int getItemIndex(foodmodel food){
    int index = -1;
    for(int i = 0; i < result.size();i++)
    {
        if (result.get(i).key.equals(food.key))
        {
            index = i;
            break;
        }

    }
    return index;
}


private void removeFood(int pos){
    foodmodel food = result.get(pos);
    String key = food.getKey();
    food.u_time="remove";

    Map<String,Object> foodValue = food.toMap();
    Map<String,Object> newFood = new HashMap<>();

    newFood.put(key,foodValue);

    ref.updateChildren(newFood);
}

private void changeFood(int pos){
    foodmodel food = result.get(pos);
    food.u_time="change";

    Map<String,Object> foodValue = food.toMap();
    Map<String,Object> newFood = new HashMap<>();

    newFood.put(food.key,foodValue);

    ref.updateChildren(newFood);
}

}

foodadapter.java

public class foodadapter extends RecyclerView.Adapter<foodadapter.foodviewholder> {

private List<foodmodel>list;
public foodadapter(List<foodmodel> list) {
    this.list = list;
}

@Override
public foodviewholder onCreateViewHolder(ViewGroup parent, int viewType) {

    return new foodviewholder(LayoutInflater.from(parent.getContext()).inflate(R.layout.view_item,parent,false));
}

@Override
public void onBindViewHolder(foodviewholder holder, int position) {
    foodmodel food = list.get(position);

    holder.txtname.setText(food.u_food);
    holder.txtdate.setText(food.u_date);
    holder.txttime.setText(food.u_time);

}

@Override
public int getItemCount() {
    return list.size();
}

public class foodviewholder extends RecyclerView.ViewHolder implements OnCreateContextMenuListener {

    TextView txtname,txtdate,txttime;
    Button btn;

    public foodviewholder(View itemView) {
        super(itemView);
        txtname = (TextView)itemView.findViewById(R.id.text_food);
        txtdate = (TextView)itemView.findViewById(R.id.text_date);
        txttime = (TextView)itemView.findViewById(R.id.text_time);
        btn = (Button)itemView.findViewById(R.id.btntest);
        itemView.setOnCreateContextMenuListener(this);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        menu.add(0, 0, 0, "Delete");
        menu.add(0, 1, 0, "Change");
    }
}
}

foomodel.java

public class foodmodel {

String u_food,u_date,u_time,key;

public foodmodel(){}

public foodmodel(String  u_food,String u_date,String u_time, String key) {
    this.u_food = u_food;
    this.u_date = u_date;
    this.u_time = u_time;
    this.key = key;
}

public Map<String,Object> toMap(){
    HashMap<String,Object> result = new HashMap<>();
    result.put("u_food",u_food);
    result.put("u_time",u_time);
    result.put("u_date",u_date);
    result.put("key",key);

    return  result;
}

public String getU_food() {
    return u_food;
}

public void setU_food(String u_food) {
    this.u_food = u_food;
}

public String getU_date() {
    return u_date;
}

public void setU_date(String u_date) {
    this.u_date = u_date;
}

public String getU_time() {
    return u_time;
}

public void setU_time(String u_time) {
    this.u_time = u_time;
}

public String getKey() {
    return key;
}

public void setKey(String key) {
    this.key = key;
}
}

应用程序的流程应该像

  1. 显示从 Firebases 检索的回收视图
  2. 用户从列表中选择项目
  3. 上下文菜单弹出
  4. 用户选择删除或更改
  5. 如果删除,则食物的u_time变为"remove"
  6. 如果改变,那么食物的u_time就变成了"change"

步骤 1-4 工作正常。但之后应用程序无法正确执行任务。

例如,如果用户在第三项上选择"delete",但第一项将被更改。之后,用户在第四项上选择 "change",第二项发生变化。我的代码有问题吗?

将您的代码替换为:

MainActivity.java

public class Main3Activity extends AppCompatActivity {

private RecyclerView recyclerView;
private List<foodmodel> result;
private foodadapter adapter;

private FirebaseDatabase database;
private DatabaseReference ref;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main3);

    database = FirebaseDatabase.getInstance();
    ref = database.getReference("Food");

    result = new ArrayList<>();

    recyclerView = (RecyclerView)findViewById(R.id.food_list);
    recyclerView.setHasFixedSize(true);
    LinearLayoutManager lim = new LinearLayoutManager(this);
    lim.setOrientation(LinearLayoutManager.VERTICAL);

    recyclerView.setLayoutManager(lim);


    adapter = new foodadapter(result);
    recyclerView.setAdapter(adapter);

    updateList();
}

@Override
public boolean onContextItemSelected(MenuItem item) {

    switch (item.getItemId())
    {
        case 0:
            if(adapter.curPos>-1){
             removeFood(adapter.curPos);
            }
            break;

        case 1:
            if(adapter.curPos>-1){
             changeFood(adapter.curPos);
            }
            break;

    }
    return super.onContextItemSelected(item);
}


private void updateList()
{
    ref.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            result.add(dataSnapshot.getValue(foodmodel.class));
            adapter.notifyDataSetChanged();
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {
            foodmodel food = dataSnapshot.getValue(foodmodel.class);

            int index = getItemIndex(food);

            result.set(index,food);
            adapter.notifyItemChanged(index);
        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {
            foodmodel food = dataSnapshot.getValue(foodmodel.class);

            int index = getItemIndex(food);

            result.remove(index);
            adapter.notifyItemRemoved(index);
        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

private int getItemIndex(foodmodel food){
    int index = -1;
    for(int i = 0; i < result.size();i++)
    {
        if (result.get(i).key.equals(food.key))
        {
            index = i;
            break;
        }

    }
    return index;
}


private void removeFood(int pos){
    foodmodel food = result.get(pos);
    String key = food.getKey();
    food.u_time="remove";

    Map<String,Object> foodValue = food.toMap();
    Map<String,Object> newFood = new HashMap<>();

    newFood.put(key,foodValue);

    ref.updateChildren(newFood);
}

private void changeFood(int pos){
    foodmodel food = result.get(pos);
    food.u_time="change";

    Map<String,Object> foodValue = food.toMap();
    Map<String,Object> newFood = new HashMap<>();

    newFood.put(food.key,foodValue);

    ref.updateChildren(newFood);
}

}

foodadapter.java

public class foodadapter extends RecyclerView.Adapter<foodadapter.foodviewholder> {

private List<foodmodel>list;
public int curPos=-1;
public foodadapter(List<foodmodel> list) {
    this.list = list;
}

@Override
public foodviewholder onCreateViewHolder(ViewGroup parent, int viewType) {

    return new foodviewholder(LayoutInflater.from(parent.getContext()).inflate(R.layout.view_item,parent,false));
}

@Override
public void onBindViewHolder(foodviewholder holder, int position) {
    foodmodel food = list.get(position);

    holder.txtname.setText(food.u_food);
    holder.txtdate.setText(food.u_date);
    holder.txttime.setText(food.u_time);

}

@Override
public int getItemCount() {
    return list.size();
}

public class foodviewholder extends RecyclerView.ViewHolder implements OnCreateContextMenuListener {

    TextView txtname,txtdate,txttime;
    Button btn;

    public foodviewholder(View itemView) {
        super(itemView);
        txtname = (TextView)itemView.findViewById(R.id.text_food);
        txtdate = (TextView)itemView.findViewById(R.id.text_date);
        txttime = (TextView)itemView.findViewById(R.id.text_time);
        btn = (Button)itemView.findViewById(R.id.btntest);
        itemView.setOnCreateContextMenuListener(this);
        itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                         curPos=getAdapterPosition();
                    }});
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        menu.add(0, 0, 0, "Delete");
        menu.add(0, 1, 0, "Change");
    }
}
}