Search code examples
javaandroidlistadapter

Runtime error while expanding a Listadapter


I am writing this code to have a custom list in android. I am using

'com.android.support:support-v4:26.1.0'

My current code is trying to show a listview that includes image and text, but I guess that doesn't matter.

FourthFragment.java

public class FourthFragment extends ListFragment {

    private ArrayList<Weather>  weatherProperties = new ArrayList<>();

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onActivityCreated(savedInstanceState);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View myFragmentView = inflater.inflate(R.layout.fragment_fourth, container, false);
        //create our property elements
        weatherProperties.add(new Weather(10, "Smith Street", "Sydney", "NSW", "A large 3 bedroom apartment right in the heart of Sydney! A rare find, with 3 bedrooms and a secured car park.", 450.00, "property_image_1", 3, 1, 1));
        weatherProperties.add(new Weather(66, "King Street", "Sydney", "NSW", "A fully furnished studio apartment overlooking the harbour. Minutes from the CBD and next to transport, this is a perfect set-up for city living.", 320.00, "property_image_2", 1, 1, 1));
        weatherProperties.add(new Weather(1, "Liverpool Road", "Liverpool", "NSW", "A standard 3 bedroom house in the suburbs. With room for several cars and right next to shops this is perfect for new families.", 360.00, "property_image_3", 3, 2, 2));
        weatherProperties.add(new Weather(567, "Sunny Street", "Gold Coast", "QLD", "Come and see this amazing studio apartment in the heart of the gold coast, featuring stunning waterfront views.", 360.00, "property_image_4" , 1, 1, 1));

        TextView tv = (TextView) myFragmentView.findViewById(R.id.bedroom);
        tv.setText("My Header");
//        setListAdapter(new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,names));
        // New Array Adapters
        ArrayAdapter<Weather> adapter = new weatherArrayAdapter(getContext(), 0, weatherProperties);
        //Find list view and bind it with the custom adapter
        ListView listView = (ListView) tv.findViewById(R.id.customListView);
        listView.setAdapter(adapter);


        return myFragmentView;
    }
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // on click display the item in toast
        Toast.makeText(getActivity(), (String)l.getItemAtPosition(position), Toast.LENGTH_SHORT).show();
    }
    static FourthFragment newInstance(int num) {
        FourthFragment fourthFragment = new FourthFragment();

        Bundle args = new Bundle();
        args.putInt("num", num);
        fourthFragment.setArguments(args);

        return fourthFragment;
    }


    //custom ArrayAdapater
    class weatherArrayAdapter extends ArrayAdapter<Weather>{

        private Context context;
        private List<Weather> weatherProperties;

        //constructor, call on creation
        public weatherArrayAdapter(Context context, int resource, ArrayList<Weather> objects) {
            super(context, resource, objects);

            this.context = context;
            this.weatherProperties = objects;
        }

        //called when rendering the list
        public View getView(int position, View convertView, ViewGroup parent) {

            //get the weather we are displaying
            Weather weather = weatherProperties.get(position);

            //get the inflater and inflate the XML layout for each item
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

            //conditionally inflate either standard or special template
            View view;

            view = inflater.inflate(R.layout.weather_layout, null);


            TextView description = (TextView) view.findViewById(R.id.description);
            TextView address = (TextView) view.findViewById(R.id.address);
            TextView bedroom = (TextView) view.findViewById(R.id.bedroom);
            TextView bathroom = (TextView) view.findViewById(R.id.bathroom);
            TextView carspot = (TextView) view.findViewById(R.id.carspot);
            TextView price = (TextView) view.findViewById(R.id.price);
            ImageView image = (ImageView) view.findViewById(R.id.image);

            //set address and description
            String completeAddress = weather.getStreetNumber() + " " + weather.getStreetName() + ", " + weather.getSuburb() + ", " + weather.getState();
            address.setText(completeAddress);

            //display trimmed excerpt for description
            int descriptionLength = weather.getDescription().length();
            if(descriptionLength >= 100){
                String descriptionTrim = weather.getDescription().substring(0, 100) + "...";
                description.setText(descriptionTrim);
            }else{
                description.setText(weather.getDescription());
            }

            //set price and weather attributes
            price.setText("$" + String.valueOf(weather.getPrice()));
            bedroom.setText("Bed: " + String.valueOf(weather.getBedrooms()));
            bathroom.setText("Bath: " + String.valueOf(weather.getBathrooms()));
            carspot.setText("Car: " + String.valueOf(weather.getCarspots()));

            //get the image associated with this weather
            int imageID = context.getResources().getIdentifier(weather.getImage(), "drawable", context.getPackageName());
            image.setImageResource(imageID);

            return view;
        }
    }


}

There is no compiletime error, but this is giving me runtime error as

 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference

   at com.example.phocast.FourthFragment.onCreateView(FourthFragment.java:39)
   at android.support.v4.app.Fragment.performCreateView(Fragment.java:2354)

What I am doing wrong here?

I will be grateful if you kindly show me the problem.

UPDATE after the answers and comments

