RecyclerView при переходе назад (компонент навигации) - PullRequest
0 голосов
/ 31 марта 2020

Существует фрагмент RuleListFragment с RecyclerView. Второй фрагмент, RuleFragment, содержит подробную информацию. При возвращении RecyclerView исчезает. В чем может быть проблема? В логах написано, что адаптер не назначен, но я не понимаю, где и почему.

public class RuleListFragment extends Fragment {
    private RecyclerView recyclerView;
    private RuleAdapter ruleAdapter;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_recycler, container, false);
        setRecyclerView(view);
        return view;
    }

    public void setRecyclerView(View view) {
        if (recyclerView == null) {
            Log.d(TAG, "new!");
            recyclerView = view.findViewById(R.id.recyclerView);
            recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        } else {
            Log.d(TAG, "old!");
        }

        if (ruleAdapter == null) {
            List<Rule> rules = Labs.get(getActivity()).getRules();
            ruleAdapter = new RuleAdapter(rules);
            recyclerView.setAdapter(ruleAdapter);
        } else {
            updateRecyclerView();
        }
    }

    public void updateRecyclerView() {
        Log.d(TAG, ruleAdapter == null ? "ruleAdapter = null" : "ruleAdapter != null");
        Log.d(TAG, recyclerView == null ? "recyclerView = null" : "recyclerView != null");
        Log.d(TAG, recyclerView.getAdapter() == null ? "recyclerView.getAdapter() = null" : "recyclerView.getAdapter() != null");
        Log.d(TAG, recyclerView.getLayoutManager() == null ? "recyclerView.getLayoutManager() = null" : "recyclerView.getLayoutManager() != null");
        List<Rule> rules = Labs.get(getActivity()).getRules();
        ruleAdapter.setRules(rules);
        ruleAdapter.notifyDataSetChanged();
    }

    private class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        Rule rule;
        ImageView icon;
        TextView title;

        private ViewHolder(View itemView) {
            super(itemView);
            itemView.setOnClickListener(this);

            icon = itemView.findViewById(R.id.icon);
            title = itemView.findViewById(R.id.title);
        }

        private void bind (Rule rule) {
            this.rule = rule;

            int iconId = getResources().getIdentifier(rule.getIcon(), "drawable", getActivity().getPackageName());
            icon.setImageResource(iconId);
            title.setText(rule.getTitle());
        }

        @Override
        public void onClick(View view) {
            Bundle args = new Bundle();
            args.putSerializable("ruleId", rule.getId());
        Navigation.findNavController(view).navigate(getLayout(rule.getType()), args);
        }
    }

    private int getLayout(int i) {
        switch (i) {
            case 1:
                return R.id.generalFragment;
            case 2:
                return R.id.leaderFragment;
            default:
                return R.id.ruleFragment;
        }
    }

    private class RuleAdapter extends RecyclerView.Adapter<ViewHolder> {
        private List<Rule> rules;
        private RuleAdapter (List<Rule> rules) {
            this.rules = rules;
        }

        @NonNull
        @Override
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
            View view = layoutInflater.inflate(R.layout.item_recycler_rule, parent, false);
            return new ViewHolder(view);
        }

        @Override
        public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
            Rule rule = rules.get(position);
            holder.bind(rule);
        }

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

        public void setRules(List<Rule> rules) {
            this.rules = rules;
        }
    }
}
public class RuleFragment extends Fragment {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getArgument();

        setHasOptionsMenu(true);
    }

    public void getArgument() {
        int ruleId = getArguments().getInt("ruleId");
        rule = Labs.get(getActivity()).getRule(ruleId);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_rule, container, false);

        ///

        return view;
    }



    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.menu_rule, menu);

        ///

    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.elect) {
            ///
        }
        return super.onOptionsItemSelected(item);
    }
}

Вход в систему при первом запуске

2020-03-31 02:25:50.190 25212-25212/? D/Constraints: new!

Вход в систему

020-03-31 02:25:59.023 25212-25212/ D/Constraints: old!
2020-03-31 02:25:59.023 25212-25212/ D/Constraints: ruleAdapter != null
2020-03-31 02:25:59.023 25212-25212/ D/Constraints: recyclerView != null
2020-03-31 02:25:59.023 25212-25212/ D/Constraints: recyclerView.getAdapter() != null
2020-03-31 02:25:59.023 25212-25212/ D/Constraints: recyclerView.getLayoutManager() != null
2020-03-31 02:25:59.065 25212-25212/ E/RecyclerView: No adapter attached; skipping layout

Ответы [ 2 ]

0 голосов
/ 31 марта 2020

Я не знаю, насколько верным является это решение, но я переделал код следующим образом. Адаптер теперь назначается RecyclerView независимо от того, является ли адаптер == нулевым или адаптером! = Нуль. Также удалены onResume и notifyDataSetChanged (). Я буду использовать последний, только когда вам нужно изменить список в RuleListFragment.

@Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_recycler, container, false);
        recyclerView = view.findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        setRecyclerView();
        return view;
    }

    public void setRecyclerView() {
        if (ruleAdapter == null) {
            ruleAdapter = new RuleAdapter(Labs.get(getContext()).getRules());
        } else {
            ruleAdapter.setRules(Labs.get(getActivity()).getRules());
        }
        recyclerView.setAdapter(ruleAdapter);
    }
0 голосов
/ 31 марта 2020

Если я правильно помню, я откуда-то читал, что кажется, что вы не можете установить RecyclerView в onCreateView, иначе вы можете закончить с проблемой, подобной вашей.

Можете ли вы попробовать переместить setRecyclerView(view) в onViewCreated?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...