Создание элементов таблицы 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)); 
  • Как использовать onConfigurationChanged () и newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE в android 2.3.3
  • setRotation (90) для съемки в портретном режиме не работает на устройствах samsung
  • Поддерживает ли веб-представление на Android поддержку SSL?
  • Не удалось создать приложение com.android.tools.fd.runtime.BootstrapApplication?
  • Отключить прокрутку в веб-просмотре?
  • Отключить или запретить мультитач в действии
  • Как подписать Android-приложение с сигнатурой системы?
  • JsonMappingException: из токена START_ARRAY
  • BroadcastReceiver для ACTION_MEDIA_BUTTON не работает
  • Несколько кнопок для Android 2.x
  • Как воспроизводить несколько видеофайлов одновременно в одном макете бок о бок в другом представлении на Android
  • Давайте будем гением компьютера.