Создание элементов таблицы GridView

Я хотел бы, чтобы элементы моего GridView были квадратными. Есть 2 столбца, а ширина элементов – fill_parent (например, они берут как можно больше горизонтального пространства. Элементы представляют собой пользовательские виды.

Как сделать высоту элементов равными их переменной ширине?

Существует более простое решение, когда столбцы GridView растянуты. Просто переопределите onMeasure для макета элемента GridView с помощью …

 @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, widthMeasureSpec); } 

Или, если вы хотите расширить представление, просто выполните что-то действительно простое:

 public class SquareImageView extends ImageView { public SquareImageView(final Context context) { super(context); } public SquareImageView(final Context context, final AttributeSet attrs) { super(context, attrs); } public SquareImageView(final Context context, final AttributeSet attrs, final int defStyle) { super(context, attrs, defStyle); } @Override protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { final int width = getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec); setMeasuredDimension(width, width); } @Override protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) { super.onSizeChanged(w, w, oldw, oldh); } } 

Стоит отметить, что super.onMeasure() не требуется. onMeasured – это то, что вы должны вызвать setMeasuredDimension .

Я не уверен, что это возможно с текущими виджетами. Лучше всего поставить свой пользовательский вид в пользовательский «SquareView». Этот вид может содержать только одно дочернее представление и заставлять высоту равняться ширине при вызове метода onLayout.

Я никогда не пытался сделать что-то подобное, но я думаю, что это не должно быть слишком сложно. Альтернативным (и, возможно, чуть более простым) решением может быть подclass вашего корневого макета настраиваемого представления (например, если это LinearLayout, сделать SquareLinearLayout) и использовать его вместо контейнера.

edit: Вот базовая реализация, которая, кажется, работает на меня:

 package com.mantano.widget; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; public class SquareView extends ViewGroup { public SquareView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onLayout(boolean changed, int l, int u, int r, int d) { getChildAt(0).layout(0, 0, rl, du); // Layout with max size } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { View child = getChildAt(0); child.measure(widthMeasureSpec, widthMeasureSpec); int width = resolveSize(child.getMeasuredWidth(), widthMeasureSpec); child.measure(width, width); // 2nd pass with the correct size setMeasuredDimension(width, width); } } 

Он разработан, чтобы иметь уникального ребенка, но я просто проигнорировал все проверки для простоты. Основная идея состоит в том, чтобы измерить дочерний элемент с параметрами width / height, заданными GridView (в моем случае он использует numColumns = 4 для вычисления ширины), а затем выполняет второй проход с конечными размерами с высотой = ширина. .. Макет – это просто макет, в котором макет уникального дочернего элемента (0, 0) с нужными размерами (справа налево, вниз).

И вот XML, используемый для элементов GridView:

       

Я использовал LinearLayout внутри SquareView, чтобы управлять всеми возможностями гравитации, полями и т. Д.

Я не уверен, насколько хорошо (или плохо) этот виджет будет реагировать на изменения ориентации и измерения, но он работает правильно.

Это становится довольно легко получить квадрат элемента сетки.

В вашем методе GetView вашего сетевого адаптера просто выполните:

 @Override public View getView(int position, View convertView, ViewGroup parent) { GridView grid = (GridView)parent; int size = grid.getRequestedColumnWidth(); TextView text = new TextView(getContext()); text.setLayoutParams(new GridView.LayoutParams(size, size)); // Whatever else you need to set on your view return text; } 

Я не знаю, если это лучший способ, но я делаю это, чтобы сделать мой пользовательский вид переопределить onSizeChanged таким образом:

 @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); if (getLayoutParams() != null && w != h) { getLayoutParams().height = w; setLayoutParams(getLayoutParams()); } } 

Я использую этот пользовательский вид внутри LinearLayout и GridView, и в обоих он показывает квадрат!

Это сработало для меня!

Если вы похожи на меня, и вы не можете использовать getRequestedColumnWidth (), потому что ваш minSdk ниже 16, я предлагаю эту опцию.

  1. в вашем fragmentе:

    DisplayMetrics dm = new DisplayMetrics(); getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm); int size = dm.widthPixels / nbColumns; CustomAdapter adapter = new CustomAdapter(list, size, getActivity());

  2. в вашем адаптере (в getView (int position, View convertView, родитель ViewGroup))

    v.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, size));

  3. fragment.xml:

  4. custom_item.xml: (например)

