2

I'm trying to implement a ListView into my Fragment and I am getting a NullPointerException no matter what I try. I checking objects for null and logging if they are, and it appears the ListView is null but the ListItemAdapter appears to be insantiated.

   ListItemAdapter listAdapter = new ListItemAdapter(getContext(), R.layout.list_item_fragment, walks);
    if(listAdapter == null)
        Log.d("ListAdapter: ", "Null!!!");
    else
        Log.d("ListAdapter: ", "Not Null!!!");

    ListView listView = (ListView) getActivity().findViewById(R.id.list_view);

    if(listView == null)
        Log.d("ListView: ", "Null!!!");
    else
        Log.d("ListView: ", "Not Null!!!");
    listView.setAdapter(listAdapter);

edit: heres the entire fragment

package com.janedoe.anothertabexample.fragments;

import android.app.Activity;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;

import com.janedoe.anothertabexample.R;
import com.janedoe.anothertabexample.models.WalkModel;

import java.util.ArrayList;
import com.janedoe.anothertabexample.Adapters.*;

public class TabFragment1 extends Fragment {


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

        ArrayList<WalkModel> walks = new ArrayList<>();
        WalkModel walk1 = new WalkModel();
        walk1.setDescription("Walked around the block.");
        walk1.setElapsed_time(SystemClock.uptimeMillis() - 99999999);

        WalkModel walk2 = new WalkModel();
        walk2.setDescription("Walked to store.");
        walk2.setElapsed_time(SystemClock.uptimeMillis() - 98999000);

        WalkModel walk3 = new WalkModel();
        walk3.setDescription("Ran a million miles.");
        walk3.setElapsed_time(SystemClock.uptimeMillis() - 97999999);

        WalkModel walk4 = new WalkModel();
        walk4.setDescription("Biked");
        walk4.setElapsed_time(SystemClock.uptimeMillis() - 96999999);

        walks.add(walk1);
        walks.add(walk2);
        walks.add(walk3);
        walks.add(walk4);

        ListItemAdapter listAdapter = new ListItemAdapter(getContext(), R.layout.list_item_fragment, walks);
        if(listAdapter == null)
            Log.d("ListAdapter: ", "Null!!!");
        else
            Log.d("ListAdapter: ", "Not Null!!!");
        ListView listView = (ListView) getView().findViewById(R.id.list_view);
        if(listView == null)
            Log.d("ListView: ", "Null!!!");
        else
            Log.d("ListView: ", "Not Null!!!");
        listView.setAdapter(listAdapter);

        return inflater.inflate(R.layout.tab_fragment_1, container, false);
    }
}

Here is the the custom adapter:

package com.janedoe.anothertabexample.Adapters;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

import com.janedoe.anothertabexample.R;
import com.janedoe.anothertabexample.fragments.TabFragment1;
import com.janedoe.anothertabexample.models.WalkModel;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

/**
 * Created by janedoe on 12/10/2015.
 */
public class ListItemAdapter extends ArrayAdapter<WalkModel> {

    public ListItemAdapter(Context context, int resource, ArrayList<WalkModel> walks) {
        super(context,resource, walks);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = LayoutInflater.from(getContext());
        View listItem = inflater.inflate(R.layout.list_item_fragment, parent, false);

        WalkModel model = getItem(position);

        TextView date = (TextView) listItem.findViewById(R.id.date);
        TextView time = (TextView) listItem.findViewById(R.id.time);
        TextView description = (TextView) listItem.findViewById(R.id.description);

        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
        String formattedDate = sdf.format(new Date(model.getDate()));

        date.setText(formattedDate);
        time.setText(String.valueOf(model.getElapsedTime()));
        description.setText(model.getDescription());

        return listItem;

    }
}

Here is the list_item_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:id="@+id/list_item_fragment"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/datetime"
        android:orientation="vertical"
        android:layout_width="125dp"
        android:layout_height="60dp"
        android:layout_marginLeft="5dp"
        android:layout_marginTop="5dp" >

        <TextView
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="01/01/1001"
            android:textAlignment="center"
            android:id="@+id/date"
            android:layout_marginBottom="2dp"
            android:textStyle="bold|italic" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="00:00:00"
            android:textAlignment="center"
            android:id="@+id/elapsed_time" />

    </LinearLayout>

    <TextView
        android:layout_toRightOf="@id/datetime"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:padding="5dp"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="This is a short description..."
        android:textAlignment="center"
        android:id="@+id/description" />

</RelativeLayout>

And here is the fragments xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#d3d3d3">

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textAlignment="center"></ListView>

</RelativeLayout>
Dustin
  • 567
  • 2
  • 5
  • 18

4 Answers4

1

The ListView is in the view hierarchy you're inflating at the end of onCreateView().

getView() returns what onCreateView() returned but it has not yet returned anything. Also the hierarchy is not yet attached to any activity so the original code using getActivity().findViewById() has the same problem.

So, instead, inflate the view hierarchy earlier and store it in a variable:

View root = inflater.inflate(R.layout.tab_fragment_1, container, false);

Then use this to access its subviews:

ListView listView = (ListView) root.findViewById(R.id.list_view);

and finally return the whole hierarchy:

return root;
laalto
  • 150,114
  • 66
  • 286
  • 303
  • Awesome, this worked perfectly. Thanks a million, I'm still very new to android and was absolutely stumped on what to even look for. After I read your post and read my method it clicked what was going on there. I didn't realize it required the fragments layout, but I guess that's where the ListView is, so it makes sense! The app I'm working on is simply the result of hacking together parts of various tutorials and changing bits and pieces to make it more my own...lol Again thanks a bunch I was getting frustrated for a bit there – Dustin Dec 11 '15 at 07:42
0

I can't even see where your fragment is. The methods on the fragment must be called before.

Null TextView object in a fragment

There is no ListView in the activity, because it is in the fragment. By doing:

ListView listView = (ListView) getActivity().findViewById(R.id.list_view);

You are finding something that is not there. Instead, since it is in the fragment, do the following:

ListView listView = (ListView) findViewById(R.id.list_view);

Now, listView will actually exist.

Community
  • 1
  • 1
Ruchir Baronia
  • 7,406
  • 5
  • 48
  • 83
0

Use:

ListView listView= (ListView) rootView.findViewById(R.id.list_view);

This will solve your problem.

nullpointer
  • 490
  • 2
  • 4
  • 20
0

You should get the reference of ListView in Fragment.onViewCreated callback method, the first parameter of this method is the root view of this Fragment, so just call the view.findViewById method of the first parameter object

Tang Ke
  • 1,508
  • 12
  • 12