Ошибка при передаче данных из одного фрагмента во второй

Рейтинг: 0Ответов: 1Опубликовано: 29.01.2023

Прочитал огромное количество тредов по теме, но ничего не нашел.

У меня есть NewsFragment, в котором представлены заголовки новостей с сайта. По клику на заголовок должен открыться SingleNewsFragment, который показывает фотографию, название, текст и дату публикации новости.

При переходе из NewsFragment в SingleNewsFragment возникают ошибки типа Attempt to read from field 'java.lang.String com.example.***.ui.news.News.imageURL' on a null object reference in method 'android.view.View com.example.***.ui.news.SingleNewsFragment.onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)

При этом сами поля класса не пустые, проверям с помощью логов. Все делжно работать корректно, но почему-то не работает((

NewsFragment:

public class NewsFragment extends Fragment {

    final ArrayList<News> newsArrayList = new ArrayList<>();

    public NewsFragment() {
        // require a empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_news, container, false);
        //NavHostFragment navHostFragment = (NavHostFragment) getChildFragmentManager().findFragmentById(R.id.nav_host_fragment);
        NavController navController = Navigation.findNavController(getActivity(), R.id.nav_host_fragment);
        ListView listView = view.findViewById(R.id.news_header_listview);
        NewsHeadersViewAdapter adapter = new NewsHeadersViewAdapter(getContext(), newsArrayList);
        listView.setAdapter(adapter);
        getNewsHeaders(adapter);
        listView.setOnItemClickListener((parent, view1, position, id) -> {
            SingleNewsFragment singleNewsFragment = SingleNewsFragment.newInstance(newsArrayList.get(position));
            navController.navigate(R.id.singleNewsFragment);
        });


        return view;
    }

    private void getNewsHeaders(NewsHeadersViewAdapter newsNewsHeadersViewAdapter) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Document siteNewspage = Jsoup.connect("https://***/ru/news/").timeout(10 * 1000)
                            .userAgent("Chrome/4.0.249.0 Safari/532.5").get();
                    Elements allNewsHeaders = siteNewspage.select("a[href^=http://***/ru/news/]");
                    for (Element newsHeader : allNewsHeaders) {
                        newsArrayList.add(new News(newsHeader.attr("href").replace("http", "https"),
                                newsHeader.select("div.mb-8 > div.text-gray-900.font-bold.text-xl.mb-2").text(),
                                newsHeader.select("div.mb-8 > p").text(),
                                "https://***" + newsHeader.select("img").attr("src")));
                    }
                } catch (IOException e) {
                    Log.d("HOMEPAGE", e.getMessage());
                }
                Activity activity = getActivity();
                if (isAdded() && activity != null) {
                    activity.runOnUiThread(newsNewsHeadersViewAdapter::notifyDataSetChanged);
                }
            }
        }).start();
    }
}

SingleNewsFragment:

public class SingleNewsFragment extends Fragment {


    private final String newsUrlKey = "newsUrlKey";
    private final String newsTitleKey = "newsTitleKey";
    private final String newsDateKey = "newsDateKey";
    private final String imageUrlKey = "imageUrlKey";
    private News news;

    public SingleNewsFragment() {
    }

    public static SingleNewsFragment newInstance(News singleNews) {
        SingleNewsFragment singleNewsFragment = new SingleNewsFragment();
        // singleNewsFragment.news = new News(singleNews.newsURL, singleNews.newsTitle, singleNews.newsDate, singleNews.imageURL);
        Bundle args = new Bundle();
        args.putString(singleNewsFragment.newsUrlKey, singleNews.newsURL);
        Log.d("LOG", singleNews.imageURL);
        args.putString(singleNewsFragment.newsTitleKey, singleNews.newsTitle);
        args.putString(singleNewsFragment.newsDateKey, singleNews.newsDate);
        args.putString(singleNewsFragment.imageUrlKey, singleNews.imageURL);
        singleNewsFragment.setArguments(args);
        return singleNewsFragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_single_news, container, false);
        news = new News(getArguments().getString(newsUrlKey), getArguments().getString(newsTitleKey),
                getArguments().getString(newsDateKey), getArguments().getString(imageUrlKey));
        ImageView newsImage = view.findViewById(R.id.news_image);
        TextView newsDate = view.findViewById(R.id.news_date);
        TextView newsContentTextView = view.findViewById(R.id.news_content);

        Picasso.get().load(news.imageURL)
                .resize(R.dimen.news_image_width, R.dimen.news_image_height)
                .onlyScaleDown()
                .into(newsImage);

        getArticleContent(newsContentTextView);

        newsDate.setText(news.newsDate);

        return view;
    }

    private void getArticleContent(TextView textView) {
        new Thread(() -> {
            final StringBuilder stringBuilder = new StringBuilder();
            try {
                Document newspage = Jsoup.connect(news.newsURL)
                        .userAgent("Chrome/4.0.249.0 Safari/532.5")
                        .referrer("http://www.google.com").get();
                Elements article = newspage.select("div.container.m-auto.px-4 > p");
                for (Element part : article) {
                    stringBuilder.append(part.toString()
                            .replace("<br>", "\n        ")
                            .replace("</b>", "\n        ")
                            .replace("<p>", "")
                            .replace("<b>", "")
                            .replace("</p>", ""));
                }
            } catch (IOException e) {
                e.printStackTrace();
                stringBuilder.append(e.getMessage());
                stringBuilder.append(news.newsURL);
            }
            Activity activity = getActivity();
            if (isAdded() && activity != null) {
                activity.runOnUiThread(() -> textView.setText(stringBuilder.toString()));
            }
        }).start();
    }
}

News:

class News {
    public String newsURL;
    public String newsTitle;
    public String newsDate;
    public String imageURL;

    public News(String newsURL, String newsTitle, String newsDate, String imageURL) {
        this.newsURL = newsURL;
        this.newsTitle = newsTitle;
        this.newsDate = newsDate;
        this.imageURL = imageURL;
    }
}

P.s. Если по умолчанию задать значения полю news то все работает просто прекрасно.

P.p.s. Помогите пожалуйста, мучаюсь второй день... Т_т

Ответы

▲ 1Принят

Вы в onClickListener создаёте SingleNewsFragment и нигде не используете. А с navigation component и не получится, вместо этого передавайте Bundle в navigation.

public class SingleNewsFragmentArgs {
    
    private static final String newsUrlKey = "newsUrlKey";
    private static final String newsTitleKey = "newsTitleKey";
    private static final String newsDateKey = "newsDateKey";
    private static final String imageUrlKey = "imageUrlKey";

    public static Bundle toBundle(News singleNews) {
        Bundle args = new Bundle();
        args.putString(newsUrlKey, singleNews.newsURL);
        args.putString(newsTitleKey, singleNews.newsTitle);
        args.putString(newsDateKey, singleNews.newsDate);
        args.putString(imageUrlKey, singleNews.imageURL);
        return args;
    }

    public static News fromBundle(Bundle bundle) {
        return new News(
                getArguments().getString(newsUrlKey), 
                getArguments().getString(newsTitleKey),
                getArguments().getString(newsDateKey), 
                getArguments().getString(imageUrlKey)
            );

    }
}
public class NewsFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //...
        listView.setOnItemClickListener((parent, view1, position, id) -> {
            Bundle args = SingleNewsFragmentArgs.toBundle(newsArrayList.get(position));
            navController.navigate(R.id.singleNewsFragment, args);
        });
        //...
    }
}
public class SingleNewsFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //...
        news = SingleNewsFragmentArgs.fromBundle(getArguments());
        //...
    }