android - RecyclerView 没有正确展开项目

标签 android android-layout android-recyclerview

我有这样的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="6dp"
    android:id="@+id/shift_main_layout"
    android:orientation="vertical"
    android:background="@android:color/white">
    <ScrollView
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_gravity="top"
        android:layout_weight="1">
        <RelativeLayout
            android:id="@+id/recycle_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:gravity="top">
            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/coworker_recycler"
                android:layout_centerHorizontal="true"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
        </RelativeLayout>
    </ScrollView>

   <LinearLayout
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="center_horizontal">
       <com.google.android.material.button.MaterialButton
           android:id="@+id/remove_operator"
           style="@style/customIconButton"
           android:layout_width="wrap_content"
           android:layout_height="25dp"
           app:icon="@drawable/ic_remove_black_24dp" />
       <com.google.android.material.button.MaterialButton
           android:id="@+id/add_operator"
           style="@style/customIconButton"
           android:layout_width="wrap_content"
           android:layout_height="25dp"
           app:icon="@drawable/ic_add_black_24dp" />
   </LinearLayout>

Recycler Viewer coworker_recycler 的项目是这样的:

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

    <LinearLayout
        android:paddingStart="0.5dp"
        android:paddingEnd="0.5dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:id="@+id/shift_layout">
        <!--region Cells-->
        <!--Ora00 Row-->
        <TextView
            android:id="@+id/ora00"
            style="@style/cell_style"/>
        <!--Ora01 Row-->
        <TextView
            android:id="@+id/ora01"
            style="@style/cell_style"/>
        <!--Ora02 Row-->
        <TextView
            android:id="@+id/ora02"
            style="@style/cell_style"/>
        <!--Ora03 Row-->
        <TextView
            android:id="@+id/ora03"
            style="@style/cell_style"/>
        <!--Ora04 Row-->
        <TextView
            android:id="@+id/ora04"
            style="@style/cell_style"/>
        <!--Ora05 Row-->
        <TextView
            android:id="@+id/ora05"
            style="@style/cell_style"/>
        <!--Ora06 Row-->
        <TextView
            android:id="@+id/ora06"
            style="@style/cell_style"/>
        <!--Ora07 Row-->
        <TextView
            android:id="@+id/ora07"
            style="@style/cell_style"/>
        <!--Ora08 Row-->
        <TextView
            android:id="@+id/ora08"
            style="@style/cell_style"/>
        <!--Ora09 Row-->
        <TextView
            android:id="@+id/ora09"
            style="@style/cell_style"/>
        <!--Ora10 Row-->
        <TextView
            android:id="@+id/ora10"
            style="@style/cell_style"/>
        <!--Ora11 Row-->
        <TextView
            android:id="@+id/ora11"
            style="@style/cell_style"/>
        <!--Ora12 Row-->
        <TextView
            android:id="@+id/ora12"
            style="@style/cell_style"/>
        <!--Ora13 Row-->
        <TextView
            android:id="@+id/ora13"
            style="@style/cell_style"/>
        <!--Ora14 Row-->
        <TextView
            android:id="@+id/ora14"
            style="@style/cell_style"/>
        <!--Ora15 Row-->
        <TextView
            android:id="@+id/ora15"
            style="@style/cell_style"/>
        <!--Ora16 Row-->
        <TextView
            android:id="@+id/ora16"
            style="@style/cell_style"/>
        <!--Ora17 Row-->
        <TextView
            android:id="@+id/ora17"
            style="@style/cell_style"/>
        <!--Ora18 Row-->
        <TextView
            android:id="@+id/ora18"
            style="@style/cell_style"/>
        <!--Ora19 Row-->
        <TextView
            android:id="@+id/ora19"
            style="@style/cell_style"/>
        <!--Ora20 Row-->
        <TextView
            android:id="@+id/ora20"
            style="@style/cell_style"/>
        <!--Ora21 Row-->
        <TextView
            android:id="@+id/ora21"
            style="@style/cell_style"/>
        <!--Ora22 Row-->
        <TextView
            android:id="@+id/ora22"
            style="@style/cell_style"/>
        <!--Ora23 Row-->
        <TextView
            android:id="@+id/ora23"
            style="@style/cell_style"/>
        <!--endregion-->
    </LinearLayout>
</LinearLayout>

项目 TextView 的单元格样式是:

<style name="cell_style" parent="android:Widget.TextView">
    <item name="android:layout_marginTop">1dp</item>
    <item name="android:layout_width">match_parent</item>
    <item name="android:layout_gravity">center_horizontal</item>
    <item name="android:layout_height">@dimen/cell_height</item>
</style>

Recycler Viewer 的适配器是:

import android.content.Context;
import android.os.Handler;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.hearth.Model.ShiftModel;
import com.example.hearth.R;
import com.example.hearth.ViewHolder.ShiftViewHolder;
import com.squareup.picasso.Picasso;

import java.util.List;

import jp.wasabeef.picasso.transformations.CropCircleTransformation;

