简体   繁体   English

如何在 RecyclerView 中显示确切的项目数量?

[英]How to show exact number of items in RecyclerView?

I am trying to show exact (eg. 3 items) in RecyclerView.我试图在 RecyclerView 中显示精确(例如 3 个项目)。 Our web application shows like this:我们的 Web 应用程序显示如下:

在此处输入图片说明

If I move items:如果我移动项目:

在此处输入图片说明

and release the mouse, it automatically comes to this:然后松开鼠标,它会自动出现: 在此处输入图片说明

In Android, I am showing images using RecyclerView:在 Android 中,我使用 RecyclerView 显示图像:

在此处输入图片说明

How to show exactly 3 items in the visible area of RecyclerView?如何在 RecyclerView 的可见区域中准确显示 3 个项目? How to avoid to show "half" items?如何避免显示“一半”项目? Is this possible?这可能吗?

RecyclerView:回收者视图:

        <android.support.v7.widget.RecyclerView
            android:layout_width="wrap_content"
            android:layout_height="130dp"
            android:id="@+id/rvProducts" />

One item in recycler view:回收商视图中的一项:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:id="@+id/ivProduct"
        android:src="@drawable/noimage"/>

</LinearLayout>

Code:代码:

    LinearLayoutManager layoutManager
            = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
    RecyclerView productImageList = (RecyclerView) view.findViewById(R.id.rvProducts);
    productImageList.setLayoutManager(layoutManager);
    GalleryRecyclerAdapter adapter = new GalleryRecyclerAdapter(images);
    productImageList.setAdapter(adapter);

One solution is to set width of each child programmatically like.一种解决方案是以编程方式设置每个孩子的width

view.getLayoutParams().width = getScreenWidth() / VIEWS_COUNT_TO_DISPLAY;

And the screen size like this:屏幕尺寸是这样的:

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics).widthPixels;

I have done the above task as following approach, please refers the following code我已经按照以下方法完成了上述任务,请参考以下代码

On my onCreateViewHolder() method of my RecycleView Adapter , i find out the width of the screen and than divided into 3 sections.Please check it once.在我的RecycleView Adapter onCreateViewHolder()方法中,我找出了屏幕的宽度,然后将其分为3 个部分。请检查一次。

@Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.MY_ITEM_TO_INFALTE, parent, false);

        itemView.getLayoutParams().width = (int) (getScreenWidth() / NUMBERS_OF_ITEM_TO_DISPLAY); /// THIS LINE WILL DIVIDE OUR VIEW INTO NUMBERS OF PARTS

        return new MyCreationItemAdapter.MyViewHolder(itemView);
    }

From above code getScreenWidth() method which we use on above is as follow,please check it.从上面的代码中,我们在上面使用的getScreenWidth()方法如下,请检查它。

public int getScreenWidth() {

        WindowManager wm = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);

        return size.x;
    }

In a general way to achieve this there is no straight forward property that recycler view comes with.在实现这一点的一般方法中,回收者视图没有直接的属性。

The way this is achievable is by sending in the parent width to the adapter..实现这一点的方法是将父宽度发送到适配器。

In a suedo way..以一种麂皮的方式..

    Parent width = parent container width;

    InitialiseRecyclerAdapter(parent width) {
         on create view holder {
                 Set the width of ur item layout with a width that divides ur parent width in equal parts;
          }
}

This solution worked for me:这个解决方案对我有用:

 private lateinit var productImageList: RecyclerView

 override fun onAttachedToRecyclerView(recyclerView: RecyclerView) 
  {
       super.onAttachedToRecyclerView(recyclerView)

        productImageList = recyclerView
  }

 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductViewHolder {
        val viewHolder = LayoutInflater.from(parent.context).inflate(R.layout.ITEM_TO_INFALTE, parent, false)

        viewHolder.layoutParams.width = productImageList.measuredWidth / NUMBERS_OF_ITEM_TO_DISPLAY

        return ProductViewHolder(viewHolder)
    }

Code is in kotlin, hope it will help you.代码在 kotlin 中,希望对您有所帮助。

The solution that I have provided below helps in displaying pre-defined number of child items(' numOfCardViewItemsOnScreen ') in a recyclerView on the screen, also calculates the margins between these items to space them evenly , by taking into account the supplied margin between the items & recyclerView's end margin's (ie, ' marginAtRecyclerViewsEnds ')我在下面提供的解决方案有助于在屏幕上的 recyclerView 中显示预定义数量的子项目(' numOfCardViewItemsOnScreen '),还计算这些项目之间的边距以均匀间隔它们,通过考虑之间提供的边距items & recyclerView 的结束边距(即,' marginAtRecyclerViewsEnds ')

