package com.beloo.widget.chipslayoutmanager.layouter;
import android.support.annotation.CallSuper;
import android.support.v7.widget.RecyclerView;
public class MeasureSupporter extends RecyclerView.AdapterDataObserver implements IMeasureSupporter {
private RecyclerView.LayoutManager lm;
private boolean isAfterRemoving;
private int measuredWidth;
private int measuredHeight;
private boolean isRegistered;
/**
* width of RecyclerView before removing item
*/
private Integer beforeRemovingWidth = null;
/**
* width which we receive after {@link RecyclerView.LayoutManager#onLayoutChildren} method finished.
* Contains correct width after auto-measuring
*/
private int autoMeasureWidth = 0;
/**
* height of RecyclerView before removing item
*/
private Integer beforeRemovingHeight = null;
/**
* height which we receive after {@link RecyclerView.LayoutManager#onLayoutChildren} method finished.
* Contains correct height after auto-measuring
*/
private int autoMeasureHeight = 0;
public MeasureSupporter(RecyclerView.LayoutManager lm) {
this.lm = lm;
}
@Override
public void onSizeChanged() {
autoMeasureWidth = lm.getWidth();
autoMeasureHeight = lm.getHeight();
}
boolean isAfterRemoving() {
return isAfterRemoving;
}
@Override
public int getMeasuredWidth() {
return measuredWidth;
}
private void setMeasuredWidth(int measuredWidth) {
this.measuredWidth = measuredWidth;
}
@Override
public int getMeasuredHeight() {
return measuredHeight;
}
@Override
public boolean isRegistered() {
return isRegistered;
}
@Override
public void setRegistered(boolean isRegistered) {
this.isRegistered = isRegistered;
}
private void setMeasuredHeight(int measuredHeight) {
this.measuredHeight = measuredHeight;
}
@Override
@CallSuper
public void measure(int autoWidth, int autoHeight) {
if (isAfterRemoving()) {
setMeasuredWidth(Math.max(autoWidth, beforeRemovingWidth));
setMeasuredHeight(Math.max(autoHeight, beforeRemovingHeight));
} else {
setMeasuredWidth(autoWidth);
setMeasuredHeight(autoHeight);
}
}
@Override
public void onItemsRemoved(final RecyclerView recyclerView){
//subscribe to next animations tick
lm.postOnAnimation(new Runnable() {
private void onFinished() {
//when removing animation finished return auto-measuring back
isAfterRemoving = false;
// and process measure again
lm.requestLayout();
}
@Override
public void run() {
if (recyclerView.getItemAnimator() != null) {
//listen removing animation
recyclerView.getItemAnimator().isRunning(new RecyclerView.ItemAnimator.ItemAnimatorFinishedListener() {
@Override
public void onAnimationsFinished() {
onFinished();
}
});
} else {
onFinished();
}
}
});
}
@Override
@CallSuper
public void onItemRangeRemoved(int positionStart, int itemCount) {
super.onItemRangeRemoved(positionStart, itemCount);
/** we detected removing event, so should process measuring manually
* @see <a href="http://stackoverflow.com/questions/40242011/custom-recyclerviews-layoutmanager-automeasuring-after-animation-finished-on-i">Stack Overflow issue</a>
*/
isAfterRemoving = true;
beforeRemovingWidth = autoMeasureWidth;
beforeRemovingHeight = autoMeasureHeight;
}
}