Остановить Android от размещения всех моих просмотров - PullRequest
9 голосов
/ 26 марта 2012

В настоящее время я занимаюсь разработкой приложения для планшета, в котором интенсивно используется виджет ViewPager. Я также получил несколько экранов одновременно на экране.

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

Мой вопрос сейчас таков: есть ли возможность реализовать Frame вокруг ViewPager, который выполняет начальную компоновку, а затем не распространяет макеты - запрашивает иерархию представлений , поскольку я знаю, что после начальной компоновки рамка остается того же размера и не изменится.

Я придумал следующий кадр, но он работает не совсем хорошо, потому что он не работает 100% времени.

public class MyFrame extends FrameLayout
{
    // VARIABLE CONTROLLING THE DISPATCH OF THE LAYOUT
    // REQUEST UP THE VIEW HIERARCHY
    private boolean doLayout = true;

    public MyFrame(Context context)
    {
        super(context);
        doLayout = true;
    }

    @Override
    public void requestLayout()
    {
        if (doLayout) // DO THE LAYOUT REQUEST UP TO THE TOP
            super.requestLayout();
        else
        {
            // JUST MEASURE MYSELF AND MY CHILDREN
            measure(MeasureSpec.getMode(MeasureSpec.AT_MOST),
            MeasureSpec.getMode(MeasureSpec.AT_MOST));
            layout(getLeft(), getTop(), getRight(), getBottom());
        }
        doLayout = false;
    }
}

Спасибо за любой совет!

Ответы [ 2 ]

6 голосов
/ 03 декабря 2013

Я знаю, что вопрос немного устарел, но мой ответ мог бы помочь кому-то еще, поскольку ваш вопрос и ответ Колина помогли мне.

У меня точно такая же проблема, как и у вас. И есть два решения для этого. Во-первых, вам нужно убедиться, что у вашего ViewPager для * layout_width * и * layout_height * установлено значение * match_parent *, и что иерархия представлений организована таким образом, что Android не придет к выводу, что ему нужно изменить макет любого родительских макетов ViewPager. Например, предположим, что у вас есть RelativeLayout с двумя представлениями фиксированных размеров один под другим и ViewPager под вторым представлением. В этом случае любое изменение ViewPager будет распространяться на родительский макет. Однако, если вы поместите эти два представления фиксированного размера и ViewPager в LinearLayout, этого не произойдет, запрос макета не будет распространен за пределы ViewPager. Более того, запрос макета на одной странице ViewPager также не будет распространяться на другие страницы.

Второе решение (на самом деле это скорее вторая часть решения) - это ваш FrameLayout, но измененный так:

public class LayoutStopperFrameLayout extends FrameLayout {

    private boolean doLayout;

    public LayoutStopperFrameLayout(Context context) {
        super(context);
        doLayout = true;
    }

    public LayoutStopperFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        doLayout = true;
    }

    public LayoutStopperFrameLayout(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
        doLayout = true;
    }

    public void setPropagateRequestLayout(boolean doLayout) {
        this.doLayout = doLayout;
    }

    @Override
    public void requestLayout() {
        if (doLayout) {
            // DO THE LAYOUT REQUEST UP TO THE TOP
            super.requestLayout();
        }
    }
}

В моем приложении я вызываю setPropagateRequestLayout () в методах Fragment onStart и onStop, чтобы включить или выключить запросы макета соответственно.

1 голос
/ 11 апреля 2012

Я действительно хотел бы сказать вам, что есть лучший способ, но я не думаю, что есть. Если ViewPager фактически добавляет / удаляет представления, ваша компоновка будет постоянно удаляться, даже если это не так, это может быть. Это ленивое предположение о том, что содержимое может измениться (что приведет к недействительности в сторону увеличения), и мы можем использовать сложные программы для удаления некоторых из этих предположений.

Если вы можете быть уверены, что границы FrameLayout никогда не изменятся, перезапись requestLayout не повредит вообще.

...