Левый скользящий макет с повторным просмотром - PullRequest
1 голос
/ 14 июля 2020

макет

Я пытаюсь сделать такую ​​раскладку, правая часть (желтая) всегда должна быть доступна. Я пытаюсь использовать 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?

1 Ответ

0 голосов
/ 14 июля 2020

Наконец, я проделал некрасивый трюк, я расширил DrawerLayout и в computeScroll я сделал некоторое отражение

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...