我有一个看似列表的简单RecyclerView,我将每个视图设置为不同的ID,通过单击第一个视图添加视图,并在单击它们时删除视图(期望第一个视图)。什么不能正常工作是当我删除一个视图然后添加另一个视图时,新视图的ID会破坏顺序。
适配器
public class AddEventsAdapter extends RecyclerView.Adapter<AddEventsAdapter.ViewHolder> {
private List<String> items = new ArrayList<>();
public void addItem(String name) {
items.add(name);
notifyItemInserted(items.size() - 1);
}
public void removeItem(int position) {
items.remove(position);
notifyItemRemoved(position);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.add_event_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
}
@Override
public int getItemCount() {
return items.size();
}
static int i;
class ViewHolder extends RecyclerView.ViewHolder{
public TextView eventName;
public RelativeLayout theLayout;
public ViewHolder(View itemView) {
super(itemView);
eventName = (TextView)itemView.findViewById(R.id.eventName);
theLayout = (RelativeLayout)itemView.findViewById(R.id.backgroundevent);
theLayout.setId(++i);
eventName.setText(String.format("", i));
theLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (v.getId() == 1){
addItem("");
}else {
removeItem(getAdapterPosition());
}
}
});
}
}
}
实施:
final AddEventsAdapter AddContainer = new AddEventsAdapter();
AddEventsRecycler.setLayoutManager(new LinearLayoutManager(this));
AddEventsRecycler.setAdapter(AddContainer);
AddEventsRecycler.setItemViewCacheSize(666);
AddContainer.addItem("");
每一行的布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@drawable/event_clicked_ripple"
android:clickable="true"
android:id="@+id/backgroundevent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp">
<TextView
android:clickable="false"
android:id="@+id/eventName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="something"
android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/eventImage"
android:layout_toStartOf="@+id/eventImage"
android:layout_marginRight="10dp"/>
<ImageButton
android:clickable="false"
android:id="@+id/eventImage"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/oval_shape"/>
</RelativeLayout>
我的问题是,如果我添加5个视图,删除第2个,然后添加另一个,它将再次添加第二个而不是第6个。 所以我认为这里的问题是如何在删除后回收视图?
答案 0 :(得分:1)
RecyclerViews背后的想法是,您在onCreateViewHolder()
中提供的视图持有者可能会被重用于同一viewType
的视图。这种行为使RecyclerViews变得高效 - 浏览视图代价高昂,运行findViewById
代价高昂。
您没有覆盖getItemViewType
,因此您的RecyclerView只有一种视图类型 - 即滚动浏览多个视图并删除/添加视图时,您的ViewHolders可以互相回收。
那么您的代码中发生了什么?删除第二个视图时,其ViewHolder将被回收,并发送回回收站视图池。当您添加视图编号6时,回收站视图将使用编号为2的回收视图持有者。因此,永远不会调用onCreateViewHolder
(因为有一个额外的视图要回收!)。但是,onBindViewHolder
被调用。因此,添加一个方法来更新ViewHolder显示的数据:
public void setData(final int position) {
eventName.setText(String.format("", position));
theLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (position == 1){
addItem("");
}else {
removeItem(position);
}
}
}
并在onBindViewHolder中调用此方法:
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.setData(position);
}
答案 1 :(得分:0)
尝试将removeItem(int position)
更改为
public void removeItem(int position) {
items.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, items.size());
}
它很可能会解决您的问题