0

I'm trying to create a Fragment showing a list of strings retrieved from a website. I created some fragments with Android Studio's command "new -> Fragment (List)". Fragments refer to the main Navigation Drawer Activity. When I try to execute the app with the emulator, the app crashes when I click on fragment's name. What can I do to fix this problem?

MainActivity.java

package com.example.is2_app;

import android.os.Bundle;

import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;

import com.example.is2_app.ui.dummy.DummyContent;
import com.example.is2_app.ui.municipio.municipioFragment;
import com.google.android.material.navigation.NavigationView;

import androidx.drawerlayout.widget.DrawerLayout;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

public class MainActivity extends AppCompatActivity implements municipioFragment.OnListFragmentInteractionListener {

    private AppBarConfiguration mAppBarConfiguration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.nav_municipio, R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow,
                R.id.nav_tools, R.id.nav_share, R.id.nav_send)
                .setDrawerLayout(drawer)
                .build();
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    }

    @Override
    public void onListFragmentInteraction(DummyContent.DummyItem item) {

    }
}

activity_main_drawer.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:showIn="navigation_view">

    <group android:checkableBehavior="single">
        <item
            android:id="@+id/nav_gallery"
            android:icon="@drawable/ic_menu_gallery"
            android:title="@string/menu_comune" />

        <item
            android:id="@+id/nav_municipio"
            android:icon="@drawable/ic_menu_gallery"
            android:title="@string/menu_municipio" />

        <item
            android:id="@+id/nav_slideshow"
            android:icon="@drawable/ic_menu_slideshow"
            android:title="@string/menu_slideshow" />
        <item
            android:id="@+id/nav_tools"
            android:icon="@drawable/ic_menu_manage"
            android:title="@string/menu_tools" />
    </group>

    <item android:title="Communicate">
        <menu>
            <item
                android:id="@+id/nav_share"
                android:icon="@drawable/ic_menu_share"
                android:title="@string/menu_share" />
            <item
                android:id="@+id/nav_send"
                android:icon="@drawable/ic_menu_send"
                android:title="@string/menu_send" />
        </menu>
    </item>

</menu>

ComuneFragment.java

package com.example.is2_app.ui.comune;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;

import com.example.is2_app.R;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;

public class ComuneFragment extends Fragment {

    private ComuneViewModel comuneViewModel;
    private Button getBtn;
    private TextView result;

    public ComuneFragment() {
    }


    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        comuneViewModel =
        ViewModelProviders.of(this).get(ComuneViewModel.class);
        View root = inflater.inflate(R.layout.fragment_comune, container, false);


        result = result.findViewById(R.id.result);
        getBtn = getBtn.findViewById(R.id.getBtn);
        getBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getWebsite();
            }
        });
        return root;
    }

    private void getWebsite() {

        new Thread(new Runnable() {
            @Override
            public void run() {
                final StringBuilder builder = new StringBuilder();
                try {
                    Document doc = Jsoup.connect("http://www.ssaurel.com/blog").get();
                    String title = doc.title();
                    Elements links = doc.select("a[href]");
                    builder.append(title).append("\n");

                    for (Element link : links) {
                        builder.append("\n").append("Link: ").append(link.attr("href"))
                                .append("\n").append("Text: ").append(link.text());

                    }

                } catch (IOException e) {
                    builder.append("Error: ").append(e.getMessage()).append("\n");
                }

                if (getActivity() != null) {
                    getActivity().runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            result.setText(builder.toString());
                        }

                    });
                }
            }
        }).start();
    }
}

ComuneViewModel.java

package com.example.is2_app.ui.comune;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

public class ComuneViewModel extends ViewModel {

    private MutableLiveData<String> mText;

    public ComuneViewModel() {
        mText = new MutableLiveData<>();
        mText.setValue("This is gallery fragment");
    }

    public LiveData<String> getText() {
        return mText;
    }
}

fragment_comune.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <Button
        android:id="@+id/getBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/result"
        android:layout_marginStart="148dp"
        android:layout_marginLeft="148dp"
        android:layout_marginTop="132dp"
        android:text="@string/get_website"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.006"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.495" />

    <TextView
        android:id="@+id/result"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/getBtn"
        android:layout_marginStart="8dp"
        android:layout_marginTop="488dp"
        android:layout_marginEnd="8dp"
        android:text="Result..."
        android:textAlignment="center"
        android:textSize="20sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

Logcat

2020-01-21 16:05:54.043 25410-25410/com.example.is2_app E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.is2_app, PID: 25410
    java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.widget.TextView.findViewById(int)' on a null object reference
        at com.example.is2_app.ui.comune.ComuneFragment.onCreateView(ComuneFragment.java:39)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
        at androidx.fragment.app.FragmentManagerImpl.addAddedFragments(FragmentManagerImpl.java:2100)
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1874)
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1830)
        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
        at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Markus Kauppinen
  • 3,025
  • 4
  • 20
  • 30
  • [Unfortunately MyApp has stopped. How can I solve this?](https://stackoverflow.com/questions/23353173/unfortunately-myapp-has-stopped-how-can-i-solve-this) helps in getting started with troubleshooting issues like this. And people will want to see the crash log because it often points out the exact nature and location of the problem. It's much more difficult to just read the code and try to spot mistakes. – Markus Kauppinen Jan 21 '20 at 15:26
  • Anyway, having `findViewById()` in `onCreateView()` could be a problem, if I remember correctly the Fragment lifecycle. I'd try `onViewCreated()` instead. – Markus Kauppinen Jan 21 '20 at 15:29
  • Ah, this is horribly wrong too: `result = result.findViewById(R.id.result);`. There's no point in trying to call `findViewById()` on the view that you are trying to find. You'll call it on the view that contains the `result` view. But you don't have that view in `onCreateView()` yet because that's the method that creates it. So, try in `onViewCreated()` instead. And maybe read about Fragments in the Android documentation if there's something unclear. – Markus Kauppinen Jan 21 '20 at 15:34
  • 1
    You wrote `result.findViewById(R.id.result)` instead of `root.findViewById(R.id.result)` – EpicPandaForce Jan 21 '20 at 15:51
  • 1
    This was very useful for me, now it works! Thanks! –  Jan 21 '20 at 15:55

0 Answers0