【问题标题】:reciclerview GridLayoutManager very slowrecyclerview GridLayoutManager 很慢
【发布时间】:2015-06-08 16:40:05
【问题描述】:

在考虑了很多文档之后,我决定分享我的代码和问题。 我有一个观点,这是我的下一个观点。 Item_grid.xml

<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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="0dp"

android:background="@color/blanco"
card_view:cardCornerRadius="0dp"
card_view:cardElevation="0dp"
card_view:cardUseCompatPadding="true">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"

    android:orientation="vertical">

    <RelativeLayout
        android:id="@+id/trlDiaNombre"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@color/naranjaffb973"
        android:minHeight="30dp"
        android:visibility="visible">

        <TextView
            android:id="@+id/txtADPDiaNombre"
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:gravity="center"
            android:singleLine="true"
            android:text="DIA"
            android:textColor="@color/blanco"
            android:textSize="14sp"
            android:textStyle="bold" />


    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/rtlDiaNumero"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:minHeight="40dp">

        <TextView
            android:id="@+id/txtADPDiaNumero"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="6"
            android:textColor="@color/morao_moraito_8C008C"
            android:textSize="18sp" />


    </RelativeLayout>

</LinearLayout>

很简单的两个Textviews。

它是适配器 这是膨胀视图的适配器 adapter.java

public class CustomAdapterListadoFechasRCV
    extends
    RecyclerView.Adapter<CustomAdapterListadoFechasRCV.ElementosLinea> {

private ArrayList<Cdia> mDataset;

private AfrmProgramaControl afrmGes;


// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public class ElementosLinea extends RecyclerView.ViewHolder {
    // each data item is just a string in this case

    TextView txtNombre;
    TextView txtNumero;
    RelativeLayout rtlNombre;
    RelativeLayout rtlNumero;
    // CardView card;

    public ElementosLinea(View v) {
        super(v);
        ArrayList<CUtilsTipografia.CtipoGraf> lstTipograf = new ArrayList<CUtilsTipografia.CtipoGraf>();
        // card = (CardView) v.findViewById(R.id.card);
        txtNombre = (TextView) v.findViewById(R.id.txtADPDiaNombre);
        txtNumero = (TextView) v.findViewById(R.id.txtADPDiaNumero);
        rtlNombre = (RelativeLayout) v.findViewById(R.id.trlDiaNombre);
        rtlNumero = (RelativeLayout) v.findViewById(R.id.rtlDiaNumero);
        lstTipograf.add(new CUtilsTipografia.CtipoGraf(txtNombre, 0, 1));
        lstTipograf.add(new CUtilsTipografia.CtipoGraf(txtNumero, 0, 0));
        CUtilsTipografia.setTypefaces(afrmGes.getActivity(), lstTipograf);

    }

}

public void add(int position, Cdia item) {
    mDataset.add(position, item);
    notifyItemInserted(position);
}

public void remove(Cdia item) {
    int position = mDataset.indexOf(item);
    mDataset.remove(position);
    notifyItemRemoved(position);


}


// Provide a suitable constructor (depends on the kind of dataset)
public CustomAdapterListadoFechasRCV(
        ArrayList<Cdia> myDataset, AfrmProgramaControl afrm) {
    mDataset = myDataset;
    afrmGes = afrm;
}

// Create new views (invoked by the layout manager)
@Override
public ElementosLinea onCreateViewHolder(
        ViewGroup parent, int viewType) {
    // create a new view
    View v = LayoutInflater.from(parent.getContext()).inflate(
            R.layout.ll_adapter_listado_fechas, parent, false);
    // set the view's size, margins, paddings and layout parameters
    ElementosLinea vh = new ElementosLinea(v);
    return vh;
}

// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ElementosLinea holder, final int position) {
    // - get element from your dataset at this position
    // - replace the contents of the view with that element
    final Cdia datossss = mDataset.get(position);

    if (datossss != null) {


        if (datossss.getDia() == -1) {//s
            holder.rtlNombre.setVisibility(View.VISIBLE);
            holder.rtlNumero.setVisibility(View.GONE);
            holder.txtNombre.setText(datossss.getNombreDia());

        } else {
            holder.rtlNombre.setVisibility(View.GONE);
            holder.rtlNumero.setVisibility(View.VISIBLE);
            if (datossss.getDia() != 0) {

                if (datossss.getMarcado() == 1) {
                    holder.txtNumero.setTextColor(afrmGes.getResources().getColor(R.color.marcacalendarioff4000));
                } else {
                    holder.txtNumero.setTextColor(afrmGes.getResources().getColor(R.color.grisclarod8d8d8));
                }

                holder.txtNumero.setText(String.valueOf(datossss.getDia()));
            } else {
                holder.txtNumero.setText("");
            }


        }


        //


    }


    holder.rtlNumero.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Cdia dia = mDataset.get(position);
            afrmGes.cargarProgramaDia(dia);
        }
    });

}

// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
    return mDataset.size();
}

}

如您所见,我的适配器只需要天数列表 Cdia.java

