I have a listview with a few buttons that I want to disclose more information. I have an xml file for the layout with several nested LinearLayouts. When the "Comments" button is pressed I want the appropriate layout to appear and then disappear. Inside of the model object I keep track of whether or not the view is disclosed.
public View getView(int position, View convertView, ViewGroup parent) {
final CarmenGrade grade = (CarmenGrade) getItem(position);
convertView = mInflater.inflate(R.layout.carmen_grade_item, null);
commentsLayout = (LinearLayout) convertView.findViewById(R.id.commentsLayout);
commentsButton = (Button) convertView.findViewById(R.id.commentsButton);
commentsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (grade.isShowingComments() == true) {
commentsLayout.setVisibility(View.GONE);
grade.setShowingComments(false);
/* other similar layout parts cut */
} else {
commentsLayout.setVisibility(View.VISIBLE);
grade.setShowingComments(true);
/* other similar layout parts cut */
}
notifyDataSetChanged();
}
});
}
On Android 4.x it works on the first press and the proper layout becomes visible. Pressing the button again doesn't appear to work consistently. Every once in a while it'll disappear.
On Android 5.0 I get a lot of warnings although it appears to work most of the time:
W/View﹕ requestLayout() improperly called by android.widget.TextView{2d2581cb V.ED.... ......ID 0,57-231,114 #7f0a0086 app:id/weightedValueTextView} during layout: running second layout pass
So my question is - how can I use items within the list to change the layout within getView so that it works consistently and doesn't throw errors? Am I missing a different, super obvious pattern?
EDIT Sorry, forgot to put in the place where I initialized the comments layout. It's definitely there.
In Adapter, getView() function is called many times. So when you go to find some view of carmen_grade_item
inside listener it will return you object which was initiated in last (Means of it may point to same object of other row from listview).
So to overcome this problem:
If you want to use it inside your adapter class : Maintain a viewHolder of specific row into array. or find specific layout like clickedView.getParent().findViewById(R.id.someLayout)
; and then perform your action.
So your listener would look like this
commentsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LinearLayout layout=(LinearLayout) ((MainParent which contains child)
v.getParent()).findViewById(R.id.commentsLayout);
if(layout.isShown()){
layout.setVisibility(View.GONE);
}else{
layout.setVisibility(View.VISIBLE);
}
notifyDataSetChanged();
}
});