макет
Я пытаюсь сделать такую раскладку, правая часть (желтая) всегда должна быть доступна. Я пытаюсь использовать drawerlayout, но не могу удалить сетку. Блок scim в правой части.
Я собирался использовать de SlidingPanelLayout, но он устарел. Итак, я создаю свой собственный макет.
public class LeftSlidingLayout extends FrameLayout
{
private static final int LEFT = 0;
private static final int RIGHT = 1;
private static final int DEFAULT_ALWAYS_SWIPEABLE_WIDTH = 35;
private static final int SWIPE_THRESHOLD = 100;
private static final int SWIPE_VELOCITY_THRESHOLD = 100;
private static final int MAX_ANIMATION_DURATION = 500;
public static final int EXCLUSION_ZONE_HEIGHT = 100;
private int _alwaysSwipeableWidth;
private int _xDelta;
private int _xDown;
private Rect _bottomExlusionSwipeableZone;
public LeftSlidingLayout(final Context context)
{
this(context, null);
}
public LeftSlidingLayout(final Context context, final AttributeSet attrs)
{
this(context, attrs, 0);
}
public LeftSlidingLayout(final Context context, final AttributeSet attrs, final int defStyleAttr)
{
this(context, attrs, defStyleAttr, 0);
}
public LeftSlidingLayout(final Context context, final AttributeSet attrs, final int defStyleAttr, final int defStyleRes)
{
super(context, attrs, defStyleAttr, defStyleRes);
final TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.LeftSlidingLayout);
setAlwaysSwipeableWidth(attributes.getDimensionPixelOffset(R.styleable.LeftSlidingLayout_always_swipeable_width, DEFAULT_ALWAYS_SWIPEABLE_WIDTH));
attributes.recycle();
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec)
{
final int adjustedWidth = widthMeasureSpec + getAlwaysSwipeableWidth();
super.onMeasure(adjustedWidth, heightMeasureSpec);
}
private Rect getBottomExlusionSwipeableZone()
{
return new Rect(getWidth() - getAlwaysSwipeableWidth(),
getHeight() - EXCLUSION_ZONE_HEIGHT,
getWidth(),
getHeight());
}
public void setAlwaysSwipeableWidth(final int alwaysSwipeableWidth)
{
_alwaysSwipeableWidth = alwaysSwipeableWidth;
setPadding(getPaddingLeft(),
getPaddingTop(),
getPaddingRight() + _alwaysSwipeableWidth,
getPaddingBottom());
}
public int getAlwaysSwipeableWidth()
{
return _alwaysSwipeableWidth;
}
@Override
public boolean onTouchEvent(final MotionEvent event)
{
if(isNotSwipeable(event))
return false;
final int X = (int) event.getRawX();
final long duration = event.getEventTime() - event.getDownTime();
switch(event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
final ViewGroup.MarginLayoutParams lParams = (ViewGroup.MarginLayoutParams) getLayoutParams();
_xDelta = X - lParams.leftMargin;
_xDown = X;
break;
case MotionEvent.ACTION_UP:
animateAdjustment(_xDown - X, duration);
break;
case MotionEvent.ACTION_MOVE:
slideLeft(formatWithingBound(X - _xDelta, -getWidth() + getAlwaysSwipeableWidth(), 0));
break;
default:
//Do nothing
}
((View) getParent()).invalidate();
return true;
}
private boolean isNotSwipeable(final MotionEvent event)
{
return !isOpen() && getBottomExlusionSwipeableZone().contains((int) event.getX(), (int) event.getY());
}
private void animateAdjustment(final int swipedPixelDistance, final float durationInMs)
{
final float velocityInMsX = swipedPixelDistance / durationInMs;
if(velocityInMsX == 0 || swipedPixelDistance == 0)
return;
final int direction;
if(Math.abs(swipedPixelDistance) > SWIPE_THRESHOLD && Math.abs(velocityInMsX) > SWIPE_VELOCITY_THRESHOLD)
{
direction = swipedPixelDistance < 0 ? LEFT : RIGHT;
}
else
{
direction = swipedPixelDistance < 0 ? RIGHT : LEFT;
}
animateCurrentView(direction == LEFT ? -getWidth() + getAlwaysSwipeableWidth() : 0, velocityInMsX);
}
private void animateCurrentView(final int endMargin, final float speed)
{
final ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();
final int startMargin = layoutParams.leftMargin;
final Animation animation = new Animation()
{
@Override
protected void applyTransformation(final float interpolatedTime, final Transformation transformation)
{
slideLeft(startMargin + (int) ((endMargin - startMargin) * interpolatedTime));
}
};
final long duration = calculateDuration(startMargin, endMargin, speed);
animation.setDuration(Math.min(duration, MAX_ANIMATION_DURATION));
startAnimation(animation);
}
private void slideLeft(final int leftMargin)
{
final ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();
layoutParams.leftMargin = leftMargin;
setLayoutParams(layoutParams);
}
private long calculateDuration(final int startMargin, final int endMargin, final float speed)
{
return Math.abs((long) ((endMargin - startMargin) / speed));
}
private int formatWithingBound(final int valueToFormat, final int minBound, final int maxBound)
{
return Math.max(Math.min(valueToFormat, maxBound), minBound);
}
public void open()
{
animateCurrentView(0, 1);
}
public void closes()
{
animateCurrentView(-getWidth() + getAlwaysSwipeableWidth(), 1);
}
public boolean isOpen()
{
final ViewGroup.MarginLayoutParams layoutParams = (MarginLayoutParams) getLayoutParams();
return layoutParams.leftMargin == 0;
}
public interface SlidingListener
{
void onLeftMarginChanged(final int leftMargin);
}
}
Если recyclerview пуст, все работает отлично, но невозможно сдвинуть представление, когда есть элементы.
Есть ли способ делегировать смахивание от ресайклервью? Или удалить ским де DrawerLayout?