RecyclerView采坑记录

1.在调用Adapter的notifyDataSetChanged后,看下面代码的注释:

/**
 * Notify any registered observers that the data set has changed.
 *
 * <p>There are two different classes of data change events, item changes and structural
 * changes. Item changes are when a single item has its data updated but no positional
 * changes have occurred. Structural changes are when items are inserted, removed or moved
 * within the data set.</p>
 *
 * <p>This event does not specify what about the data set has changed, forcing
 * any observers to assume that all existing items and structure may no longer be valid.
 * LayoutManagers will be forced to fully rebind and relayout all visible views.</p>
 *
 * <p><code>RecyclerView</code> will attempt to synthesize visible structural change events
 * for adapters that report that they have {@link #hasStableIds() stable IDs} when
 * this method is used. This can help for the purposes of animation and visual
 * object persistence but individual item views will still need to be rebound
 * and relaid out.</p>
 *
 * <p>If you are writing an adapter it will always be more efficient to use the more
 * specific change events if you can. Rely on <code>notifyDataSetChanged()</code>
 * as a last resort.</p>
 *
 * @see #notifyItemChanged(int)
 * @see #notifyItemInserted(int)
 * @see #notifyItemRemoved(int)
 * @see #notifyItemRangeChanged(int, int)
 * @see #notifyItemRangeInserted(int, int)
 * @see #notifyItemRangeRemoved(int, int)
 */
public final void notifyDataSetChanged() {
    mObservable.notifyChanged();
}

可以看出,在调用notifyDataSetChanged后,调用Recyclerview的getChildAdapterPosition(view)就会返回-1,这时要使用getChildLayoutPosition(view)可以拿到layout之前的对应view的位置,getChildAdapterPosition(view)和getChildLayoutPosition(view)本质上调用的是ViewHolder的getAdapterPosition()和getLayoutPosition()方法。二者区别如下:

(1)getLayoutPosition():返回的一直是界面上呈现的 Item 的位置信息,即使某个 Item 已经从数据源中被移除。

(2)getAdapterPosition():当数据源发生变化,且界面已经刷新过后即 onBindViewHolder() 已经被调用了后,返回的值跟 getLayoutPosition() 一致;但当数据源发生变化,且在 onBindViewHolder() 被调用之前,如果调用了 notifyDataSetChanged(), 那么将返回无效的位置标志 -1;如果调用了 notifyItem系列(),那么将返回 Item 在数据源中的位置信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的搜索界面,包括SearchView和RecyclerView,可以保存搜索历史记录。 首先,我们需要在布局文件中添加SearchView和RecyclerView: ``` <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <SearchView android:id="@+id/searchView" android:layout_width="match_parent" android:layout_height="wrap_content" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> ``` 接下来,我们需要创建一个适配器来显示搜索历史记录: ``` public class HistoryAdapter extends RecyclerView.Adapter<HistoryAdapter.ViewHolder> { private List<String> mList; private OnItemClickListener mListener; public HistoryAdapter(List<String> list, OnItemClickListener listener) { mList = list; mListener = listener; } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_history, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { String item = mList.get(position); holder.textView.setText(item); holder.itemView.setOnClickListener(v -> { if (mListener != null) { mListener.onItemClick(item); } }); } @Override public int getItemCount() { return mList.size(); } public static class ViewHolder extends RecyclerView.ViewHolder { TextView textView; public ViewHolder(@NonNull View itemView) { super(itemView); textView = itemView.findViewById(R.id.textView); } } public interface OnItemClickListener { void onItemClick(String text); } } ``` 然后,我们需要在MainActivity中设置SearchView和RecyclerView,并实现保存搜索历史记录的逻辑: ``` public class MainActivity extends AppCompatActivity implements HistoryAdapter.OnItemClickListener { private SearchView mSearchView; private RecyclerView mRecyclerView; private HistoryAdapter mAdapter; private List<String> mHistoryList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mSearchView = findViewById(R.id.searchView); mRecyclerView = findViewById(R.id.recyclerView); mHistoryList = new ArrayList<>(); mAdapter = new HistoryAdapter(mHistoryList, this); mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); mRecyclerView.setAdapter(mAdapter); mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { // 在这里处理搜索逻辑 if (!mHistoryList.contains(query)) { mHistoryList.add(0, query); mAdapter.notifyDataSetChanged(); } return true; } @Override public boolean onQueryTextChange(String newText) { return false; } }); } @Override public void onItemClick(String text) { mSearchView.setQuery(text, true); } } ``` 最后,我们还需要添加一个item_history布局文件,用于显示搜索历史记录: ``` <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" android:textSize="16sp" /> ``` 这样,我们就完成了一个简单的搜索界面,包括SearchView和RecyclerView,可以保存搜索历史记录
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值