Как я могу использовать layout_weight в представлении элементов RecyclerView или ListView, чтобы элементы с равной высотой заполняли доступное пространство на экране?

В настоящее время мне нужно использовать RecyclerView (или ListView), но количество элементов фиксировано в 4. Я хочу, чтобы эти 4 элемента одинаково использовали доступное пространство на экране. RecyclerView - это единственный вид на экране, за исключением панели приложений. То есть RecyclerView имеет layout_height значение match_parent. Я выбрал RecyclerView, потому что элементы имеют разные макеты в зависимости от состояния модели.

Я еще не просмотрел его, но я уверен, что я могу установить высоту программно в Java-коде для каждого элемента. Но это кажется неэлегантным, если я могу указать его в XML. Подобные вопросы, которые я имею в виду, когда я пишу это, отвечают на этот вопрос.

Я пробовал следующее в файле item_layout.xml, способ layout_weight используется в других сценариях:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_weight="1"
    android:layout_height="0dp">...</LinearLayout>

Но на экране ничего не отображается.

Что я хотел бы знать, могу ли я сделать это в XML-макете с layout_weight или что-то еще? Если да, то как?

Ответы

Ответ 1

Как говорится в ссылке API, layout_weight является атрибутом LinearLayout, поэтому не может использоваться с другими группами представлений, такими как, например, RecyclerView и ListView. Вместо этого вы должны установить высоту элемента программно.

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

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater
            .from(parent.getContext())
            .inflate(R.layout.item_list, null);

    int height = parent.getMeasuredHeight() / 4;
    int width = parent.getMeasuredWidth();

    view.setLayoutParams(new RecyclerView.LayoutParams(width, height));

    return new ViewHolder(view);
}

Ответ 2

Попробуй, работай для меня

int weight = 3; //number of parts in the recycler view. 

@Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View rowView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row,parent,false);
        rowView.getLayoutParams().height = parent.getHeight() / weight;
        return new ViewHolder(rowView);
    }

Ответ 3

Я столкнулся с этой проблемой, так как у меня был RecyclerView с переменными элементами. Мой горизонтальный RecyclerView должен был поместиться как минимум в три вида без переполнения, поэтому я построил свои представления для изменения размера во время выполнения, чтобы он соответствовал экрану.

class MyRecyclerView extends RecyclerView.Adapter<ViewHolder> {

    int mViewWidth;

    public MyRecyclerView(Context context) {
      mViewWidth = defineViewWidth(context);
    }

    private int defineViewWidth(Context context) {
      int definedWidth = (int) context.getResources().getDimension(R.dimen.default_view_width);
      DisplayMetrics dm = new DisplayMetrics();
      WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
      wm.getDefaultDisplay().getMetrics(dm);
      if (definedWidth * 3 > dm.widthPixels) {
        return dm.widthPixels / 3;
      }
      return definedWidth;
    }

    ...

}

Как только вы определили ширину, вам нужно установить ширину вида:

@Override
public ViewHolder onCreateViewHolder(ViewHolder holder, int position) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false);
    ViewGroup.LayoutParams params = v.getLayoutParams();
    params.width = mViewWidth;
    v.setLayoutParams(params);
    return new ViewHolder(v);
}

Вы можете легко изменить это, чтобы убедиться, что RecyclerView соответствует как можно большему количеству элементов (по вертикали или по горизонтали).