【发布时间】:2017-01-08 05:04:02
【问题描述】:
我想重用一个膨胀的视图,就像 listView 适配器对 convertView 所做的那样。我一直潜伏在适配器的源代码上,没有运气。
我需要根据数据向 recyclerItemView 添加动态视图,现在我根据需要添加视图的次数,但考虑到它在 recyclerView 中,此操作可能会变得非常昂贵,具体取决于数据量和滚动用户的行为。
我的问题的其他解决方案是在 recyclerItem 内创建一个列表视图,因此列表视图不能滚动,根据动态添加的数据展开到最大高度(使列表视图容器展开以显示其所有数据)并使recyclerItem 根据其高度展开。
活动
public class Main1Activity extends AppCompatActivity {
RecyclerView recyclerView;
CustomAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main1);
recyclerView = (RecyclerView) findViewById(R.id.recycler);
setUpRecycler();
}
private void setUpRecycler(){
Sample sample1 = new Sample("List of Items1");
Sample sample2 = new Sample("List of Items2");
Sample sample3 = new Sample("List of Items3");
List<Sample> sampleList = new ArrayList<>();
sampleList.add(sample1);
sampleList.add(sample2);
sampleList.add(sample3);
adapter = new CustomAdapter(this,sampleList);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
}
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="30dp">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
型号
public class Sample {
String name;
public Sample(){}
public Sample(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
XML 项目
**item_list**
<?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="40dp">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
**item_smaple**
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/name"
android:layout_width="120dp"
android:layout_height="40dp"
android:layout_margin="10dp"
android:text="List of Items"
android:textSize="20sp"/>
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:orientation="vertical"/>
</LinearLayout>
适配器
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private List<Sample> mySamples;
private Context mContext;
public CustomAdapter(Context context, List<Sample> mySamples) {
this.mContext = context;
this.mySamples = mySamples;
}
private Context getContext() {
return mContext;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView name;
public LinearLayout linearLayout;
public ViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.name);
linearLayout = (LinearLayout) itemView.findViewById(R.id.linearLayout);
}
}
@Override
public CustomAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View contactView = inflater.inflate(R.layout.item_sample, parent, false);
ViewHolder viewHolder = new ViewHolder(contactView);
return viewHolder;
}
@Override
public void onBindViewHolder(CustomAdapter.ViewHolder holder, int position) {
Sample sample = mySamples.get(position);
holder.name.setText(sample.getName());
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.item_list, null, false);
for (int i = 0; i < 20; i++){
TextView textView = (TextView) v.findViewById(R.id.textView);
textView.setText("hello"+i);
holder.linearLayout.addView(v);
}
}
@Override
public int getItemCount() {
return mySamples.size();
}
}
现在我正在循环内充气。如何修改视图参数以使其可重用于框架?
我的应用在 addView() 上崩溃 -->java.lang.IllegalStateException: 指定的孩子已经有一个父母。您必须先在孩子的父母上调用 removeView()。
【问题讨论】:
-
那么使用 RecyclerView 有什么问题?
-
我的问题是我想膨胀一个复杂的布局并用 addView() 将它添加到线性布局中,所以如果 recycler-item 需要在线性布局内膨胀 4-5 这个布局,这可能会减慢甚至冻结 recyclerview 上的滚动;因为膨胀操作将在回收器项填充和清空视图时执行大量次,并且膨胀它是一个成本高昂的操作,如果可能的话,列表小部件会避免重复。现在我会很容易地在每个回收站做 2-3 次。
-
是的,膨胀视图是一项昂贵的操作,这就是他们制作 ListView/RecyclerView 的原因,这样它就不会每次都膨胀视图,但它会重用它们并绑定数据
-
如果你读了第三个段落,你可以看到我已经考虑过了,但是我调查了一个列表视图,它的行为就像我需要但没有运气,所以我想自己膨胀视图,如果你知道如何创建我需要的列表视图(3 段)只需创建一个答案,这样我就可以检查它是否正确,谢谢您的时间:)
标签: android performance android-layout listview android-inflate