How to Fill a ListView with an ArrayAdapter in a Fragment

1

I'm trying an example of how to read remote xml files, and after testing it works correctly I have modified it to integrate it into a fragment of a Drawer Layout, with the disappointment that it seems that it does not work the same at the time of filling a ListView with an ArrayAdapter inside a Main_Activity that in a fragment, I have pasted the piece of code and I have marked with a comment the two lines that give me the error.

I hope you have explained me well, regards.

I leave you the complete fragment, inside is the function where I collect all the data from the XML, but I think the problem does not go there, the ArrayAdapter adapter is created and it gets to fill well with the string holders

This is the line of original code used in a MainActivity and that in the fragment gives me error

ArrayAdapter adaptador  = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,titulares);

I had to change it for this one that works for me

ArrayAdapter adaptador  = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,titulares);

The error is given to me when I try to fill the ListView listTitles with the content of the ArrayAdapter adapter

listadoTitulos.setAdapter(adaptador);

Here is the complete fragment:

import android.content.Intent;
import android.os.Bundle;

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

import android.os.StrictMode;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import com.google.android.material.navigation.NavigationView;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import static android.os.Build.VERSION_CODES.N;


public class NewsFragment extends Fragment implements NavigationView.OnNavigationItemSelectedListener {

private URL url;
private ArrayList<ElCurso> UnCurso;
private String[] titulares;
private ListView listadoTitulos;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    StrictMode.ThreadPolicy permiso = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(permiso);

    listadoTitulos = (ListView) getActivity().findViewById(R.id.vtTitulares);
    UnCurso = new ArrayList<ElCurso>();

    try {

        url = new URL(" http://www.videotutoriales.es/android-xml/cursos.xml")             
        leerxml();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }

        ArrayAdapter adaptador  = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,titulares);
        listadoTitulos.setAdapter(adaptador);
    listadoTitulos.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Intent intent = new Intent (getActivity(),Detalle_curso.class);
            intent.putExtra("CURSO", UnCurso.get(position));
            startActivity(intent);
        }
    });


    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_news, container, false);
}



    private void leerxml() {
    XmlPullParserFactory factory;
    XmlPullParser xml;

    int evento;



    boolean titulo;
    boolean imagen;
    boolean detalle;

    ArrayList<String> titulos;
    ArrayList<String> imagenes;
    ArrayList<String> detalles;

    titulo = false;
    imagen = false;
    detalle = false;

    titulos = new ArrayList<String>();
    imagenes = new ArrayList<String>();
    detalles = new ArrayList<String>();

    try {
        factory = XmlPullParserFactory.newInstance();
        xml=factory.newPullParser();
        xml.setInput(url.openStream(), "UTF-8");

        evento=xml.getEventType();

        while (evento != XmlPullParser.END_DOCUMENT){

            switch (evento){
                case XmlPullParser.START_TAG:
                    if (xml.getName().equals("titulo")){
                        titulo = true;
                    }
                    if (xml.getName().equals("imagen")){
                        imagen = true;
                    }
                    if (xml.getName().equals("detalle")){
                        detalle = true;
                    }
                    break;
                case XmlPullParser.TEXT:
                    if (titulo){
                        titulos.add(xml.getText());
                    }
                    if (imagen){
                        imagenes.add(xml.getText());
                    }
                    if (detalle){
                        detalles.add(xml.getText());
                    }
                    break;
                case XmlPullParser.END_TAG:
                    if (xml.getName().equals("titulo")){
                        titulo = false;
                    }
                    if (xml.getName().equals("imagen")){
                        imagen = false;
                    }
                    if (xml.getName().equals("detalle")){
                        detalle = false;
                    }
                    break;

            }
            evento = xml.next();
        }

        titulares = new String[titulos.size()];
        for (int i = 0; i < titulos.size(); i++){
            UnCurso.add(new ElCurso(titulos.get(i), detalles.get(i), imagenes.get(i) ) );
            titulares[i] = titulos.get(i);
        }

    } catch (XmlPullParserException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

 @Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
    return false;
}

}

And here the error that gives me:

  

E / AndroidRuntime: FATAL EXCEPTION: main       Process: com.corporation.toneti.toneti100, PID: 23983       java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter (android.widget.ListAdapter)'   on a null object reference           at com.corporation.toneti.toneti100.NewsFragment.onCreateView (NewsFragment.java:75)           at androidx.fragment.app.Fragment.performCreateView (Fragment.java:2426)           at androidx.fragment.app.FragmentManagerImpl.moveToState (FragmentManager.java:1460)           at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState (FragmentManager.java:1795)           at androidx.fragment.app.FragmentManagerImpl.moveToState (FragmentManager.java:1863)           at androidx.fragment.app.BackStackRecord.executeOps (BackStackRecord.java:802)           at androidx.fragment.app.FragmentManagerImpl.executeOps (FragmentManager.java:2634)           at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether (FragmentManager.java:2421)           at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute (FragmentManager.java:2376)           at androidx.fragment.app.FragmentManagerImpl.execPendingActions (FragmentManager.java:2283)           at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange (FragmentManager.java:3286)           at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated (FragmentManager.java:3238)           at androidx.fragment.app.FragmentController.dispatchActivityCreated (FragmentController.java:201)

    
asked by Ciberdrac 05.08.2018 в 03:04
source

1 answer

1

The problem is that you are looking for the reference, in a non-existent space in Fragment . You must make sure that each reference belongs to the layout inflated by Fragment .

For example, in Activity you do setContentView to set the layout that will load. However, in Fragment is different. The root is inflated and fixed to the life cycle of the Activity that is the parent or creator element.

In your Fragment you have a onCreateView method that is the one who will create the view or layout that will be loaded in said Fragment container, therefore you should look for the reference in the root that it loads. In your code you must modify it in the following way:

Instead of returning the inflated view directly:

// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_news, container, false);

You must store it in a variable and look up the references in it, for example:

. . . At the beginning of the onCreateView method you must do. . .

// Inflate the layout for this fragment
View root = inflater.inflate(R.layout.fragment_news, container, false);

You look for references in root of the elements of the axml inflated, in this case the layout fragment_news .

Instead of:

listadoTitulos = (ListView) getActivity().findViewById(R.id.vtTitulares);

Change it to:

listadoTitulos = (ListView) root.findViewById(R.id.vtTitulares);

and at the end of everything, you must return root :

return root;

Tip: In the onCreateView , always try to handle all the tasks that belong to the creation of the view, assign and change its properties, call methods that load the data before creating the view, etc ... This will make your code look more orderly. For example, in your code:

StrictMode.ThreadPolicy permiso = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(permiso);

You should overwrite the onCreate method and put it there. You can see what method is called, from its creation until it is destroyed in the next image.

Life cycle of a Fragment

    
answered by 05.08.2018 / 15:17
source