Сетка изображений внутри ScrollView

Я пытаюсь создать экран с текстом и изображениями. Я хочу, чтобы изображения были выложены как grid, как показано ниже, но я хочу, чтобы у них не было никаких функций прокрутки, кроме того, что предусмотрено окружением ScrollView.

Изображение лучше всего проиллюстрирует мой вопрос:

alt text

        

Каков наилучший способ показать сетку разного количества изображений, где grid не имеет функции прокрутки?

Обратите внимание, что отключение функций прокрутки для GridView не работает, так как это просто отключает полосы прокрутки, но не отображает все элементы.

Обновление. На приведенном ниже изображении показано, как это выглядит, когда в GridView отключены полосы прокрутки.

alt text

О мальчик, да, у тебя будут проблемы с этим. Это сводит меня с ума, что ListViews и GridViews не могут быть расширены, чтобы обернуть их детей, потому что мы все знаем, что они имеют более полезные функции в дополнение к их прокрутке и переработке своих детей.

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

В моем собственном приложении я включил ListView в ScrollView. Я сделал это, явно указав, что ListView точно такой же, как и его содержимое. Я делаю это, изменяя параметры макета прямо внутри метода ListView.onMeasure() следующим образом:

 public class ExpandableListView extends ListView { boolean expanded = false; public ExpandableListView(Context context, AttributeSet attrs, int defaultStyle) { super(context, attrs, defaultStyle); } public boolean isExpanded() { return expanded; } public void setExpanded(boolean expanded) { this.expanded = expanded; } @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // HACK! TAKE THAT ANDROID! if (isExpanded()) { // Calculate entire height by providing a very large height hint. // View.MEASURED_SIZE_MASK represents the largest height possible. int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); LayoutParams params = getLayoutParams(); params.height = getMeasuredHeight(); } else { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } } 

Это работает, потому что, когда вы предоставляете ListView в режиме AT_MOST , он создает и измеряет все его дочерние onMeasure для вас, прямо внутри метода onMeasure (я обнаружил это, просмотрев исходный код). Надеемся, что GridView ведет себя одинаково, но если это не так, вы все равно можете сами измерить все содержимое GridView. Но было бы проще, если бы вы могли обмануть GridView, чтобы сделать это за вас.

Теперь вы должны иметь в виду, что это решение полностью отключит переработку вида, что делает GridView настолько эффективным, и все эти ImageViews будут в памяти, даже если они не видны. То же самое касается моего следующего решения.

Другая возможность – вырезать GridView и создать собственный макет. Вы можете расширить либо AbsoluteLayout либо RelativeLayout . Например, если вы расширяете RelativeLayout , вы можете поместить каждое изображение LEFT_OF в предыдущее, отслеживая ширину каждого изображения, пока не выйдете из комнаты в этой строке, а затем запустите следующую строку, поставив первое изображение нового row BELOW самое высокое изображение последней строки. Чтобы получить изображения по горизонтали или по разнесенным столбцам, вам придется пройти еще большую боль. Может быть, AbsoluteLayout лучше. В любом случае, какая-то боль.

Удачи.

GridView с верхним и нижним колонтитулом можно использовать вместо того, чтобы вставлять GridView в ScrollView. Верхний и нижний колонтитулы могут быть любыми: тексты, изображения, списки и т. Д. Существует пример GridView с верхним и нижним колонтитулом: https://github.com/SergeyBurish/HFGridView

У вас есть 2 решения для этого:

  1. Напишите свой собственный макет. Это будет более сложное решение (но может считаться правильным).

  2. Задайте реальную высоту вашего GridView в коде. Например:

   RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) myGridView.getLayoutParams ();
   // lp.setMargins (0, 0, 10, 10);  // если у вас есть границы макета, вы также должны установить их
   lp.height = measureRealHeight (...);
   myGridView.setLayoutParams (LP);

Метод measureRealHeight() должен выглядеть примерно так (надеюсь, я правильно понял):

 private int measureRealHeight(...) { final int screenWidth = getWindowManager().getDefaultDisplay().getWidth(); final double screenDensity = getResources().getDisplayMetrics().density; final int paddingLeft = (int) (X * screenDensity + 0.5f); // where X is your desired padding final int paddingRight = ...; final int horizontalSpacing = (int) (X * screenDensity + 0.5f); // the spacing between your columns final int verticalSpacing = ...; // the spacing between your rows final int columnWidth = (int) (X * screenDensity + 0.5f); final int columnsCount = (screenWidth - paddingLeft - paddingRight + horizontalSpacing - myGridView.getVerticalScrollbarWidth()) / (columnWidth + horizontalSpacing); final int rowsCount = picsCount / columnsCount + (picsCount % columnsCount == 0 ? 0 : 1); return columnWidth * rowsCount + verticalSpacing * (rowsCount - 1); } 

Вышеприведенный код должен работать в Android 1.5+.

Создайте прокручиваемое представление списка следующим образом:

 public class ExpandableListView extends ListView{ public ExpandableListView(Context context) { super(context); } public ExpandableListView(Context context, AttributeSet attrs, int defaultStyle) { super(context, attrs, defaultStyle); } public ExpandableListView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec( Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom); ViewGroup.LayoutParams params = getLayoutParams(); params.height = getMeasuredHeight(); } } 