public class ShiftMapAdapter extends RecyclerView.Adapter {

    private Context context;

    private List<ShiftModel> shiftModelList;

    int operatorShow;

    private int Hour(double ora) {
        return ora == 0 ? R.drawable.hour_empty : (ora == 0.5 ? R.drawable.hour_half : R.drawable.hour_full);
}

public ShiftMapAdapter(Context context, List<ShiftModel> shiftModelList, int operatorShow) {
    this.context = context;
    this.shiftModelList = shiftModelList;
    this.operatorShow = operatorShow;
}

@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    View itemView = LayoutInflater.from(context).inflate(R.layout.layout_shift_container, parent, false);

    GridLayoutManager.LayoutParams lp = (GridLayoutManager.LayoutParams)itemView.getLayoutParams();

    float itemWidth = pxToDp(parent.getMeasuredWidth());

    lp.width = dpToPx((itemWidth)/operatorShow);

    itemView.setLayoutParams(lp);

    return new ShiftViewHolder(itemView);
}

public int dpToPx(float dp) {
    DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
    int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
    return px;
}

public float pxToDp(float px) {
    DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
    float dp = px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT);
    return dp;
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

    ShiftViewHolder vh = (ShiftViewHolder)holder;

    Handler myHandler = new Handler();

    myHandler.post(() -> {

        vh.ora00.setBackgroundResource(Hour(shiftModelList.get(position).getOra00()));
        vh.ora01.setBackgroundResource(Hour(shiftModelList.get(position).getOra01()));
        vh.ora02.setBackgroundResource(Hour(shiftModelList.get(position).getOra02()));
        vh.ora03.setBackgroundResource(Hour(shiftModelList.get(position).getOra03()));
        vh.ora04.setBackgroundResource(Hour(shiftModelList.get(position).getOra04()));
        vh.ora05.setBackgroundResource(Hour(shiftModelList.get(position).getOra05()));
        vh.ora06.setBackgroundResource(Hour(shiftModelList.get(position).getOra06()));
        vh.ora07.setBackgroundResource(Hour(shiftModelList.get(position).getOra07()));
        vh.ora08.setBackgroundResource(Hour(shiftModelList.get(position).getOra08()));
        vh.ora09.setBackgroundResource(Hour(shiftModelList.get(position).getOra09()));
        vh.ora10.setBackgroundResource(Hour(shiftModelList.get(position).getOra10()));
        vh.ora11.setBackgroundResource(Hour(shiftModelList.get(position).getOra11()));
        vh.ora12.setBackgroundResource(Hour(shiftModelList.get(position).getOra12()));
        vh.ora13.setBackgroundResource(Hour(shiftModelList.get(position).getOra13()));
        vh.ora14.setBackgroundResource(Hour(shiftModelList.get(position).getOra14()));
        vh.ora15.setBackgroundResource(Hour(shiftModelList.get(position).getOra15()));
        vh.ora16.setBackgroundResource(Hour(shiftModelList.get(position).getOra16()));
        vh.ora17.setBackgroundResource(Hour(shiftModelList.get(position).getOra17()));
        vh.ora18.setBackgroundResource(Hour(shiftModelList.get(position).getOra18()));
        vh.ora19.setBackgroundResource(Hour(shiftModelList.get(position).getOra19()));
        vh.ora20.setBackgroundResource(Hour(shiftModelList.get(position).getOra20()));
        vh.ora21.setBackgroundResource(Hour(shiftModelList.get(position).getOra21()));
        vh.ora22.setBackgroundResource(Hour(shiftModelList.get(position).getOra22()));
        vh.ora23.setBackgroundResource(Hour(shiftModelList.get(position).getOra23()));

    });
}

@Override
public int getItemCount() {
    return shiftModelList.size();
    }
}

我在 onCreateViewHolder 方法中使用 operatorShow 来设置项目的宽度 = 设备屏幕的 1/6。

View 持有者是:

import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.example.hearth.R;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;

public class ShiftViewHolder extends RecyclerView.ViewHolder {

    Unbinder unbinder;

    @BindView(R.id.ora00)
    public
    TextView ora00;
    @BindView(R.id.ora01)
    public
    TextView ora01;
    @BindView(R.id.ora02)
    public
    TextView ora02;
    @BindView(R.id.ora03)
    public
    TextView ora03;
    @BindView(R.id.ora04)
    public
    TextView ora04;
    @BindView(R.id.ora05)
    public
    TextView ora05;
    @BindView(R.id.ora06)
    public
    TextView ora06;
    @BindView(R.id.ora07)
    public
    TextView ora07;
    @BindView(R.id.ora08)
    public
    TextView ora08;
    @BindView(R.id.ora09)
    public
    TextView ora09;
    @BindView(R.id.ora10)
    public
    TextView ora10;
    @BindView(R.id.ora11)
    public
    TextView ora11;
    @BindView(R.id.ora12)
    public
    TextView ora12;
    @BindView(R.id.ora13)
    public
    TextView ora13;
    @BindView(R.id.ora14)
    public
    TextView ora14;
    @BindView(R.id.ora15)
    public
    TextView ora15;
    @BindView(R.id.ora16)
    public
    TextView ora16;
    @BindView(R.id.ora17)
    public
    TextView ora17;
    @BindView(R.id.ora18)
    public
    TextView ora18;
    @BindView(R.id.ora19)
    public
    TextView ora19;
    @BindView(R.id.ora20)
    public
    TextView ora20;
    @BindView(R.id.ora21)
    public
    TextView ora21;
    @BindView(R.id.ora22)
    public
    TextView ora22;
    @BindView(R.id.ora23)
    public
    TextView ora23;

