I have a custom list view which has a Textview and an image. When I click on the textview a hidden layout will be expanded for that particular row. But what happening was, f
You need to add a attribute to your adapter, a simple int
. When you click on an item, update the current selected position. When you build the view, check if position equals the selected position.
public View getView(final int position, View convertView, ViewGroup parent) {
if(this.selectedPosition == position){
//add a holder
else{
//don't add a holder
return convertview;
}
What I'm saying is that you are encountering a View recycling problem. If you modify item n°2 and then the view of item n°10 is build from the View n°2, you end up with an item unwanted (that will look as it was clicked).
When an item of your list is clicked:
1) update the selected item (attribute of your adapter). Example, if you click on item 12 of your listview, selectedItem = 12;
2) call method notifyDataSetChanged(). This will refresh the view of the list.
3) When you build the view (getView() of adapter), check for each position if it corresponds to the selected item. If it does, build your special view (I don't know exactly what you want to do). If it doesn't correspond to the selected item, build your view "normally"
But what happening was, for eg., when I click on 2nd row, 10th row is also getting expanded.
You are fighting the way ListViews recycle the row layouts. But this is easy enough to deal with, first let's add a couple new class variables:
SparseBooleanArray expanded = new SparseBooleanArray();
LayoutInflater inflater; // initialize this in your constructor
Now we'll use expanded
to check whether displayRecordRL
should be visible:
public View getView(final int position, View convertView, ViewGroup parent) {
DataFields rowItems = (DataFields) getItem(position);
if (convertView == null) {
convertView = inflater.inflate(R.layout.home_field_row, null);
holder = new ViewHolder();
holder.dataFields = items.get(position);
holder.mName = (TextView) convertView
.findViewById(R.id.hmFieldName);
holder.mDeleteImage = (ImageView) convertView
.findViewById(R.id.hmFieldDeleteImage);
holder.deleteMainRL = (RelativeLayout) convertView
.findViewById(R.id.hmdeleteMainRL);
// Add this to your holder
holder.mAddInfo = (RelativeLayout) convertView
.findViewById(R.id.displayRecordRL);
holder.mDeleteImage.setTag(position);
holder.mName.setTag(position);
holder.deleteMainRL.setTag(position);
holder.mName.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Get the ViewHolder
holder = (ViewHolder) ((View) v.getParent()).getTag();
Animation expandAnim = expand(holder.mAddInfo, true);
holder.mAddInfo.startAnimation(expandAnim);
// Remember that this View is expanded
int pos = (Integer) v.getTag();
expanded.put(pos, true);
}
});
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.mName.setText(rowItems.getName());
if(expanded.get(position, false))
holder2.mAddInfo.setVisibility(View.VISIBLE);
else
holder2.mAddInfo.setVisibility(View.GONE);
return convertView;
}
Notice how this tracks whether each row should be visible and uses a simple if statement to make sure the recycled layout correctly shows or hide the "Add Info" section.
The problem you experience could be that you animate a View (converView) that is being re-used for another item in your list-view when scrolling.
Look at this YouTube video and you may get an idea on how to solve your problem. Chet Haase (Google engineer) "DevBytes" series "ListView Animations" :
https://www.youtube.com/watch?v=8MIfSxgsHIs#!
Try to put the R.id.displayRecordRL as part of the viewholder and on the OnClick method call it.
holder.displayAddInfo = (RelativeLayout)clickView.findViewById(R.id.displayRecordRL);
and on the OnclickMethod :
Animation expandAnim = expand(holder.displayAddInfo,
true);
holder.displayAddInfo
.startAnimation(expandAnim);
}