Reputation: 767
In creating a custom list adapter to be able to click different elements in a single row entry and start different activities, I ran across a problem where my findViewById() method was returning null. Additionally, only the first item in my ListView calls the onClick method; the other rows don't register clicks.
public class CustomListAdapter extends SimpleAdapter implements View.OnClickListener {
Context context;
TextView habitId;
Intent intent;
public CustomListAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
this.context = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.habit_entry, null);
}
TextView tv = (TextView) v.findViewById(R.id.habitTitle);
tv.setOnClickListener(this);
ImageView iv = (ImageView) v.findViewById(R.id.plus);
iv.setOnClickListener(this);
return super.getView(position, convertView, parent);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.habitTitle:
Log.d("Test", "habitid = " + v.findViewById(R.id.habitId));
break;
case R.id.plus:
Log.d("Test", "plus clicked");
default:
break;
}
}
When the code is run, the habitTitle case of onClick prints
D/NULL: habitid = null
habit_entry
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:src="@drawable/ic_plus"
android:id="@+id/plus"
android:scaleType="centerCrop"
android:paddingRight="20dp"
android:paddingLeft="20dp"
android:background="#9bfcff" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="New Text"
android:id="@+id/habitId"
android:visibility="gone" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="difficulty"
android:id="@+id/habitDifficulty"
android:gravity="right"
android:paddingLeft="15dp"
android:layout_alignParentBottom="true"
android:layout_alignRight="@+id/habitTitle"
android:layout_alignEnd="@+id/habitTitle"
android:layout_marginRight="30dp"
android:layout_marginEnd="30dp" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="@id/plus"
android:layout_above="@id/habitDifficulty"
android:layout_alignWithParentIfMissing="true"
android:text="Your new habits go here!"
android:id="@+id/habitTitle"
android:padding="5dp"
android:textColor="#444444"
android:textSize="20sp"
android:textStyle="bold"
android:layout_alignParentStart="false"
android:gravity="right"
android:allowUndo="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="frequency"
android:id="@+id/habitFrequency"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
call in MainActivity
if(habitList.size() != 0) {
ListView listView = (ListView) findViewById(android.R.id.list);
ListAdapter adapter = new CustomListAdapter(
this, habitList, R.layout.habit_entry, new String[]{"habitId", "title", "difficulty", "frequency"}, new int[]{
R.id.habitId, R.id.habitTitle, R.id.habitDifficulty, R.id.habitFrequency});
listView.setAdapter(adapter);
}
The list populates perfectly, so I'm not sure why I'm having so much trouble with my adapter.
Upvotes: 2
Views: 439
Reputation: 11903
I see a couple problems here. You are inflating the View
yourself and then returning the View
returned by calling super.getView(position, convertView, parent);
. You should instead rely on super.getView(position, convertView, parent);
to create the View
for you since you are using the default implementation like this:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
v.findViewById(R.id.habitTitle)
.setOnClickListener(this);
v.findViewById(R.id.plus)
.setOnClickListener(this);
return v;
}
Also v.findViewById(R.id.habitId));
is returning null inside onClick()
because the variable v
itself is the TextView
with id = R.id.habitId.
Upvotes: 1
Reputation: 10650
You set the visibility of the habitId textview to gone. The textview will not be inflated and is null. You can read more information about visibility in the android documentation
Upvotes: 0