Note that I have tested this in devices between 5.0" to 7.0" inch devices & obtained consistent result.请注意,我已经在 5.0" 到 7.0" 英寸设备之间进行了测试,并获得了一致的结果。

private fun configureCardViewLayoutParams(cardView: CardView, numOfCardViewItemsOnScreen: Int, marginAtRecyclerViewsEnds: Float, marginLeftParam: Float, marginRightParam: Float, marginTopParam: Float, marginBottomParam: Float): ViewGroup.MarginLayoutParams {
    val numOfGapsInBetweenItems = numOfCardViewItemsOnScreen - 1
    var combinedGapWidth = ((marginLeftParam + marginRightParam) * numOfGapsInBetweenItems) + (marginAtRecyclerViewsEnds * 2)
    //Provided approx. adjustment of 2dp to prevent the extreme edges of the card from being cut-off
    combinedGapWidth += 2
    val combinedGapWidthDp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, combinedGapWidth, cardView.resources.displayMetrics).toInt()
    //Since margins/gaps are provided in-between the items, these have to be taken to account & subtracted from the width in-order to obtain even spacing
    cardView.layoutParams.width = (getScreenWidth(cardView.context as MainActivity) - combinedGapWidthDp) / numOfCardViewItemsOnScreen

    //Margins in-between the items
    val marginLeftOfItem = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginLeftParam, cardView.resources.displayMetrics).toInt()
    val marginRightOfItem = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginRightParam, cardView.resources.displayMetrics).toInt()
    val marginTopOfItem = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginTopParam, cardView.resources.displayMetrics).toInt()
    val marginBottomOfItem = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginBottomParam, cardView.resources.displayMetrics).toInt()

    //Providing the above margins to the CardView
    val cardViewMarginParams: ViewGroup.MarginLayoutParams = cardView.layoutParams as ViewGroup.MarginLayoutParams
    cardViewMarginParams.setMargins(marginLeftOfItem, marginTopOfItem, marginRightOfItem, marginBottomOfItem)
    return cardViewMarginParams
}

The below method helps in calculating the screenWidth as the name implies顾名思义,以下方法有助于计算 screenWidth

private fun getScreenWidth(activity: MainActivity): Int {
    var width: Int = 0
    val size = Point()
    val windowManager = activity.getSystemService(Context.WINDOW_SERVICE) as WindowManager
    width = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        val bounds = windowManager.currentWindowMetrics.bounds
        bounds.width()
    } else {
        val display: Display? = windowManager.defaultDisplay
        display?.getSize(size)
        size.x
    }
    return width
}

Finally inside onCreateViewHolder, utilise the configureCardViewLayoutParams method depicted above & pass in the desired arguments最后在 onCreateViewHolder 中,利用上面描述的 configureCardViewLayoutParams 方法并传入所需的参数

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyRecyclerViewHolder {
    val view = LayoutInflater.from(parent.context).inflate(R.layout.row_item_layout, parent, false)
    view.layoutParams = configureCardViewLayoutParams(view as CardView, 4, 12f, 4f, 4f, 8f, 8f)
    return MyRecyclerViewHolder(view)
}

For the sake of quick understanding, I have also provided the child items xml layout (row_item_layout.xml) So as you can see from the below xml, the root view of our child item layout is a CardView.为了便于理解,我还提供了子项的xml布局(row_item_layout.xml),所以从下面的xml可以看出,我们子项布局的根视图是一个CardView。

<?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:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:elevation="5dp"
    android:foregroundGravity="center">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="30dp"
            android:layout_height="28dp"
            android:layout_marginTop="22dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:src="@tools:sample/avatars" />

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="7dp"
            android:layout_marginTop="18dp"
            android:layout_marginEnd="7dp"
            android:layout_marginBottom="16dp"
            android:ellipsize="end"
            android:gravity="center"
            android:maxLines="2"
            android:text="@{accountOptionsModel.title}"
            android:textSize="14sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/imageView1"
            tools:text="@tools:sample/full_names" />
    </androidx.constraintlayout.widget.ConstraintLayout>


</androidx.cardview.widget.CardView>

There is no special logic within the getCount(), just return the entire list size getCount() 中没有特殊逻辑,只返回整个列表大小

override fun getItemCount(): Int = myList.size

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

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