繁体   English   中英

如何使 Android RecyclerView 响应最初适合屏幕?

[英]How can I make the Android RecyclerView responsive to fit the screen initially?

如果屏幕很大或覆盖屏幕的项目较少,有时 RecyclerView 会在底部显示空白区域。 此外,如果它有更多项目,有时它会部分显示一些项目。 我想要的是:

RecyclerView 将覆盖给定行数的全部可用空间。 无论屏幕大小如何,它都会始终填满屏幕。

我怎样才能做到这一点?

将 match_parent 用于宽度和高度。

我现在为任何未来的提问者发布我的解决方案。 在这里,通过RESPONSIVE一词,我希望 Items 平等地占用可用的屏幕空间。 例如,如果我们最初想要 4 行,那么 4 行将完全覆盖屏幕; 这意味着,当 RecyclerView 第一次出现在屏幕上时,不会有部分可见的项目。 并且这仅在 RecyclerView 具有固定高度的情况下有效,而不管其子级如何,这意味着不要将 WRAP_CONTENT 赋予 RecyclerView layout_height,而应赋予其他任何东西,例如 MATCH_PARENT 或约束高度。

Step1:您需要向Adapter传递一个参数rows 您还需要将RecyclerView传递给适配器。

步骤 2:我们需要保留一个FLAG ,它将决定何时在屏幕上显示子项。 这个 FLAG 最初是 FALSE,当我们完成计算 RecyclerView 在屏幕上的可用高度时,这将是 TRUE。 当我们得到 RecyclerView 的高度时,我们将其按行进行划分,并得到每一行的高度。 所以我们需要在 RecyclerView 上放一个OnGlobalLayoutListener

这是一个示例代码。

RecyclerView 布局如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:id="@+id/recycler_view"
        tools:listitem="@layout/item"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

项目布局将如下所示:

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardPreventCornerOverlap="true"
    app:cardUseCompatPadding="true"
    card_view:cardCornerRadius="5dp"
    card_view:cardElevation="5dp">

    <TextView
        android:padding="15dp"
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:enabled="true"
        android:focusable="true"
        android:longClickable="true"
        android:textIsSelectable="true" />

</androidx.cardview.widget.CardView>

适配器将如下所示:

public class ResponsiveItemListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements View.OnClickListener
{
    public static final int NUMBER_OF_ROWS_AUTO = -1;

    Context context;
    LayoutInflater layoutInflater;
    RecyclerViewItemClickListeners listener;
    List<Item> items;
    RecyclerView recyclerView;
    int numberOfRows;
    int rowHeightInPx = 0;
    boolean itemHeightCalculationCompleted = false;

    public ResponsiveItemListAdapter(Context context, List<Item> items, RecyclerViewItemClickListeners listener, RecyclerView rv, int rows)
    {
        super();
        this.context = context;
        this.items = items;
        this.listener = listener;
        this.layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.recyclerView = rv;
        this.numberOfRows = rows;

        if (this.numberOfRows > 0)
        {
            this.recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
            {
                @Override
                public void onGlobalLayout()
                {
                    if (recyclerView.getMeasuredHeight() > 0)
                    {
                        recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        setRowHeightInPx(recyclerView.getMeasuredHeight() / numberOfRows);
                        itemHeightCalculationCompleted = true;
                        notifyDataSetChanged();
                    }
                }
            });
        } else
        {
            itemHeightCalculationCompleted = true;
        }

    }

    public int getRowHeightInPx()
    {
        return rowHeightInPx;
    }

    public void setRowHeightInPx(int rowHeightInPx)
    {
        this.rowHeightInPx = rowHeightInPx;
    }

    @Override
    public int getItemCount()
    {
        if (this.items != null && this.itemHeightCalculationCompleted)
            return this.items.size();
        else
            return 0;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        RecyclerView.ViewHolder vh;
        View view = this.layoutInflater.inflate(R.layout.item, parent, false);
        if (getRowHeightInPx() > 0)
        {
            RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) view.getLayoutParams();
            layoutParams.height = getRowHeightInPx();
            layoutParams.width = MATCH_PARENT;
            view.setLayoutParams(layoutParams);
        }
        vh = new GeneralViewHolder(view);
        return vh;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
    {
        Item page = items.get(position);

        CardView view = ((CardView) ((GeneralViewHolder) holder).getView());
        ((GeneralViewHolder) holder).getTitle().setText(page.getTitle());
        ((GeneralViewHolder) holder).getView().setOnClickListener(this);
        ((GeneralViewHolder) holder).getView().setTag(position);
    }


    @Override
    public void onViewRecycled(RecyclerView.ViewHolder holder)
    {
        super.onViewRecycled(holder);
    }


    @Override
    public void onClick(View v)
    {
        int position = (int) v.getTag();
        this.listener.onRecyclerViewItemClick(this.items, position);
    }

    public class GeneralViewHolder extends RecyclerView.ViewHolder
    {

        View view;
        TextView title;

        public GeneralViewHolder(View itemView)
        {
            super(itemView);
            view = itemView;
            title = itemView.findViewById(R.id.title);
        }


        public View getView()
        {
            return view;
        }

        public TextView getTitle()
        {
            return title;
        }

    }

    public interface RecyclerViewItemClickListeners
    {
        void onRecyclerViewItemClick(List<Item> items, int position);
    }
}

像这样设置适配器:

public class MainActivity extends AppCompatActivity implements ResponsiveItemListAdapter.RecyclerViewItemClickListeners
{

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        List<Item> items = new ArrayList<>();
        items.add(new Item("One"));
        items.add(new Item("Two"));
        items.add(new Item("Three"));
        items.add(new Item("Four"));
        items.add(new Item("Five"));
        items.add(new Item("Six"));
        items.add(new Item("Seven"));

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(new ResponsiveItemListAdapter(this, items, this, recyclerView, 3));
    }

    @Override
    public void onRecyclerViewItemClick(List<Item> items, int position)
    {
        Toast.makeText(this, items.get(position).getTitle(), Toast.LENGTH_LONG).show();

    }
}

这是输出:

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM