Search code examples
androidlistviewandroid-fragmentscustom-adapter

getView() method of custom adapter never gets called


I've read various SO threads on the topic but none of them seem to apply to my code.

I'm trying to populate a fragment with a ListView with my custom NearbyAdapter. However, my getView() method never gets called (as demonstrated by my logs not showing up). The view itself seems to be appropriately attached to my fragment, as demonstrated by the button in the view showing up, but not the ListView.

enter image description here

Relevant NearbyListFragment.java code:

public class NearbyListFragment extends ListFragment {

    private int mImageSize;
    private boolean mItemClicked;
    private NearbyAdapter mAdapter;

    private List<Place> places;
    private LatLng mLatestLocation;

    private static final String TAG = "NearbyListFragment";

    public NearbyListFragment() {
    }

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

        Log.d(TAG, "NearbyListFragment created");

        View view = inflater.inflate(R.layout.fragment_nearby, container, false);
        return view;
    }

    //TODO: Do asynchronously?
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {

        //Load from data source (NearbyPlaces.java)

        mLatestLocation = ((NearbyActivity) getActivity()).getmLatestLocation();
        //FIXME: Hardcoding mLatestLocation to Michigan for testing
        //mLatestLocation = new LatLng(44.182205, -84.506836);

        places = loadAttractionsFromLocation(mLatestLocation);
        mAdapter = new NearbyAdapter(getActivity(), places);

        ListView listview = (ListView) view.findViewById(R.id.listview);
        //setListAdapter(mAdapter);
        listview.setAdapter(mAdapter);

        Log.d(TAG, "Adapter set to ListView");
        mAdapter.notifyDataSetChanged();
    }

    private class NearbyAdapter extends ArrayAdapter {

        public List<Place> placesList;
        private Context mContext;

        public NearbyAdapter(Context context, List<Place> places) {
            super(context, R.layout.item_place);
            mContext = context;
            placesList = places;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // Get the data item for this position
            Place place = (Place) getItem(position);
            //FIXME: This never gets called
            Log.d(TAG, "Place " + place.name);

            // Check if an existing view is being reused, otherwise inflate the view
            if (convertView == null) {
                convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_place, parent, false);
            }

            // Lookup view for data population
            TextView tvName = (TextView) convertView.findViewById(R.id.tvName);
            TextView tvDesc = (TextView) convertView.findViewById(R.id.tvDesc);

            // Populate the data into the template view using the data object
            tvName.setText(place.name);
            tvDesc.setText(place.description);

            // Return the completed view to render on screen
            return convertView;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

The layout file of the fragment, fragment_nearby.xml :

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/listview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_above="@+id/btn_New">
    </ListView>
    <Button
        android:id="@+id/btn_New"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_marginBottom="20dp"
        android:text="Button"
        android:width="170dp"
        android:layout_alignParentBottom="true" />

</RelativeLayout>

And the layout file of the item, item_place.xml :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <TextView
        android:id="@+id/tvName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Name" />
    <TextView
        android:id="@+id/tvDesc"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Desc" />
</LinearLayout> 

Edit: Does anyone want to actually include a reason for the downvote? Especially when something like Custom Adapter for List View has 129 upvotes?


Solution

  • The issue is that ArrayAdapter does not know about List places: Use this to fix it:

    private static class NearbyAdapter extends ArrayAdapter<Place> {
       public NearbyAdapter(Context context, List<Place> places) {
          super(context, R.layout.item_place, places);
          mContext = context;
          placesList = places;
       }
    }
    

    P/s: in this case, I think you need more control to set your place data to your view. Consider using BaseAdapter instead of ArrayAdapter.