Надеюсь, это поможет кому-то!

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

если вы используете auto_fit тогда будет немного сложно получить кол-во столбцов (метода getColumnCount () нет, btw этот вопрос должен как-то помочь вам.

это код, который я использую в getView(...) адаптера с фиксированным числом столбцов:

  item_side = mFragment.holder.grid.getWidth() / N_COL; v.getLayoutParams().height = item_side; v.getLayoutParams().width = item_side; 

Это то, что я делаю, чтобы показать квадратные ячейки в GridView. Я не уверен, хотите ли вы квадратные ячейки или что-то еще.

 GridView grid = new GridView( this ); grid.setColumnWidth( UIScheme.cellSize ); grid.setVerticalSpacing( UIScheme.gap ); grid.setStretchMode( GridView.STRETCH_COLUMN_WIDTH ); grid.setNumColumns( GridView.AUTO_FIT ); 

И затем представление, которое я создаю для каждой ячейки, я должен сделать для этого следующее:

 cell.setLayoutParams( new GridView.LayoutParams(iconSize, iconSize) ); 

Пытаться

  

Вы также можете играть в других режимах

На основании ответа СтиваБоркмана , который является API 16+:

 @Override public View getView(int position, View convertView, ViewGroup parent) { GridView grid = (GridView)parent; int size = grid.getColumnWidth(); if (convertView == null){ convertView = LayoutInflater.from(context).inflate(R.layout.your_item, null); convertView.setLayoutParams(new GridView.LayoutParams(size, size)); } //Modify your convertView here return convertView; } 

В соответствии с ответом @ Gregory мне пришлось обернуть изображение в LinearLayout, чтобы GridView не манипулировал своими размерами из квадрата. Обратите внимание, что внешний LinearLayout должен быть установлен так, чтобы иметь размер изображения, а ширина столбца GridView должна быть шириной изображения PLUS любого поля. Например:

      

и GridView:

   

В вашей деятельности

  DisplayMetrics displaymetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); valX = displaymetrics.widthPixels/columns_number; 

в CustomAdapter GridView

  v.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, YourActivity.valX)); 
  • Как я могу сделать свои пользовательские объекты Parcelable?
  • почему MenuItemCompat.getActionProvider возвращает значение null?
  • получение нулевого идентификатора устройства при регистрации до gcm
  • Как получить текст в значке ActionBar?
  • Android SDK 22 - проблемы с визуализацией SearchView
  • Камера: функция setDisplayOrientation не работает для Samsung Galaxy ACE с Android 2.3.6
  • Какова основная цель методов setTag () getTag () View?
  • Какой самый простой способ получить текущий день недели в Android?
  • Android Spanned, SpannedString, Spannable, SpannableString и CharSequence
  • Неверный способ обработки fragmentации при изменении ориентации
  • Обратный вызов fragmentа из диалогового windows
  • Interesting Posts

    Facebook / Twitter с dotnetopenauth?

    Ошибка Xcode 6: Неизвестный class в файле Interface Builder

    Можно ли использовать дерби из apache в Eclipse теперь, когда они перестали разрабатывать плагин дерби для Eclipse?

    Не удается ввести пароль и логин – Windows 7 Professional

    Перегрузка арифметического оператора для общего classа в C #

    как получить параметр в методе post spring mvc?

    Передача файлов cookie FormsAuthentication в службу WCF

    Методы classа, которые создают новые экземпляры

    как установить только числовое значение для edittext в android?

    Как вызвать код Objective-C из Swift

    Как найти последний файл в каталоге с помощью .NET и без цикла?

    Как создать загрузочный USB-ключ Linux, который работает на Mac (Intel 64-битный процессор)?

    Установите LAN для приоритета сети перед тем, как Wi-Fi в Windows 7

    .. Основное соединение было закрыто: произошла непредвиденная ошибка при получении

    Почему некоторые процессы Windows продолжают записываться на диск даже на системном простоя?

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