2015-10-01 3 views
1

Пожалуйста, помогите мне, я застрял в решении этой проблемы RecyclerView. Я новичок в RecyclerView и создал RecyclerView, у которого есть простое приложение для управления задачами.RecyclerView вставка/удаление анимации удаляет нежелательный объект

Проблемы:

  • Когда я удалить любой элемент и вызвать notifyItemRemoved() он иногда удаляет нежелательный элемент и сбои приложения. (возможно, из-за того, что индексы мешают)
  • Даже когда я обновляюсь снова, звоня по телефону setAdapter, происходят нежелательные события (см. код #here в коде.). Цвет начинается с нужных элементов при запуске, но после прокрутки он применяется ко всем прокручиваемым.

Вот мой адаптер:

public class RVadapter extends RecyclerView.Adapter<RVadapter.mHolder> { 

    public List<Task> mTask; 
    private SQLhelper sql; 
    private Context mContext; 
    public RVadapter(Context context) 
    { 
     super(); 
     mContext=context; 
     sql=new SQLhelper(mContext,null); 
     PlannerAI ai=new PlannerAI(); 
     mTask=ai.generateTaskList(sql.getTasks()); 
    } 

    public interface listener { 
     public void refresh(); 
    } 

    @Override 
    public void onBindViewHolder(mHolder holder,final int i) { 
     try { 
      final Task t = mTask.get(i); 
      // #here 
      if(t.getId().equals("Enjoy")) 
      { 
       holder.vv.setBackgroundColor(mContext.getResources().getColor(android.R.color.some_color)); 
      } 
      holder.name.setText(t.getName()); 
      holder.extras.setText(t.getExtras()); 
      holder.id.setText(t.getId()); 
      holder.subject.setText(t.getSubject()); 
      holder.type.setText(t.getType()); 
      holder.noq.setText(t.getNo()+" questions"); 
      holder.del.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        if(t.id!=null) { 
         sql.deleteTask(t.id); 
         mTask.remove(i); 
         notifyItemRemoved(i); 
         if (mContext instanceof listener) { 
          ((listener) mContext).refresh(); 
         } 
        } 
       } 
      }); 
     }catch(Exception e){ 
      Log.d("TAG_LOG_EM",e.toString()); 
     } 
    } 


    @Override 
    public mHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     mHolder view; 
     view = null; 
     try{ 
      View v=LayoutInflater.from(parent.getContext()).inflate(R.layout.planner_item,null); 
      view=new mHolder(v); 

     }catch(Exception e){ 
      Log.d("TAG_LOG_EM",e.toString()); 
     } 
     return view; 
    } 

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

    class mHolder extends RecyclerView.ViewHolder{ 
     public TextView name; 
     public TextView extras; 
     public TextView id; 
     public TextView subject; 
     public TextView type; 
     public TextView noq; 
     public View vv; 
     public ImageView del; 

     public mHolder(View view){ 
      super(view); 
      vv=view; 
      try { 
       name = (TextView) view.findViewById(R.id.planner_name); 
       extras = (TextView) view.findViewById(R.id.planner_extras); 
       id = (TextView) view.findViewById(R.id.planner_id); 
       del = (ImageView) view.findViewById(R.id.t_delete); 
       subject = (TextView) view.findViewById(R.id.planner_subject); 
       type = (TextView) view.findViewById(R.id.planner_type); 
       noq = (TextView) view.findViewById(R.id.planner_no); 
      }catch(Exception e){ 
       Log.d("TAG_LOG_EM",e.toString()); 
      } 
     } 

    } 
} 

Я не нужнее SQL и MainActivity классы (пожалуйста, прокомментируйте, если это необходимо). Пожалуйста, помогите и сообщите любые рекомендуемые изменения кода. Спасибо!

Edit: Функция обновления является:

public void refresh(){ 

     radapter = new RVadapter(this); 
     rv.setAdapter(radapter); 
    } 
+0

Вам нужна функция обновления? Что произойдет, если вы удалите его? Он создает новый адаптер, который кажется ненужной работой. Проверьте этот ответ здесь http://stackoverflow.com/questions/26076965/android-recyclerview-addition-removal-of-items и попробуйте вызвать функцию notifyItemRangeChanged. –

ответ

12

Просто поместите эти функции внутри вашей RVadapter

public void onItemDismiss(int position) { 
    if(position!=-1 && position<mTask.size()) 
    { 
     mTask.remove(position); 
     notifyItemRemoved(position); 
     notifyItemRangeChanged(position, getItemCount()); 
    } 
} 

он обеспечивает подсчет общего количества элементов, в настоящее время в адаптере

@Override 
public int getItemCount() { 
    return (null != mTask ? mTask.size() : 0); 
} 

и в вашем OnClick(), просто добавьте:

holder.del.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
        onItemDismiss(i) 
      } 
     }); 

Edit 1: Объяснение

mTask.remove(position); - удаляет элемент определенной позиции из списка.

notifyItemRemoved(position); - уведомляет RecyclerView Adapter, что данные в адаптере были удалены в определенном положении.

notifyItemRangeChanged(position, getItemCount()); - уведомляет RecyclerView Adapter о том, что позиции элемента в адаптере были изменены с позиции (индекс удаленных элементов до конца списка), пожалуйста, обновите его.

if(position!=-1 && position<mTask.size()) - это условие проверяет, что позиция элемента не равна -1, а позиция элемента должна быть меньше, чем размер всех элементов в списке. следовательно, не вызывая нежелательного сбоя из-за индексов элементов.

+0

Пожалуйста, скажите мне мою ошибку. Также я не могу удалить добавленный элемент. – Mrigank

+0

@ Рихард вы пробовали мой код? –

+0

Да, что сработало – Mrigank

Смежные вопросы