背景:項(xiàng)目當(dāng)中一個(gè)消息列表頁(yè)面曼追,頁(yè)面上半部分是一些固定高度的內(nèi)容。下半部分是消息列表将硝,用RecyclerView實(shí)現(xiàn)。最下面有輸入框屏镊,能打開軟鍵盤依疼。
問(wèn)題:當(dāng)消息量大的時(shí)候部分手機(jī)打開軟鍵盤的時(shí)候頁(yè)面卡頓嚴(yán)重。
經(jīng)過(guò)現(xiàn)象分析發(fā)現(xiàn)而芥,
- 只有在軟鍵盤打開時(shí)律罢,消息列表被完全擠掉的手機(jī)上才會(huì)出現(xiàn)卡頓。
- 日志輸出之后發(fā)現(xiàn)RecyclerView為當(dāng)前Adapter中的所有數(shù)據(jù)創(chuàng)建了ViewHolder。
- 進(jìn)一步跟蹤發(fā)現(xiàn)這時(shí)候的RecyclerView的height的高度已經(jīng)巨大無(wú)比误辑。
Demo示例如下
布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_recyle_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.mozat.myapplication.RecyleViewActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recylerView"
android:layout_marginTop="350dp"
android:layout_width="match_parent"
android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
Java代碼
//adapter
recylerView.setAdapter(new RecyclerView.Adapter<Holder>() {
@Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
TextView textView = new TextView(parent.getContext());
Log.d("aaaa", "onCreateViewHolder "+textView.hashCode());
return new Holder(textView);
}
@Override
public void onBindViewHolder(Holder holder, int position) {
Log.d("aaaa", "onBindViewHolder "+position);
holder.textView.setText("" + position);
}
@Override
public int getItemCount() {
return 10000;
}
});
//holder
class Holder extends RecyclerView.ViewHolder {
TextView textView;
public Holder(View itemView) {
super(itemView);
textView = (TextView) itemView;
}
}
用layout_marginTop模擬頁(yè)面上部分的固定高度沧踏。
當(dāng)軟鍵盤打開的就會(huì)看到onCreateViewHolder被大量調(diào)用
總結(jié):這應(yīng)該是RecyclerView的一個(gè)bug。當(dāng)其被嵌套在RelativeLayout中時(shí)如果沒(méi)有展示空間則其onMeasure得到的高度就會(huì)出錯(cuò)巾钉。簡(jiǎn)單的解決辦法就是RelativeLayout換成FrameLayout翘狱。
至于其內(nèi)部的具體原因沒(méi)有去深究。僅此記錄