I am trying to create a swipe menu for my items in recyclerview and ended up implemeting the library: https://github.com/chthai64/SwipeRevealLayout
At first look at it after implementing it, I thought it was working. But for some reason, it does not change/measure/layout the correct width of the item when the parent view/layout (framelayout for containing fragment) changes.
The item simply keep the same width, which is either too wide or too short, depending of which way the parent view scales.
I have included the onMeasure method from the custom view "SwipeRevealLayout" from the library.
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (getChildCount() < 2) {
throw new RuntimeException("Layout must have two children");
}
final LayoutParams params = getLayoutParams();
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int desiredWidth = 0;
int desiredHeight = 0;
// first find the largest child
for (int i = 0; i < getChildCount(); i++) {
final View child = getChildAt(i);
measureChild(child, widthMeasureSpec, heightMeasureSpec);
desiredWidth = Math.max(child.getMeasuredWidth(), desiredWidth);
desiredHeight = Math.max(child.getMeasuredHeight(), desiredHeight);
}
// create new measure spec using the largest child width
widthMeasureSpec = MeasureSpec.makeMeasureSpec(desiredWidth, widthMode);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(desiredHeight, heightMode);
final int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
final int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
for (int i = 0; i < getChildCount(); i++) {
final View child = getChildAt(i);
final LayoutParams childParams = child.getLayoutParams();
if (childParams != null) {
if (childParams.height == LayoutParams.MATCH_PARENT) {
child.setMinimumHeight(measuredHeight);
}
if (childParams.width == LayoutParams.MATCH_PARENT) {
child.setMinimumWidth(measuredWidth);
}
}
measureChild(child, widthMeasureSpec, heightMeasureSpec);
desiredWidth = Math.max(child.getMeasuredWidth(), desiredWidth);
desiredHeight = Math.max(child.getMeasuredHeight(), desiredHeight);
}
// taking accounts of padding
desiredWidth += getPaddingLeft() + getPaddingRight();
desiredHeight += getPaddingTop() + getPaddingBottom();
// adjust desired width
if (widthMode == MeasureSpec.EXACTLY) {
desiredWidth = measuredWidth;
} else {
if (params.width == LayoutParams.MATCH_PARENT) {
desiredWidth = measuredWidth;
}
if (widthMode == MeasureSpec.AT_MOST) {
desiredWidth = (desiredWidth > measuredWidth)? measuredWidth : desiredWidth;
}
}
// adjust desired height
if (heightMode == MeasureSpec.EXACTLY) {
desiredHeight = measuredHeight;
} else {
if (params.height == LayoutParams.MATCH_PARENT) {
desiredHeight = measuredHeight;
}
if (heightMode == MeasureSpec.AT_MOST) {
desiredHeight = (desiredHeight > measuredHeight)? measuredHeight : desiredHeight;
}
}
setMeasuredDimension(desiredWidth, desiredHeight);
}
I found a part of the solution somewhere else, where all of the content of the item was scaled correctly. I replaced all the code in onMeasure withe the code below. However, this solution had a side effect, where the item is wiped all the way out of the screen instead of stopping just before the buttons of the swipe menu.
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth() / 2);
// this is required because the children keep the super class calculated dimensions (which will not work with the new MyFrameLayout sizes)
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View v = getChildAt(i);
v.measure(MeasureSpec.makeMeasureSpec(getMeasuredWidth(),
MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
getMeasuredHeight(), MeasureSpec.EXACTLY));
}