В вашем файле макета создайте такой элемент:

  

Это должно сработать.

Я нашел способ предоставить GridView фиксированный размер внутри ScrollView и включить прокрутку.

Для этого вам нужно будет реализовать новый class, расширяющий GridView и переопределяющий onTouchEvent () для вызова requestDisallowInterceptTouchEvent (true). Таким образом, родительский вид оставит события касания перехвата сетки.

GridViewScrollable.java:

 package com.example; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.GridView; public class GridViewScrollable extends GridView { public GridViewAdjuntos(Context context) { super(context); } public GridViewAdjuntos(Context context, AttributeSet attrs) { super(context, attrs); } public GridViewAdjuntos(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean onTouchEvent(MotionEvent ev){ // Called when a child does not want this parent and its ancestors to intercept touch events. requestDisallowInterceptTouchEvent(true); return super.onTouchEvent(ev); } } 

Добавьте его в свой макет с требуемыми характеристиками:

    

И просто получите его в своей деятельности и установите адаптер, например ArrayAdapter <> :

 GridViewScrollable mGridView = (GridViewScrollable) findViewById(R.id.myGVS); mGridView.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new String[]{"one", "two", "three", "four", "five"})); 

Я надеюсь, что это поможет =)

Попробуй это

  public static void setGridViewHeightBasedOnChildren(GridView gridView, int columns) { ListAdapter listAdapter = gridView.getAdapter(); if (listAdapter == null) return; int desiredWidth = View.MeasureSpec.makeMeasureSpec(gridView.getWidth(), View.MeasureSpec.UNSPECIFIED); int totalHeight = 0; View view = null; int rows = listAdapter.getCount() / columns; if(listAdapter.getCount() % columns> 0){ rows++; } for (int i = 0; i < rows; i++) { view = listAdapter.getView(i, view, gridView); if (i == 0) view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, LinearLayout.LayoutParams.WRAP_CONTENT)); view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED); totalHeight += view.getMeasuredHeight(); } ViewGroup.LayoutParams params = gridView.getLayoutParams(); params.height = totalHeight + (gridView.getHorizontalSpacing() * rows); gridView.setLayoutParams(params); gridView.requestLayout(); } 

Для GridView с другим представлением внутри Save ScrollView, чтобы сделать все это прокруткой, перейдите по этой ссылке: http://www.londatiga.net/it/programming/android/make-android-listview-gridview-expandable-inside-scrollview / # комментарий-3967742 . Это полезно и сэкономило мое время, которое я просто трачу на 5 минут с этим, когда я никогда об этом не знаю.

Обновить:

Из ссылки я настроил ExpandedGridView:

 public class ExpandedGridView extends GridView { boolean expanded = false; public ExpandedGridView(Context context) { super(context); } public ExpandedGridView(Context context, AttributeSet attrs) { super(context, attrs); } public ExpandedGridView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public boolean isExpanded() { return expanded; } @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // HACK! TAKE THAT ANDROID! if (isExpanded()) { // Calculate entire height by providing a very large height hint. // But do not use the highest 2 bits of this integer; those are // reserved for the MeasureSpec mode. int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); ViewGroup.LayoutParams params = getLayoutParams(); params.height = getMeasuredHeight(); } else { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } public void setExpanded(boolean expanded) { this.expanded = expanded; } } 
  • Темный прозрачный слой над QMainWindow в Qt
  • Форматирование даты MM / DD / YYYY в текстовом поле в VBA
  • Как отобразить более трех уровней расширяемого вида списка?
  • Почему этот код Parallel.ForEach заморозит программу?
  • Измените сторону, которую текст появится на переключателе
  • Создание надежного масштабируемого графического интерфейса Swing Chess
  • Дизайн пользовательского интерфейса Blackberry - настраиваемый пользовательский интерфейс?
  • Добавьте n прямоугольников в canvas с MVVM в WPF
  • Java swing JComponent "размер"
  • Обновление пользовательского интерфейса из streamа
  • Qt сигнализирует по streamам, один - stream GUI?
  • Interesting Posts

    Укажите пароль, который не связан с моей учетной записью Microsoft?

    Компьютер не загружается, показывает ошибку PXE и ​​/ или «операционная система не найдена», «нет загрузочного устройства», «вставить загрузочный носитель» или другую аналогичную ошибку

    Как передать права администратора приложения на C #? файл манифеста

    Утечка ресурсов: «in» никогда не закрывается

    прием HTTPS-соединений с самозаверяющими сертификатами

    Как вы разбиваете JVM?

    где я должен разместить файлы сценариев js в приложении mvc, чтобы jquery работал хорошо?

    Почему вызов getWidth () в представлении в onResume () возвращает 0?

    Лучший способ читать структурированные двоичные файлы с помощью Java

    Ярлык «или-присваивание» (| =) в Java

    Быстрая и компактная сериализация объектов в .NET.

    g ++ не показывает «неиспользуемое» предупреждение

    Можно ли изменить цвет текста в строке на несколько цветов в Java?

    Как хранить DNS-кеш в случае отказа DNS-сервера?

    Перегрузка конструктора в TypeScript

    Давайте будем гением компьютера.