Как обновить один item после изменения в RecyclerView?

230
26 декабря 2017, 16:53

RecyclerView отображает список CardView с текстом, их можно добавлять и удалять. Проблема вот в чем, я пытаюсь реализовать изменение itema, то есть, на card view по мимо текста есть еще и кнопка change, которая вызывает FragmentDialog в котором есть editText для ввода строчки замены. Я вставляю измененный объект Item в мой DataList и потом в onBindViewHolder в onClick я вызываю notifyItemChanged(position); и item на экране не обновляется, а в DataList все нормально, новый объект на той же позиции. Как тогда обновить item на экране? После перезапуска приложения, естественно item обновленный.

UPD:

public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
List<ListItem> list = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    loadData();
    recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    recyclerView.setHasFixedSize(true);
    layoutManager = new LinearLayoutManager(this);
    recyclerView.setLayoutManager(layoutManager);
    adapter = new MyAdapter(list, this, getFragmentManager());
    recyclerView.setAdapter(adapter);
}
public void loadData() {
    list.add(new ListItem("Item1"));
    list.add(new ListItem("Item2"));
    list.add(new ListItem("Item3"));
    list.add(new ListItem("Item4"));
    list.add(new ListItem("Item5"));
    list.add(new ListItem("Item6"));
    list.add(new ListItem("Item7"));
}

}

В адаптере

 @Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    holder.title.setText(list.get(position).getTitle());
    holder.changeButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            new MyDialog(list, position).show(fragmentManager, "myDialog");
            notifyItemChanged(position);

        }
    });

}

В DialogFragment

 @SuppressLint("ValidFragment")
public MyDialog(List<ListItem> list, int position) {
    this.list = list;
    this.position = position;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.my_dialog, null);
    name = view.findViewById(R.id.editText);
    buttonOk = view.findViewById(R.id.buttonOk);
    buttonCancel = view.findViewById(R.id.buttonCancel);

    buttonOk.setOnClickListener(this);
    buttonCancel.setOnClickListener(this);
    return view;
}
@Override
public void onClick(View view) {
    if (view.getId() == R.id.buttonOk) {
        String nameText = name.getText().toString();
        ListItem item = list.get(position);
        item.setTitle(nameText);
        list.set(position, item);
        dismiss();
    } else if (view.getId() == R.id.buttonCancel) {
        dismiss();
    }
}
Answer 1

В общем мысли следующие. Нужно передать обновленный list из MyDialog в MainActivity

  1. в MyDialogобъявим переменную и создадим интерфейс

    Communicator communicator;
    //.... 
    public interface Communicator {
         public void messageList(List<ListItem> list); 
            }
  2. В public class MainActivity extends AppCompatActivity допишем implements MyDialog.Communicator
  3. Вынесем вызов адаптера в отдельный метод

    private void updateRecyclerView(List<ListItem> list){
        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        recyclerView.setHasFixedSize(true);
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        adapter = new MyAdapter(list, this, getFragmentManager());
        recyclerView.setAdapter(adapter);
    }
  4. В public class MainActivity реализуем метод интерфейса MyDialog.Communicator

    @Override
    public void messageList(List<ListItem> listFromDialog) {
         this.list = listFromDialog;
         updateRecyclerView(list);
    }
  5. в MyDialog в onClick вызовем communicator.messageList(list)

    @Override
    public void onClick(View view) {
    if (view.getId() == R.id.buttonOk) {
       String nameText = name.getText().toString();
       ListItem item = list.get(position);
       item.setTitle(nameText);
       list.set(position, item);
       dismiss();
       communicator.messageList(list);//<--------------
    
    } else if (view.getId() == R.id.buttonCancel) {
       dismiss();
    } 
  6. В MainActivity в onCreate проверяем

    if (list != null) {
        updateRecyclerView(list);
    } else {
        updateRecyclerView(loadData());
    }

Наверняка сходу что-то не учел, будем додумывать если что

update

В точности повторил, кидает NullPointer в этой строке communicator.messageList(list); java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.user.myapplication.MyDialog$Communicator.message‌​List(java.util.List)‌​' on a null object reference at com.example.user.myapplication.MyDialog.onClick(MyDialog.jav‌​a:66)

  1. Возможно контекста не хватает. Можно попробовать добавить в MyDialog

     @Override
       public void onAttach(Activity activity) {
        super.onAttach(activity);
           if (activity instanceof Communicator) {
            communicator = (Communicator) getActivity();
          } else {
            throw new ClassCastException(activity.toString()
                    +  must implemenet MyDialog.communicator”);
        }
    }
READ ALSO
Подключение к БД Oracle

Подключение к БД Oracle

Есть БД на удаленном сервереПытаюсь подключиться так

301
JavaFX, Рисование на Canvas

JavaFX, Рисование на Canvas

Как рисовать на одном Canvas из разных классов? Проблема в том, что при обращении к canvas из разных классов возвращаются разные ссылки

263
Бот для чат приложения android [требует правки]

Бот для чат приложения android [требует правки]

ЗдравствуйтеНадо нужно написать бота для чат-приложения

198