RecyclerView не может получить правильную позицию для выполнения задачи, когда пользователь выбирает опцию из контекстного меню - PullRequest
0 голосов
/ 14 мая 2018

Мое приложение не может получить правильную позицию для выполнения задачи, которую пользователь выбирает из 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. , если удалить, то время пищи становится«удалить»
  6. если изменить, то u_time пищи становится «изменить»

шаг 1-4 работает нормально.но после этого приложение не может получить позицию для правильного выполнения задачи.

Например, если пользователь выберет «удалить» для третьего элемента, но первый элемент будет изменен.После этого пользователь выбирает «изменить» для четвертого элемента, второй элемент изменяется.Есть ли проблема с моим кодом?

1 Ответ

0 голосов
/ 14 мая 2018

Замените ваш код следующим образом:

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");
    }
}
}
...