Closed nathanielwolf closed 11 years ago
Yes indeed that is a problem currently. Do you have an idea how to solve this?
I solved this problem, and the problem of randomly expanded views as result of view recycling in the Adapter.
public class MyListAdapter extends ArrayAdapter<MyObject>
int[] mCollapsableHeights;
boolean[] mOpenned;
public WhyPuursAdapter(Context context,
List<WhyPuur> objects) {
super(context, 0, objects);
mCollapsableHeights = new int[objects.size()];
mOpenned = new boolean[objects.size()];
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final View view = convertView;
final View collapsable = view.findViewById(R.id.row_whypure_collapsable);
//measure only once - hide expanded views by returning false in onPreDraw()
if(mCollapsableHeights[position] == 0){
view.getViewTreeObserver().addOnPreDrawListener(
new OnPreDrawListener(){
@Override
public boolean onPreDraw() {
view.getViewTreeObserver().removeOnPreDrawListener(this);
mTextHeights[position] = collapsable.getHeight();
setCollapsedView(collapsable, position);
return false;
}
});
} else
setCollapsedView(collapsable, position);
view.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
mOpenned[position] = !mOpenned[position];
ExpandAnimation newAnim = new ExpandAnimation(collapsable, 300);
collapsable.startAnimation(newAnim);
}
});
return view;
}
/*
* Set visibility of collapsed view
*/
public void setCollapsedView(View collapsable, int position){
final LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)collapsable.getLayoutParams();
if(!mOpenned[position] ){
collapsable.setVisibility(View.GONE);
params.bottomMargin = 0-mTextHeights[position];
}else{
collapsable.setVisibility(View.VISIBLE);
params.bottomMargin = 0;
}
collapsable.setLayoutParams(params);
}
}
I solved it like this:
public ExpandCollapseAnimation(View view, int duration, int type) {
setDuration(duration);
mAnimatedView = view;
//Force Measure with unspecified specs
mAnimatedView.measure(0, 0);
//Get Measured Height
mEndHeight = mAnimatedView.getMeasuredHeight();
//mEndHeight = mAnimatedView.getLayoutParams().height;
mLayoutParams = ((LinearLayout.LayoutParams) view.getLayoutParams());
mType = type;
if(mType == EXPAND) {
mLayoutParams.bottomMargin = -mEndHeight;
} else {
mLayoutParams.bottomMargin = 0;
}
view.setVisibility(View.VISIBLE);
}
Hey @nathanielwolf thanks, thats a smart solution. B.t.w. the problem randomly expanded views is just solved in the current master. So that should be fixed now.
For now i'm going to test the solution by @gorilla-maguila
@gorilla-maguila your solution does not have the correct measured height for the /sample project. Hmmz i'm going to look for the proper generic solution.
what's giving you getMeasuredHeight() ? In my project works great the above solution.
Issue #6 was related.
I think I tackled it. I solved it by using the OnPreDrawListener and setCollapseView method as @nathanielwolf suggested, smart move btw! However I also updated the ExpandCollapseAnimation to use getHeight instead of the LinearLayout height.
B.t.w. the only thing that I dislike is the Map<Integer, Integer> that now has an entry for every item in the list. If the list grows to 1000 items, it means a lot of extra memory is needed. But I don't see a nice solution for you.
@nathanielwolf @gorilla-maguila @grivos could you all confirm that this commit fixes the problem?
Thanks in Advance!! Coudn't do it without your ideas!
Looks good. Nice work!
However, There is a problem if the data set is changed and the current state is invalid. You might want to make WrapperListAdapterImpl extend BaseAdapter, and then in AbstractSlideExpandableListAdapter - override notifyDataSetChanged() and reset the state there.
I thought of that problem too. Wanted to solve it with:
registerDataSetObserver(new DataSetObserver() { ... }
However If a user of the library would set its own datasetobserver it would break my listener. Since only one listener is allowed.
I think your solution is the correct one. It should also override notifyDataSetInvalidated() in that case.
Will look at this later.
Created issue #11, closed this one.
This does not function when using wrap_content for the layout_height of the collapsable view. The animator cannot get a proper value for mEndHeight because the view has not been laid out yet.