Android NestedScrollView имеет неправильный размер после app:layout_behavior

Поскольку Google опубликовал библиотеку поддержки дизайна для Android, есть много приятных вещей, которые можно сделать без реализации собственного кода. Пока я тестировал пользовательские представления в этой библиотеке, я обнаружил худшую вещь, и я не знал, является ли это ошибкой или нет.

Я нашел проект cheesesquare на github. В activity_detail.xml(файл макета) есть 3 CardView внутри NestedScrollView. Если вы удалите 2 из них, вы увидите, что NestedScrollView не имеет полного размера родителя (match_parent). NestedScrollView привязан к нижней части родительского представления. http://i.stack.imgur.com/BXl7w.png

NestedScrollView получает свой полный размер, когда я удаляю app:layout_behavior="@string/appbar_scrolling_view_behavior".

Но когда я удаляю поведение макета, панель инструментов не рушится.

Есть ли какое-нибудь решение для этого? Пример файла макета можно найти здесь: https://github.com/Smove/cheesesquare/blob/stackoverflow/app/src/main/res/layout/activity_detail.xml

Вы можете собрать apk-файл cheesesquare из моей ветки github stackoverflow


person Jan    schedule 03.06.2015    source источник
comment
У меня такая же проблема. Это выглядит особенно плохо, если вы используете тень в верхней части NestedScrollView.   -  person Jimeux    schedule 03.06.2015
comment
Здесь та же проблема! Если содержимое не больше, чем прокрутка, оно выровнено по низу и ведет себя очень странно :( RecyclerView работает нормально (также, если есть только 1 элемент)..   -  person Philip Giuliani    schedule 04.06.2015
comment
android:layout_gravity="fill_vertical" должен работать, но я надеюсь, что в следующем релизе это исправят.   -  person natario    schedule 12.06.2015
comment
Я тоже использую библиотеку, и кажется, что с ней все еще много проблем с макетом.   -  person Tommy Chan    schedule 18.06.2015


Ответы (5)


У меня была эта проблема, и я исправил добавление:

android:layout_gravity="fill_vertical"

в NestedScrollView. Затем он начинает вести себя правильно, как я объяснил здесь. Конечно, для NestedScrollView нужен какой-то дочерний элемент (т. е. он не должен быть пустым), иначе панель инструментов не рухнет.

Обновлять

Хотя это работает хорошо с небольшим содержанием, я заметил, что у него есть некоторые проблемы с отображением более длинного содержимого, например. как полный activity_detail.xml выше. Проблема в том, что вы не можете прокрутить до самой нижней части контента — он недоступен внизу.

Из моих тестов я обнаружил, что отсутствующая часть такая же большая, как свернутая панель инструментов (по крайней мере, мне так кажется). Чтобы решить эту проблему и иметь надежное решение как для малого, так и для большого содержимого, вы должны добавить layout_marginBottom в ScrollView, чтобы он измерялся и освобождал отсутствующую нижнюю часть. Таким образом:

android:layout_gravity="fill_vertical"
android:layout_marginBottom="?attr/actionBarSize"

или любой другой размер, который вы указали для Toolbar.

Но до сих пор

Прокрутка с небольшим содержимым с помощью этого решения, даже если содержимое правильно выровнено вверху, на самом деле не так гладко, как прокрутка с большим содержимым. Буду пользоваться, пока не придет исправление библиотеки.

Обновление2

Похоже, это было исправлено в v22.2.1.

person natario    schedule 12.06.2015
comment
Это решение отлично работает! Пользуюсь пока не выйдет фикс от гугла - person Jan; 17.06.2015
comment
Я пробовал почти все решения, но это было единственное, что сработало для меня. Спасибо..! - person Tushar Kathuria; 15.01.2016
comment
Отличное решение! Я люблю это сообщество за те мелочи, которых нам не хватает, независимо от того, на каком мы уровне программиста. Благодарю вас! - person sud007; 29.07.2016
comment
Вам все еще нужно использовать это исправление даже после обновления? - person Mike Purcell; 18.10.2016
comment
@ Майк, нет, библиотека дизайна теперь начинает казаться надежной. - person natario; 18.10.2016
comment
Я все еще сталкиваюсь с проблемой в некоторых случаях. Моя версия библиотеки поддержки — 23.4.0. Кто-нибудь может мне помочь, пожалуйста! - person Nigam Patro; 17.05.2017
comment
Добавьте android:layout_marginBottom=?attr/actionBarSize в родительский макет, чтобы не повторять код - person Latief Anwar; 05.09.2019

используя ответ @natario. Если вы вместо этого установите отступ для ребенка (в моем случае LinearLayout), он будет выглядеть лучше:

<androidx.core.widget.NestedScrollView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_behavior="@string/appbar_scrolling_view_behavior"
                android:layout_gravity="fill_vertical">
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:paddingBottom="?attr/actionBarSize">
                <!--Rest of the code-->

Или в Котлине вы можете сделать что-то вроде этого:

 coordinator.doOnLayout {
        nestedScrollView.minimumHeight = resources.displayMetrics.heightPixels - with(TypedValue().also {theme.resolveAttribute(android.R.attr.actionBarSize, it, true)}) {
            TypedValue.complexToDimensionPixelSize(data, resources.displayMetrics)}
    }
person mhmt93t    schedule 16.08.2020

добавить android:minHeight="?attr/actionBarSize" к CollapsingToolbarLayout

person H X    schedule 17.04.2021

Временное решение

Прежде чем показывать свой NestedScrollView и после привязки данных к содержимому NestedScrollView, я вызываю метод fullScroll(int direction) моего экземпляра NestedScrollView с направлением View.FOCUS_UP в качестве аргумента.

Пример кода для фрагмента:

NestedScrollView scrollView = (NestedScrollView) getActivity().findViewById(R.id.scroll_view); scrollView.fullScroll(View.FOCUS_UP);

person Jérôme    schedule 08.07.2015

используйте RecyclerView вместо NestedScrollView, исправьте эту ошибку, установите количество элементов 1, чтобы ViewHolder вернул ваш реальный контентView;

мой код:

    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);

    recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
    // 添加分割线
    recyclerView.addItemDecoration(new DividerItemDecoration(getApplicationContext()));

    recyclerView.setAdapter(new Adapter<ViewHolder>() {

        @Override
        public int getItemCount() {
            return 1;
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int arg1) {
            WebView view = (WebView) holder.itemView;
            view.getSettings().setJavaScriptEnabled(true);
            view.loadUrl("http://www.baidu.com");
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup arg0, int arg1) {
            return new ViewHolder(inflater.inflate(R.layout.webview, arg0, false)) {
            };
        }
    });
person 张小凡    schedule 12.06.2015