Reputation: 1433
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;
}
}
Upvotes: 1
Views: 322
Reputation: 4445
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
Upvotes: 0
Reputation: 21733
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> {
Upvotes: 1
Reputation: 11948
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
Upvotes: 0
Reputation: 53657
you need to set CustomAdapter to list view. list.setAdapter(customAdapter)
Upvotes: 0