Android Swipe меню в элементе списка не может обрабатывать изменения родительской ширины - PullRequest
0 голосов
/ 24 сентября 2018

Я пытаюсь создать меню прокрутки для своих предметов в программе повторного просмотра и в итоге реализовал библиотеку: https://github.com/chthai64/SwipeRevealLayout

Сначала, посмотрев ее, я подумал, что она работает.Но по какой-то причине он не меняет / не измеряет / не корректирует правильную ширину элемента при изменении родительского представления / макета (структура кадра для содержащего фрагмента).

Элемент просто сохраняет ту же ширину, которая либослишком широкий или слишком короткий, в зависимости от того, каким образом масштабируется родительское представление.

Я включил метод onMeasure из пользовательского представления "SwipeRevealLayout" из библиотеки.

@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);
    }

Я нашелчасть решения где-то еще, где все содержимое элемента было правильно масштабировано.Я заменил весь код в onMeasure с кодом ниже.Однако, у этого решения был побочный эффект, когда элемент стирался полностью с экрана, а не останавливался непосредственно перед кнопками меню смахивания.

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));
        }

1 Ответ

0 голосов
/ 24 сентября 2018

Не берите в голову :) Я наконец решил это, управляя шириной элементов в OnMeasure.Это прекрасно работает для меня.Может быть, кто-то еще может использовать это.То, что я сделал, было проверить, шире ли первый дочерний элемент, чем я позволяю ему быть (шире, чем родительское представление), и установил для него максимальную ширину, если она есть.если другие дочерние представления (например, для элемента в списке) имеют ширину / измеренную ширину, которая НЕ равна ширине родительских представлений, я устанавливаю ширину дочерних представлений в это значение.

Вот верхняя часть onMeasure, который я немного изменил.

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if (getChildCount() < 2) {
        throw new RuntimeException("Layout must have two children");
    }
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    final LayoutParams params = getLayoutParams();

    final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    final int heightMode = MeasureSpec.getMode(heightMeasureSpec);

    int maxWidth        = getMeasuredWidth();
    int desiredWidth    = 0;
    int desiredHeight   = 0;

    // first find the largest child
    for (int i = 0; i < getChildCount(); i++) {
        final View child = getChildAt(i);
        if (i == 0 && (child.getWidth() > maxWidth || child.getMeasuredWidth() > maxWidth)
            || i > 0 && (child.getWidth() != maxWidth || child.getMeasuredWidth() != maxWidth)) {
            LayoutParams lm = child.getLayoutParams();
            lm.width        = maxWidth;
            child.setLayoutParams(lm);
        }
        measureChild(child, widthMeasureSpec, heightMeasureSpec);
        desiredWidth = Math.max(child.getMeasuredWidth(), desiredWidth);
        desiredHeight = Math.max(child.getMeasuredHeight(), desiredHeight);
    }

...
...