在我的适配器类的onCreateViewHolder
中我将屏幕的整体高度分布在我喜欢的项目上:
@Override
public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_card, parent, false);
// float weight = 1 / (mCards.size() * 1.0f);
// LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, weight);
// view.setMinimumHeight(params.height);
int height = parent.getMeasuredHeight() / mCards.size();
view.setMinimumHeight(height - 15);
return new ViewHolder(view, listener);
}
但是当我致电adapter.notifyDataSetChanged()
时,只有新项目获得新的高度。所有其他(已经存在的)物品都坚持旧的高度。
我应该在何处移动高度计算,以便在更新数据集时进行检查?
答案 0 :(得分:1)
在RecyclerView中,当创建新视图对象并将其附加到父视图时, onCreateViewHolder()会被调用,当视图离开时会调用 onBindViewHolder()滚动屏幕,屏幕上出现新视图。
RecyclerAdapter.java
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder>{
private Context context;
private ArrayList<String> months = new ArrayList<>();
public RecyclerAdapter(Context context, ArrayList<String> months){
this.context = context;
this.months = months;
}
@Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View vi = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
Log.d("RECYCLER_CALLBACKS", "onCreateViewHolder() " + parent.getChildCount());
return new ViewHolder(vi);
}
@Override
public void onBindViewHolder(RecyclerAdapter.ViewHolder holder, int position) {
holder.month.setText(months.get(position));
Log.d("RECYCLER_CALLBACKS", "onBindViewHolder() " + months.get(holder.getAdapterPosition()));
}
@Override
public void onViewRecycled(ViewHolder holder) {
super.onViewRecycled(holder);
Log.d("RECYCLER_CALLBACKS", "onViewRecycled() " + months.get(holder.getAdapterPosition()));
}
@Override
public int getItemCount() {
return months.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private CardView cardView;
private TextView month;
private TextView date;
public ViewHolder(View itemView) {
super(itemView);
cardView = (CardView) itemView.findViewById(R.id.cardView);
month = (TextView) itemView.findViewById(R.id.textView2);
date = (TextView) itemView.findViewById(R.id.textView3);
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Button button;
private RecyclerView recyclerView;
private LinearLayoutManager layoutManager;
private RecyclerAdapter adapter;
private static int MONTH_COUNT = 1;
private ArrayList<String> monthsList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
monthsList.add("January");
monthsList.add("February");
monthsList.add("March");
monthsList.add("April");
monthsList.add("May");
monthsList.add("June");
monthsList.add("July");
monthsList.add("August");
monthsList.add("September");
monthsList.add("October");
monthsList.add("November");
monthsList.add("December");
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
adapter = new RecyclerAdapter(this, monthsList);
recyclerView.setAdapter(adapter);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
monthsList.add("New Month " + MONTH_COUNT);
MONTH_COUNT++;
adapter.notifyDataSetChanged();
}
});
}
}
08-26 21:32:23.547 28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onCreateViewHolder()0
08-26 21:32:23.557 28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onCreateViewHolder()1
08-26 21:32:23.557 28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onBindViewHolder()二月
08-26 21:32:23.563 28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onCreateViewHolder()2
08-26 21:32:23.563 28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onBindViewHolder()March
08-26 21:32:23.569 28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onCreateViewHolder()3
08-26 21:32:23.569 28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onBindViewHolder()4月
08-26 21:32:23.575 28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onCreateViewHolder()4
08-26 21:32:23.575 28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onBindViewHolder()可能
08-26 21:32:23.581 28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS:onCreateViewHolder()5
08-26 21:32:23.581 28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS:onBindViewHolder()June
最初,在创建视图时,会为每个视图调用onCreateViewHolder()和onBindViewHolder()。当我们向下滚动到底部
08-26 21:37:36.579 28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onCreateViewHolder()6
28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onBindViewHolder()7月
28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onCreateViewHolder()7
28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onBindViewHolder()八月
28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onCreateViewHolder()7
28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onBindViewHolder()9月
28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onCreateViewHolder()7
28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onBindViewHolder()十月
28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onViewRecycled()1月
28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onBindViewHolder()11月
28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onViewRecycled()二月
28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onBindViewHolder()12月
28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onViewRecycled()March
因此, onCreateViewHolder()在第8个视图后停止调用,而是调用 onViewRecycled(),它使用相同的视图,而不是屏幕创建一个新视图。 现在,当我们回滚到顶部时:
08-26 21:54:20.262 28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onBindViewHolder()March
08-26 21:54:20.784 28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onViewRecycled()12月
08-26 21:54:21.471 28518-28518 / com.stabstudio.aftera nimation D / RECYCLER_CALLBACKS: onBindViewHolder()二月
08-26 21:54:21.835 28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onViewRecycled()11月
08-26 21:54:22.277 28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onBindViewHolder()1月
08-26 21:54:26.050 28518-28518 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onViewRecycled()十月
当我们向上滚动时,12月首先退出屏幕,3月进入屏幕。所以,
现在,当我们创建一个新月时,我们调用 notifyDataSetChanged()来报告对适配器的更改:
2597-2597 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onViewRecycled()5 2597-2597 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS:onViewRecycled()4 2597-2597 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onViewRecycled()3 2597-2597 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS:onViewRecycled() - 1 2597-2597 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onViewRecycled()-1 2597-2597 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS:onViewRecycled() - 1 2597-2597 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onViewRecycled()-1 2597-2597 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS:onViewRecycled() - 1 2597-2597 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onViewRecycled()-1 2597-2597 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS:onBindViewHolder()7月 2597-2597 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onBindViewHolder()8月2597-2597 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS:onBindViewHolder()9月 2597-2597 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onBindViewHolder()10月2597-2597 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS:onBindViewHolder()11月 2597-2597 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onCreateViewHolder()5 2597-2597 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS:onBindViewHolder()12月 2597-2597 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS: onCreateViewHolder()6 2597-2597 / com.stabstudio.afteranimation D / RECYCLER_CALLBACKS:onBindViewHolder()新月1
调用 notifyDataSetChanged()后,所有视图都会被回收, onCreateViewHolder()会再次被调用显示的项目数量在屏幕+ 2 。屏幕底部1,屏幕底部1,不可见。在这种情况下,无论 RecyclerView 中有多少项,它只有8次。
所以,你应该将高度计算移动到 onBindViewHolder(),它将被调用所有视图而不是onCreateViewHolder(),它只被调用的次数与屏幕中可见的项目数一样多