RecyclerView项目宽度layout_width ="match_parent"与父项不匹配

Diy*_*yaa 8 xml android android-recyclerview

我正在使用RecyclerView,我正在尝试使用RecyclerView的宽度项match_parent,因为我正在使用

LinearLayoutManager.HORIZONTAL

运行后的RecyclerView项目

 <android.support.v7.widget.RecyclerView
            android:id="@+id/listOffersHits"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
Run Code Online (Sandbox Code Playgroud)

custom_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:layout_weight="1"
    android:layout_margin="2dp"
    card_view:cardCornerRadius="2dp">
    <ImageView
        android:id="@+id/offerImage"
        android:layout_width="match_parent"
        android:layout_height="match_parent"

        android:background="@drawable/item_selector"
        android:scaleType="fitXY"
        android:src="@drawable/offer"
        />

</android.support.v7.widget.CardView>
Run Code Online (Sandbox Code Playgroud)

布局管理

   LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity(),LinearLayoutManager.HORIZONTAL, false);
    listOffersHits.setLayoutManager(linearLayoutManager);
Run Code Online (Sandbox Code Playgroud)

ViewHolder

View view= LayoutInflater.from(parent.getContext())
                .inflate(R.layout.custom_layout, parent, false);
        ViewOffersHolder viewHolder=new ViewOffersHolder(view);
        return viewHolder;
Run Code Online (Sandbox Code Playgroud)

Diy*_*yaa 13

我解决了这个问题:

1-获取屏幕尺寸(宽度).

2-使ViewHolder宽度与屏幕尺寸相同.

在我的代码下面,如果有人需要它.

WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
        int width = windowManager.getDefaultDisplay().getWidth();
        int height = windowManager.getDefaultDisplay().getHeight();
        view.setLayoutParams(new RecyclerView.LayoutParams(width, RecyclerView.LayoutParams.MATCH_PARENT));
Run Code Online (Sandbox Code Playgroud)


Rhe*_*vim 7

注意: 请参阅本文末尾的更新.


旧答案:

以下对我有用:

view.getLayoutParams ().width = parentViewGroup.getWidth (); 
Run Code Online (Sandbox Code Playgroud)

,在充气视图'视图'之后.

它基本上采用父级的宽度,并用父级的宽度替换新视图的layout_width.

您还可以添加对MATCH_PARENT的检查,以确保它在将来将XML修改为不同宽度时正确显示.像这样:

    public ViewHolder onCreateViewHolder (ViewGroup parent, int type) {
        View vItem = LayoutInflater.from (parent.getContext ()) 
                             .inflate (R.layout.bookmark_card, parent, false); 
        if (vItem.getLayoutParams ().width == RecyclerView.LayoutParams.MATCH_PARENT) 
            vItem.getLayoutParams ().width = parent.getWidth (); 
        return new ViewHolder (vItem); 
    } 
Run Code Online (Sandbox Code Playgroud)

如果在此之前宽度为MATCH_PARENT,它将仅使其成为父宽度.

编辑:

请注意过度使用此修复程序,因为它的变体导致我出现布局错误.我这样做了:

    public ViewHolder onCreateViewHolder (ViewGroup parent, int type) { 
        View vItem = LayoutInflater.from (parent.getContext ()) 
                             .inflate (R.layout.page_tile, parent, false); 
        if (vItem.getLayoutParams ().width == RecyclerView.LayoutParams.MATCH_PARENT) 
            vItem.getLayoutParams ().width = parent.getWidth (); 
        if (vItem.getLayoutParams ().height == RecyclerView.LayoutParams.MATCH_PARENT) 
            vItem.getLayoutParams ().height = parent.getHeight (); 
        return new ViewHolder (vItem); 
    } 
Run Code Online (Sandbox Code Playgroud)

这很有效,但是在调整RecyclerView的大小时,它没有更新宽度和高度.因此,可以应用此修复程序的两个修复程序之一:

  1. 检查RecyclerView适配器方向,并仅对允许滚动的维度执行此parent.getHeight()等.
  2. 或者,在ViewHolder中的某处,保存原始的"宽度"和"高度",然后每次在onBindViewHolder()方法中重做此步骤.

以下修复似乎有效:

    public ViewHolder onCreateViewHolder (ViewGroup parent, int type) { 
        View vItem = LayoutInflater.from (parent.getContext ()) 
                             .inflate (R.layout.page_tile, parent, false); 
        ViewHolder holder = new ViewHolder (vItem); // Create view holder. 
        holder.vItem = vItem; // Save top-level View. 
        holder.vParent = parent; // Save its parent. 
        ViewGroup.LayoutParams lp = vItem.getLayoutParams (); 
        if (lp != null) { // Save the original width and height from lp: 
            holder.originalWidth = lp.width; 
            holder.originalHeight = lp.height; 
            refreshLayoutParams (holder); // Check for MATCH_PARENT. 
        } else holder.originalHeight = holder.originalWidth = 0; 
        return holder; 
    } 
    public void onBindViewHolder (ViewHolder holder, int position) { 
        ... do work here ... 
        refreshLayoutParams (holder); // Check AGAIN for MATCH_PARENT. 
    } 
    private void refreshLayoutParams (ViewHolder holder) {
        ViewGroup.LayoutParams lp = holder.vItem.getLayoutParams (); 
        View parent = holder.vParent; 
        if (parent == null) return; // Is there a parent to check against? 
        if (lp == null) 
            holder.vItem.setLayoutParams (lp = 
                            new RecyclerView.LayoutParams (holder.originalWidth, holder.originalHeight)); 
        if (holder.originalWidth == RecyclerView.LayoutParams.MATCH_PARENT) 
            lp.width = parent.getWidth (); // Check width. 
        if (holder.originalHeight == RecyclerView.LayoutParams.MATCH_PARENT) 
            lp.height = parent.getHeight (); // Check height. 
    } 
Run Code Online (Sandbox Code Playgroud)

注意另外:如果在onBindViewHolder()方法中使用这种调整大小的方法,则还需要在Activity.onSizeChanged()内部使用getAdapter().notifyDataSetChanged ()!

简而言之,主要思想是:在每个绑定上检查MATCH_PARENT ,而不仅仅是在创建视图持有者上.这样也可以调整RecyclerView的大小.


更新: 至少从RecyclerView v7:23.2.1开始,似乎他们已修复它,现在不再需要这些自定义修复.RecyclerView本身现在应该识别WRAP_CONTENT和MATCH_PARENT设置.