    public ShiftViewHolder(@NonNull View itemView) {
        super(itemView);

        unbinder = ButterKnife.bind(this, itemView);
    }
}

我在 fragment 中这样称呼所有内容:

public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    shiftsViewModel = ViewModelProviders.of(this).get(ShiftsViewModel.class);

    selectedDate = "2019-11-12";

    setHasOptionsMenu(true);

    View root = inflater.inflate(R.layout.fragment_shifts, container, false);

    unbinder = ButterKnife.bind(this, root);

    //Count how many columns are created in the recycle

    addOperator.setOnClickListener(view -> {

        int adapterItemsCount = shiftMapAdapter.getItemCount();

        if (operatorShow < adapterItemsCount) {

            operatorShow++;

            getMap(selectedDate);
        }
        else {
            Toast.makeText(getContext(), "Can't add more columns", Toast.LENGTH_SHORT).show();
        }
    });

    removeOperator.setOnClickListener(view -> {

        if (operatorShow > 5) {

            operatorShow--;

            getMap(selectedDate);
        }
        else {
            Toast.makeText(getContext(), "Can't remove more columns", Toast.LENGTH_SHORT).show();
        }
    });

    initialize();

    getMap(selectedDate);
    return root;
}


private void getMap(String selectedDate) {

    shiftsViewModel.getCoworkerList(selectedDate).observe(getActivity(), shiftModel -> {

        shiftMapAdapter = new ShiftMapAdapter(ShiftsFragment.this.getContext(), shiftModel, operatorShow);

        coworker_recycler.setAdapter(shiftMapAdapter);
        coworker_recycler.setLayoutAnimation(layoutAnimationController);
    });
}

private void initialize() {
    layoutAnimationController = AnimationUtils.loadLayoutAnimation(getContext(), R.anim.layout_item_from_left);
    coworker_recycler.setHasFixedSize(true);
    coworker_recycler.setLayoutManager(new GridLayoutManager(getContext(), 1, RecyclerView.HORIZONTAL, false));
}

enter image description here

问题是当我需要添加更多列时,例如 8,项目没有正确展开。

enter image description here

很明显,像图片一样,右边缘有一些绿色像素。

对我做错的事情有什么帮助,或者有什么建议可以更好地平均扩展 RecyclerViewer 的项目吗?

最佳答案

float itemWidth = pxToDp(parent.getMeasuredWidth());
lp.width = dpToPx((itemWidth)/operatorShow);

当您将 itemWidth 除以 operatorShow 时,答案很可能是分数,具体取决于屏幕宽度。 因为宽度是整数,所以你失去了精度。'

如果上面的内容没有意义,我会在这里解释:

更详细的解释:
假设宽度为 640,如果列数为 6,则:

itemWidth = 640/6 = 106.6666 = 106 (fractional part dropped since pixel is the smallest unit)

现在对于每个项目,您的宽度正好是 106。现在让我们计算如果每列占用 106 列,则所有 6 列将占用多少空间:

106 * 6 = 636  //Notice that our actual width was 640 so we lost 4 pixels in precision

如您所见,由于我们去掉了小数部分,我们失去了 4 个精度。这 4 个像素在末尾被遗漏了,这就是为什么当 View 试图填充空白空间时您会看到下一列的原因。

该怎么办?
您可以将列数减少到设备宽度的一个因子,如上例所示,如果除以 6 得到一个分数,则尝试使用 5 并继续降低直到找到一个。 如果这破坏了应用程序的功能,恐怕没有任何帮助,因为像素/dps 不能是分数。

关于android - RecyclerView 没有正确展开项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58791540/

相关文章:

android - 如何在 Android 中设置背景图像并将该图像适合整个卡片以用于卡片 View ?

android - 如何在回收器 View 的 onBindViewHolder() 方法中调用 getString()?

两次插入项目时Android Room持久性SQLiteConstraintException

java - 如何在android中获取web服务的所有权限?

android - 我如何为自定义 ExpandableListview 上的每个项目设置动画

Android View 布局设计帮助

android - 如何在协调器布局中将 LinearLayout 附加到屏幕底部?

java - Android ViewPager2中如何动态添加和删除页面?

android - 谷歌照片应用程序时间轴功能使用图像创建时的年份

android - 带有 Google Glass 库/管理器问题的 OpenCV