Bład w kodzie przy wyświetlaniu Fragmentów

0

Witajcie,

próbuje dynamicznie podmieniać Fragmenty, ale gdy odpalam aplikacje to się zaraz rozwala. Nie wyświetla się żaden błąd w kodzie ale jednak coś musi być nie tak. Do momentu kiedy nie zacząłem grzebać we fragmentList.add(new Fragment1(null, R.drawable.image_file, null, true)); wszystko grało.

MainActivity

fragmentList = new ArrayList<>();
        fragmentList.add(new Fragment1(getResources().getString(R.string.text_page_1), R.drawable.swans, new String[]{getResources().getString(R.string.answer1), getResources().getString(R.string.answer2),getResources().getString(R.string.answer3)},false));
        fragmentList.add(new Fragment1(null, R.drawable.image_file, null, true));
        fragmentList.add(new Fragment1(getResources().getString(R.string.text_page_2), R.drawable.nature, new String[]{getResources().getString(R.string.answer4), getResources().getString(R.string.answer5),getResources().getString(R.string.answer6)},false));```

Fragment1

public class Fragment1 extends Fragment {

    String stringValue;
    int imagesResId;
    TextView text;
    String[] rbData;
    RadioGroup radioButtons;
    boolean mapImage;
    ImageView maps;
     View answer;

    public Fragment1(String str, int imageView , String[] rb, boolean arg) {

        this.stringValue = str;
        this.imagesResId = imageView;
        this.rbData = rb;
        this.mapImage = arg;

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        Log.i("x","onCreateViewFragment");

        View view = inflater.inflate(R.layout.fragment_1, container, false);
        text =  view.findViewById(R.id.textView);
        ImageView imageResId = view.findViewById(image);
        maps = view.findViewById(map_images);
        answer = view.findViewById((R.id.radioGroup));

        text.setText(stringValue);
        imageResId.setImageResource(imagesResId);
        maps.setImageResource(imagesResId);

        if(mapImage){
            view = inflater.inflate(R.layout.maps, container, false);
            maps = view.findViewById(R.id.map_images);
            maps.setImageResource(imagesResId);

        }else{
            view = inflater.inflate(R.layout.fragment_1, container, false);
            text =  view.findViewById(R.id.textView);
            radioButtons = view.findViewById(R.id.radioGroup);
            text.setText(stringValue);
            imageResId.setImageResource(imagesResId);

            //checkboxes, textviews, imageviews, etc
        }

        if (answer != null) {
            for (int i = 0; i < radioButtons.getChildCount(); i++) {
                ((RadioButton) radioButtons.getChildAt(i)).setText(rbData[i]);
            }
        }

        return view;
    }

Uaktualnienie postu, log:

10-30 17:22:53.281 14867-14867/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                   java.lang.NullPointerException
                                                       at make.appaplication.Fragment1.onCreateView(Fragment1.java:64)

Chodzi o tą linię kodu w metodzie onCreateView Fragment

maps.setImageResource(imagesResId);
0

Co masz w logcat?

0

jaki masz blad w logcat

fragmentList.add(new Fragment1(null, R.drawable.image_file, null, true));
    public Fragment1(String str, int imageView , String[] rb, boolean arg) {
        this.stringValue = str;
        text.setText(stringValue);

wpychasz do textView nulla wiec tutaj chyba jest 1 blad,

zamiast przekazywac null'e w konstruktorze dodaj 2 konstruktor z mniejsza iloscia parametrow

0

A czy ten drugi layout xml z ifa czyli view = inflater.inflate(R.layout.maps, container, false); nie musi być też zaimplementowany w onCreateView ?

Spróbowałem inaczej maps.setImageResource(mapImage); ale teraz metoda jest int a parametr boolean. Jak to pogodzić? :)

0
10-30 17:22:53.281 14867-14867/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                   java.lang.NullPointerException
                                                       at make.appaplication.Fragment1.onCreateView(Fragment1.java:64)

wkleiłeś za mało informacji. wiemy że błąd jest w onCreateView i 64 linii kodu a w Twoim poście nie ma numerów linii kodu :) wklej trochę więcej tego stacktraca

A czy ten drugi layout xml z ifa czyli view = inflater.inflate(R.layout.maps, container, false); nie musi być też zaimplementowany w onCreateView ?
masz dobrze, na podstawie warunku If określasz co ma być generowane.

Spróbowałem inaczej maps.setImageResource(mapImage); ale teraz metoda jest int a parametr boolean. Jak to pogodzić? :)
bo mapImage to taka flaga do określenia który layout chcesz mieć, a setImageResource pobiera resourceId czyli u Ciebie imageView

ogólnie troche nazywnictwo kuleje ale wszystko z czasem. Wklej aktualny kod i powiedź z czym masz dalej problem

0

Mam wciąż problem z tą linią kodu (setImageResurce to typ int, mapImage to typ boolean). Ta linia kodu ma ustawiać images z drawable i wyświetlać je co drugi Fragment ( do czego służy metoda if w dalszej części poniższego kodu). Do wyświetlania images w pozostałych Fragmentach mam imageResId.setImageResource(imagesResId); co umieszczone jest potem w else.

maps.setImageResource(mapImage);
public class Fragment1 extends Fragment {



        String stringValue;
        int imagesResId;
        TextView text;
        String[] rbData;
        RadioGroup radioButtons;
        boolean mapImage;
        View answer;




        public Fragment1(String str, int imageView , String[] rb, boolean arg) {

            this.stringValue = str;
            this.imagesResId = imageView;
            this.rbData = rb;
            this.mapImage = arg;

        }


        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            Log.i("x","onCreateViewFragment");

            View view = inflater.inflate(R.layout.fragment_1, container, false);
            text =  view.findViewById(R.id.textView);
            ImageView imageResId = view.findViewById(image);
            ImageView maps = view.findViewById(map_images);
            answer = view.findViewById((R.id.radioGroup));



            text.setText(stringValue);
            imageResId.setImageResource(imagesResId);
            maps.setImageResource(mapImage);





            if(mapImage){
                view = inflater.inflate(R.layout.maps, container, false);
                maps = view.findViewById(R.id.map_images);
                maps.setImageResource(mapImage);

            }else{
                view = inflater.inflate(R.layout.fragment_1, container, false);
                text =  view.findViewById(R.id.textView);
                radioButtons = view.findViewById(R.id.radioGroup);
                text.setText(stringValue);
                imageResId.setImageResource(imagesResId);

               }




            if (answer != null) {
                for (int i = 0; i < radioButtons.getChildCount(); i++) {
                    ((RadioButton) radioButtons.getChildAt(i)).setText(rbData[i]);
                }
            }


            return view;
        }
0

ogólnie to do developmentu używaj AndroidStudio
znasz na tyle angielski żeby sobie swobodnie czytać dokumentację po angielsku?

imagesResId to jest typ prosty int, nie posiada żadnych metod, możesz tam przypisać jakiś int np. liczbę 100 i nic więcej
android generuje sobie taką klasę o nazwie R dla różnych danych i m.in. dla Resurce Drowable, R.drawable.jakaś_nazwa

imageResId.setImageResource(imagesResId); nie ma prawa działać bo chcesz wywołać metodę na typie prostym int imageResId a ten takich nie posiada jak pisałem wcześniej.

tak powinno to wyglądać:

            if (mapImage){
                view = inflater.inflate(R.layout.maps, container, false);
                maps = view.findViewById(R.id.map_images);
                maps.setImageResource(mapImage);
            } else {
                view = inflater.inflate(R.layout.fragment_1, container, false);
                text =  view.findViewById(R.id.textView);
                radioButtons = view.findViewById(R.id.radioGroup);
                text.setText(stringValue);
                maps.setImageResource(imagesResId);
           }

wcześniej masz ImageView maps = view.findViewById(map_images); więc obiektem do którego ładujesz zdjęcie o id przekazanym przez imagesResId jest obiekt maps i to na tym obiekcie wywołujesz metodę setImageResource

IDE AndroidStudio w czasie kompilacji powinno Ci takie coś zgłosić jako błąd. Poucz się podstaw Javy i podstaw Androida

0

dobra teraz widzę że ogólnie cała metoda kuleje. Musisz się zdecydować co chcesz robić. Z metody onCreateView musisz zwrócić return wygenerowany widok view

Zobacz co robisz (komentarze do linijek)

           View view = inflater.inflate(R.layout.fragment_1, container, false); // generujesz sobie widok z fragment_1
            text =  view.findViewById(R.id.textView); // bindujesz sobie textView do pola w klasie
            ImageView imageResId = view.findViewById(image); // bindujesz sobie widok do lokalnej zmiennej imageResId o typie ImageView, a masz w klasie int imageResId
            ImageView maps = view.findViewById(map_images); // bindujesz widok mapy
            answer = view.findViewById((R.id.radioGroup)); //bindujesz radiogrupe

            text.setText(stringValue);
            imageResId.setImageResource(imagesResId); // tutaj masz konflikt nazw
            maps.setImageResource(mapImage); // do obietku maps chcesz wstawic zmienna boolean a potrzebny jest resource

            if(mapImage){ // warunek sprawdzasz
                view = inflater.inflate(R.layout.maps, container, false); // tutaj znowu robisz inflate i podmieniasz sobie view ktore zwracasz pozniej 
                maps = view.findViewById(R.id.map_images); // znowu bindujesz maps
                maps.setImageResource(mapImage); // do obiektu wpisujesz boolean
            }else{
                view = inflater.inflate(R.layout.fragment_1, container, false); // znowu kreujesz nowy widok
                text =  view.findViewById(R.id.textView); // znowu bindujesz text
                radioButtons = view.findViewById(R.id.radioGroup);
                text.setText(stringValue);
                imageResId.setImageResource(imagesResId); // znowu blad z tymi samymi nazwami
               }

w notatniku ten kod piszesz, przecież to IDE jak AndroidStudio nie pozwoli nawet skompilować. Ściągnij jakieś porządne środowisko i poczytaj o Javie bo obiektu od typu prostego nie rozróżniasz nawet

0

Witaj,
dziękuje Ci serdecznie za zainteresowanie moim postem. Odpisując w punktach to tak:

  1. używam Android Studio i zdarza się że korzystaniem z dokumentacji np. na android developer, jednak nie wszystko jest tam dla mnie jasne (zbyt techniczny język).

  2. odziwo ta linia kodu o której pisałeś imageResId.setImageResource(imagesResId); działa (może po prostu nie dostrzegłeś litery S w nazwie o którą się różnią, tylko przypuszczam).

  3. piszesz, "że to ma wyglądać tak" ale w tym kodzie znów mamy tą nieszczęsną linię maps.setImageResource(mapImage);

  4. zrobiłem dla Ciebie rysunek z layoutem (będzie nam lepiej się zrozumieć) :)

layout z kodem.jpg

Mam nadzieje ,że uda nam się razem poprawić ten kod i będzie działał poprawnie.
Miłego dnia i do kolejnego postu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1