簡體   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