public class Cdia {


private int _iDia;
private String _sNombreDia;
private int _iMarcado;
private int _iMes;


public Cdia() {
    _iDia = 0;
    _sNombreDia = "";
    _iMarcado = 0;
    _iMes =0;
}


public int getDia() {
    return _iDia;
}

public void setDia(int _iDia) {
    this._iDia = _iDia;
}

public String getNombreDia() {
    return _sNombreDia;
}

public void setNombreDia(String _sNombreDia) {
    this._sNombreDia = _sNombreDia;
}


public int getMarcado() {
    return _iMarcado;
}

public void setMarcado(int _iMarcado) {
    this._iMarcado = _iMarcado;
}


public int getMes() {
    return _iMes;
}

public void setMes(int _iMes) {
    this._iMes = _iMes;
}

一切准备就绪后,我会解释我的问题 gridLayoutManages 的这个dispodicion分为七列,这样我生成了两个月,每列对应的日历日如下。

自从成为数据列表的适配器直到它在裤装中经过太长时间,超过 4 秒。这就是我的适配器有多满。

我没有找到解决加载速度问题的方法 有人可以在我的黑暗之路上给我光明吗? 谢谢。

更新更新:

public class GridViewReciclerObservable extends ObservableRecyclerView {

//para ponerle el tipo linear
private GridLayoutManagerCustom mLayoutManager;

private int _iColumnas = 7;

public GridViewReciclerObservable(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

    mLayoutManager = new GridLayoutManagerCustom(getContext(), _iColumnas);
    setLayoutManager(mLayoutManager);
    LayoutParams par = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    setLayoutParams(par);

}


public GridViewReciclerObservable(Context context, AttributeSet attrs) {
    super(context, attrs);
    mLayoutManager = new GridLayoutManagerCustom(getContext(), _iColumnas);
    setLayoutManager(mLayoutManager);
    LayoutParams par = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    setLayoutParams(par);
    // TODO Auto-generated constructor stub
}

public GridViewReciclerObservable(Context context) {
    super(context);
    mLayoutManager = new GridLayoutManagerCustom(getContext(), _iColumnas);
    setLayoutManager(mLayoutManager);
    LayoutParams par = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    setLayoutParams(par);
    // TODO Auto-generated constructor stub
}

}

VIEWPARENT

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/blanco">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">


        <TextView
            android:id="@+id/txtMesEnCurso"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="New Text"
            android:layout_margin="5dp"
            android:textSize="25sp"
            android:textColor="@color/gris444444">


        </TextView>

        <com.jesusdelarosainfante.herramientas.view.GridViewReciclerObservable
            android:id="@+id/rcvGCalen"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="5dp"
            android:scrollbars="vertical" />


    </LinearLayout>

</RelativeLayout>

【问题讨论】:

  • 我在使用 Rcyclerview 和 GridLayoutManager 时遇到了类似的性能问题。经过几个小时的头撞。我注意到我有一个不透明度为 0.2 的视图用作我的项目视图中的叠加层。当我将不透明度改回 1 时。所有性能问题都消失了。不透明度绘图似乎很重。
  • 这个问题很老,但我也有同样的问题。你解决了吗?
  • 你好,如果我能解决的话。我遇到了自动权重与linearLayout中屏幕的最大调整相结合的问题,简而言之,问题是由于您的视图构造不正确。我通过将父容器放入 macth_parent(高度,宽度)来解决它们,当我绘制自定义对象时,我将该对象留在更新中

标签: android android-layout android-recyclerview gridlayoutmanager


【解决方案1】:

我可以看到许多提高代码性能的方法,但这些方法不会缩短 4 秒。

我猜大部分的性能问题是从你的数据库中获取 myDataset (或者你正在获取你的数据)。

尝试测量代码的特定部分,以更好地了解究竟是什么花费了这么长时间。 您可以通过添加来衡量:

long before = System.currentTimeMillis();

在一些代码块之前,并且:

long after = System.currentTimeMillis();

在它之后,然后以毫秒为单位打印花费了多长时间:(after - before)

不管怎样,你可以在你的代码中改进的东西(但可能不会有太大的不同):

  1. 在适配器的构造函数中只获取一次LayoutInflater,并将其存储到成员中。
  2. 重复使用相同的OnClickListener 而不是在绑定方法上创建新对象,然后您可以通过检查传递给OnClick 方法的视图来决定要执行的操作。

【讨论】:

  • 你好,我的加载数据源需要0.2毫秒的速度相当快,当你必须在屏幕上绘制所有框时,我的问题来了,大多数框的onclick方法都被禁用了。
【解决方案2】:

在您的xml 文件中,尝试将属性值从wrap_content 更改为固定值或match_parent,因为每次视图初始化或重用时,如果heigh/width 的值是wrap_content,则意味着操作系统总是计算以获得最佳大小,并且需要大量性能。 您可以登录onMeasure()查看。

【讨论】:

  • 你说的我试过了,画的时候还是一样,我把所有的固定尺寸。如果你看看我的处置,宽度上没有任何 wrap_content。
  • 宽度和高度都应该是固定值来测试性能,我认为
  • 我试着把所有固定的尺寸和时间都没有改善膨胀。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-24
  • 1970-01-01
  • 1970-01-01
  • 2017-01-16
  • 2021-08-19
  • 1970-01-01
相关资源
最近更新 更多