Заполнение RecyclerView элементов из JSONObject

391
15 сентября 2017, 19:53

Что делаю: Я получаю все JSONObjects с моего сервера через websockets в MainActivity и кладу их в ArrayList<JSONObject>:

 usersInfo = new ArrayList<>();
    for (int i = contacts.size() - 1; i >= 0; i--) {
        JSONObject obj = new JSONObject();
        try {
            obj.put("id", contacts.get(i));
            socket.emit("info", obj);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        socket.off();
        socket.on("user_info", new Emitter.Listener() {
            @Override
            public void call(Object... args) {
                userInfo = (JSONObject) args[0];
                usersInfo.add(userInfo);
            }
        });
    }
}

К этой активити у меня прицеплен Fragment и чтобы передать ему данные я использую в этой активности этот метод:

public static ArrayList<JSONObject> getUsersInfo(){return usersInfo;}

Далее уже в фрагменте я получаю данные с помощью этого метода:

usersInfo = MainActivity.getUsersInfo();

И начинаю распарсивать его и вставлять все в элементы RecyclerView:

 for (int i = usersInfo.size()-1; i >= 0; i--) {
        try {
            adapter.editItemByID(usersInfo.get(i).getString("id"), usersInfo.get(i).getString("status"), "online");
            adapter.editItemByID(usersInfo.get(i).getString("id"), usersInfo.get(i).getString("nick"), "nick");
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

Просмотрев в Debug режиме, что данные успешно передаются, удостоверяюсь что все данные будут успешно распарсены и вставлены в элементы!. НО! При запуске приложения эти элементы не обновились и остались null, как я их задал по умолчанию. Но при обновлении фрагмента (нажал на BottomNavigationView) Эти данные берут и появляются.

Мне максимально не понятна эта ошибка, так как в DebugMode все данные успешно переправляются между классами.

У меня два вопроса.

  1. Как это исправить и в чем заключается ошибка

  2. Правильно ли передавать данные между классами вот таким способом?

    public static ArrayList getUsersInfo(){return usersInfo;} usersInfo = MainActivity.getUsersInfo();

Дополнение:(без холдера RecyclerView)

public class DialogsFragment extends Fragment {
private RecyclerAdapter adapter;
private Socket socket = AuthActivity.socket;
private JSONObject userInfo;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_dialogs, null);
    RecyclerView rv = view.findViewById(R.id.dialogs);
    LinearLayoutManager llm = new LinearLayoutManager(getActivity().getApplicationContext());
    rv.setLayoutManager(llm);
    ArrayList<String> chats = new ArrayList<>();
    ArrayList<DialogInfo> data = new ArrayList<>();
    ArrayList<String> contacts = MainActivity.getContacts();
    ArrayList<MessagesObject> messages = MainActivity.getMessages();
    String id = MainActivity.getUserAuthID();
    for(int i = contacts.size()-1; i>=0; i-- ){
        data.add(new DialogInfo("null", contacts.get(i), "null", "null", contacts.get(i), "false"));
    }

    adapter = new RecyclerAdapter();
    rv.setAdapter(adapter);
    adapter.addAll(data);
    for (MessagesObject message : messages) {
            if (id.equals(message.getSenderId()) && !search(chats, message.getRecipient())) {
                chats.add(chats.size(), message.getRecipient());
                adapter.editItemByID(message.getRecipient(), "Вы: "+message.getMessage(), "lm");
            } else if (!id.equals(message.getSenderId()) && !search(chats, message.getSenderId())) {
                chats.add(chats.size(), message.getSenderId());
                adapter.editItemByID(message.getSenderId(), message.getMessage(), "lm");
            } else if (id.equals(message.getSenderId())) {
                adapter.editItemByID(message.getRecipient(), "Вы: "+message.getMessage(), "lm");
            } else {
                adapter.editItemByID(message.getSenderId(), message.getMessage(), "lm");
            }
    }
    for (int i = contacts.size() - 1; i >= 0; i--) {
        JSONObject obj = new JSONObject();
        try {
            obj.put("id", contacts.get(i));
            socket.emit("info", obj);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        socket.off();
        socket.on("user_info", new Emitter.Listener() {
            @Override
            public void call(Object... args) {
                userInfo = (JSONObject) args[0];
                try {
                    adapter.editItemByID(userInfo.getString("id"), userInfo.getString("status"), "online");
                    adapter.editItemByID(userInfo.getString("id"), userInfo.getString("nick"), "nick");
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }
    return view;
}

private boolean search(ArrayList<String> chats, String recipient){
    for(int i =0; i<chats.size(); i++){
        if(chats.get(i).equals(recipient)){
            return true;
        }
    }
    return false;
}
private class RecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private List<DialogInfo> items = new ArrayList<>();
    void addAll(List<DialogInfo> fakeItems) {
        int pos = getItemCount();
        this.items.addAll(fakeItems);
        notifyItemRangeInserted(pos, this.items.size());
    }
    void editItemByID(String id, String editValue, String editItem){
        for(int position = 0; position < items.size(); position++){
            if(items.get(position).getId().equals(id)){
                switch (editItem) {
                    case "nick":
                        items.get(position).setName(editValue);
                        break;
                    case "lm":
                        items.get(position).setLastMessage(editValue);
                        break;
                    case "time":
                        items.get(position).setTime(editValue);
                        break;
                    case "photo":
                        items.get(position).setPhoto(editValue);
                        break;
                    case "id":
                        items.get(position).setId(editValue);
                        break;
                    case "online":
                        items.get(position).setOnline(editValue);
                        break;
                }

                notifyItemChanged(position);
            }
        }
    }
Answer 1

в Фрагменте

userInfo=new ArrayList<>();
usersInfo = MainActivity.getUsersInfo();
READ ALSO
Доступ к ListView из другого потока

Доступ к ListView из другого потока

Запускаю метод загрузки данных из БД из потока

383
Вылетает чат на firebase

Вылетает чат на firebase

Хочу освоить firebaseПриложение вылетает сразу же после запуска на телефоне

297
Узнать ID устройства по сокету (по IP)

Узнать ID устройства по сокету (по IP)

Есть сервер, запущенный на компьютере:

243
Выбор программ и языка для создания контента

Выбор программ и языка для создания контента

Здравствуйте, У меня появился вопросЯ попыталась найти в гуугле ответ, но нашла какие-то общие мысли и ничего конкретного

259