Question

So I've been lurking around trying to find the answer to this for a while. I'm caving. I need a fresh set of eyes. My View getView inside my CustomAdapter is not being called.

public class User_List_Fragment extends ListFragment {
    View view;
    DBHelper db;
    List<UTable> userList;
    ListView list;
    TextView id, firstName, lastName, job;
    String mId;

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.view_users_fragment, container, false);

        list = (ListView) view.findViewById(android.R.id.list);
        db = new DBHelper(getActivity());
        userList = db.getUserList();

        class CustomAdapter extends ArrayAdapter<String> {
             private Context context;

            public CustomAdapter(Context context, int textViewResourceId, List<UTable> userList) {
                    super(context, textViewResourceId);
                    this.context = context;
             }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View row = convertView;
                if (row == null) {
                    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    row = inflater.inflate(R.layout.custom_list_row, null);
                }

                id = (TextView) row.findViewById(R.id.list_id);
                firstName = (TextView) row.findViewById(R.id.list_first_name);
                lastName = (TextView) row.findViewById(R.id.list_last_name);
                job = (TextView) row.findViewById(R.id.list_job);               
                for (UTable uTable : userList) {
                    id.setText(String.valueOf(uTable.getId()));
                    firstName.setText(uTable.getFirstName());
                    lastName.setText(uTable.getLastName());
                    job.setText(uTable.getJob());

                    String mId = String.valueOf(uTable.getId());
                    String mF = uTable.getFirstName();
                    String mL = uTable.getLastName();
                    String j = uTable.getJob();

                    Log.v("ID", mId);
                    Log.v("First Name", mF);
                    Log.v("Last Name", mL);
                    Log.v("Job", j);                    
                 }              
                return row;
            }           
        }
        list.setAdapter(new CustomAdapter(getActivity().getApplicationContext(), R.layout.custom_list_row, userList));
        db.close();
        return view; 
    }
}

view_users_fragment.xml

    <?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" >

        <ListView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@android:id/list"
            android:gravity="center" />

        <TextView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/no_data"
            android:id="@android:id/empty"
            android:gravity="center"/>

    </LinearLayout>

custom_list_row.xml

<?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="horizontal" >

    <TextView
        android:id="@+id/list_id" 
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight=".10"
        android:text="@string/one"/>

    <TextView
        android:id="@+id/list_first_name" 
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight=".25"
        android:text="@string/first_name_hint"/>

    <TextView
        android:id="@+id/list_last_name" 
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight=".25"
        android:text="@string/last_name_hint"/>

    <TextView
        android:id="@+id/list_job"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight=".5"
        android:text="@string/job_hint" />

</LinearLayout>

The default TextView is instead being called. Which happens when the list is empty and its stating "no data found". I have tested the query to the database and it works. If I place my for loop outside of my getView it returns the results. I think I'm messing up my constructor for my CustomAdapter, but I can't seem to figure it out. Any help is appreciated.

EDIT RE-FACTORED CODE

User_List_Fragment.java

public class User_List_Fragment extends ListFragment {
    View view;
    DBHelper db;
    List<UTable> userList;
    ListView list;
    CustomAdapter adapter;

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.view_users_fragment, container, false);

        db = new DBHelper(getActivity());
        userList = db.getUserList();

        list = (ListView) view.findViewById(android.R.id.list);
        adapter = new CustomAdapter(getActivity().getApplicationContext(), R.layout.custom_list_row, userList);     
        list.setAdapter(adapter);

        db.close();
        return view; 
    }
}

CustomAdapter.java

public class CustomAdapter extends ArrayAdapter<UTable> {
     private Context context;

    public CustomAdapter(Context context, int textViewResourceId, List<UTable> userList) {
        super(context, textViewResourceId);
        this.context = context;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView== null) {
            convertView = View.inflate(context, R.layout.custom_list_row, null);
        }

        TextView id = (TextView) convertView.findViewById(R.id.list_id);
        TextView firstName = (TextView) convertView.findViewById(R.id.list_first_name);
        TextView lastName = (TextView) convertView.findViewById(R.id.list_last_name);
        TextView job = (TextView) convertView.findViewById(R.id.list_job);

        UTable uTable = getItem(position);
        if (uTable != null) {
            id.setText(String.valueOf(uTable.getId()));
            firstName.setText(uTable.getFirstName());
            lastName.setText(uTable.getLastName());
            job.setText(uTable.getJob());

            Log.v("JOB", uTable.getJob());
        }
        return convertView;
    }           
}
Was it helpful?

Solution

Ok, I've just taken a quick look, you are misunderstanding how to use an Adapter.

getView is called by each row of data passed in. Inside get view you should just getItem(position) and fill in the fields with that objects data

To be clearer - you wont need a for loop at all, as long as you are extending a baseadapter somewhere in the heirarchy the loop will be automatic

Example

  class CustomAdapter extends ArrayAdapter<UTable> {

        public CustomAdapter(Context context, int textViewResourceId, List<UTable> userList) {
                super(context, textViewResourceId, userlist);
         }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView== null) {
               convertView = View.inflate(R.layout.custom_list_row, null);
            }

            //google the view holder pattern when you are more exerienced
            TextView id = (TextView) row.findViewById(R.id.list_id);
            TextView firstName = (TextView) row.findViewById(R.id.list_first_name);
            TextView lastName = (TextView) row.findViewById(R.id.list_last_name);
            TextView job = (TextView) row.findViewById(R.id.list_job);               

            UTable item = getItem(position);
            job.setText(item.getJob());
            ...

            return convertView;
        }           
    }

Things that are broken:

  //Java classes should be named like UserListFragment 
  public class User_List_Fragment extends ListFragment {

     //You shouldnt have these views here, they arent part of the fragmetn
     //they are part of each row in the list and so will keep changing!
     TextView id, firstName, lastName, job;
     String mId;

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

       ...

           //You are inside the onCreateView method here - yo ucant decalre a class inside a method!
           class CustomAdapter extends ArrayAdapter<UTable> {

OTHER TIPS

you need to set CustomAdapter to list view. list.setAdapter(customAdapter)

you need pass your data to constructor too, change Constructor method with following code:

public CustomAdapter(Context context, int textViewResourceId, List<UTable> userList) {
        super(context, textViewResourceId , userList);
        this.context = context;
             }

or use BaseAdapter class instead of ArrayAdapter and override GetCount() and GetItem() method and in GetCount method return size of your list

the reason behind your getview method is not being called is...

in order to let adapter know how many rows it has, you must pass either your data from Constructor or by overriding the getCount method.

you are not doing any of the thing. so adapter is not aware of any data.

so

use any of this constructor bellow

    http://developer.android.com/reference/android/widget/ArrayAdapter.html#ArrayAdapter%28android.content.Context,%20int,%20T[]%29

http://developer.android.com/reference/android/widget/ArrayAdapter.html#ArrayAdapter%28android.content.Context,%20int,%20int,%20T[]%29

http://developer.android.com/reference/android/widget/ArrayAdapter.html#ArrayAdapter%28android.content.Context,%20int,%20int,%20T[]%29

http://developer.android.com/reference/android/widget/ArrayAdapter.html#ArrayAdapter%28android.content.Context,%20int,%20int,%20java.util.List%3CT%3E%29

or override getCount method

http://developer.android.com/reference/android/widget/ArrayAdapter.html#getCount%28%29

and you are done. hope that help

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top