The error is here: (sorry for putting this as quote, otherwise SO doesnt allow me to submit as mostly code error)

TextView tv = (TextView) myFragmentView.findViewById(R.id.bedroom);
tv.setText("My Header");

and the xml is:

weather_layout.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:paddingTop="10dp"
    android:paddingBottom="10dp">

    <ImageView
        android:id="@+id/image"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginRight="10dp"
        android:contentDescription="Property Image" />

    <LinearLayout
        android:id="@+id/infoSection"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/image"
        android:orientation="vertical">

        <TextView
            android:id="@+id/address"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:text="Street Address"
            android:textSize="18sp" />

        <TextView
            android:id="@+id/description"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:text="Description"
            android:textSize="15sp" />
    </LinearLayout>

    <RelativeLayout
        android:id="@+id/pricingSection"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/infoSection"
        android:orientation="vertical">

        <TextView
            android:id="@+id/price"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:text="Price" />

        <TextView
            android:id="@+id/bedroom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/price"
            android:layout_marginRight="15dp"
            android:text="Bed:" />

        <TextView
            android:id="@+id/bathroom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/price"
            android:layout_marginRight="15dp"
            android:layout_toRightOf="@id/bedroom"
            android:text="Bath:" />

        <TextView
            android:id="@+id/carspot"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/price"
            android:layout_marginRight="15dp"
            android:layout_toRightOf="@id/bathroom"
            android:text="Car:" />

    </RelativeLayout>

</RelativeLayout>

UPDATE 2: fragment_four.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:background="@color/colorPrimaryLight">

    <ListView
    android:id="@+id/customListView"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_centerHorizontal="true"
    android:layout_alignParentStart="true"
    android:scrollbars="vertical"
    android:textAlignment="gravity">
    </ListView>
    </RelativeLayout>

UPDATE3 So, I have created a fourth_fragment.xml as:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@color/colorPrimaryLight">

    <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:text="Description"
            android:textSize="15sp" />
    <ListView
        android:id="@+id/customListView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_centerHorizontal="true"
        android:scrollbars="vertical"
        android:textAlignment="gravity"></ListView>
</LinearLayout>

and changed the line:

tv = (TextView) myFragmentView.findViewById(R.id.textView);
          tv.setText("My Header");

But I am still getting the error:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference


Solution

  • You are getting null over here. Check whether you have TextView id = bedroom or not in layout fragment_fourth

      TextView tv = (TextView) myFragmentView.findViewById(R.id.bedroom);
      tv.setText("My Header");
    

    Your Error :

    'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference

    Its issue of Id of your TextView,The variable tv is probably null and you call the setText method on that null, which you can't.

    And Modify your code like this :

    TextView tv; //Global Variable
    
          tv = (TextView) myFragmentView.findViewById(R.id.bedroom);
          tv.setText("My Header");
    

    Try also : Clean your project & Rebuilt it.

    Change your fragmentfour.xml code : (Put ScrollView if needed)

        <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:background="@color/colorPrimaryLight">
    
    <include
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       layout="@layout/yourTextView_layout)" />
    
        <ListView
        android:id="@+id/customListView"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_centerHorizontal="true"
        android:layout_alignParentStart="true"
        android:scrollbars="vertical"
        android:textAlignment="gravity">
        </ListView>
        </LinearLayout>
    

    Update your Fragment java class :

    ListView listView;//globally
    TextView tv;
    
    
         @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View myFragmentView = inflater.inflate(R.layout.fragment_fourth, container, false);
    
      listView = (ListView) tv.findViewById(R.id.customListView);
            //create our property elements
            weatherProperties.add(new Weather(10, "Smith Street", "Sydney", "NSW", "A large 3 bedroom apartment right in the heart of Sydney! A rare find, with 3 bedrooms and a secured car park.", 450.00, "property_image_1", 3, 1, 1));
            weatherProperties.add(new Weather(66, "King Street", "Sydney", "NSW", "A fully furnished studio apartment overlooking the harbour. Minutes from the CBD and next to transport, this is a perfect set-up for city living.", 320.00, "property_image_2", 1, 1, 1));
            weatherProperties.add(new Weather(1, "Liverpool Road", "Liverpool", "NSW", "A standard 3 bedroom house in the suburbs. With room for several cars and right next to shops this is perfect for new families.", 360.00, "property_image_3", 3, 2, 2));
            weatherProperties.add(new Weather(567, "Sunny Street", "Gold Coast", "QLD", "Come and see this amazing studio apartment in the heart of the gold coast, featuring stunning waterfront views.", 360.00, "property_image_4" , 1, 1, 1));
    
             tv = (TextView) myFragmentView.findViewById(R.id.bedroom);
            tv.setText("My Header");
    //        setListAdapter(new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,names));
            // New Array Adapters
            ArrayAdapter<Weather> adapter = new weatherArrayAdapter(getContext(), 0, weatherProperties);
            //Find list view and bind it with the custom adapter
    
            listView.setAdapter(adapter);
    
    
            return myFragmentView;
        }