更新循环视图与DiffUtil和AsyncListDiffer不工作



我使用DiffUtilAsyncListDifferFragment中创建RecyclerView,因为我不想使用notifyDataSetChanged()方法。但我在使用这种方法时遇到了一个问题。我试图从数据库中检索项目,但每次数据变化(增加)UI不会直接更新。我必须先关闭我的应用程序,然后再打开它,或者去另一个类检查更新的项目。

这是我的适配器:
public class AdapterSaham extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements SectionIndexer, SearchFilter {
public static final int SECTION_VIEW = 0;
public static final int CONTENT_VIEW = 1;
List<DaftarSaham> daftarSahamList;
private ArrayList<Integer> mSectionPositions;
private static int  lastClicked = -1;
WeakReference<Context> mContextWeakReference;
private ItemClickListener itemClickListener;
private int lastPosition = -1;
int row_index = -1;
public AdapterSaham(ArrayList<DaftarSaham> daftarSaham, Context context, ItemClickListener clickListener){
this.daftarSahamList = daftarSaham;
this.mContextWeakReference = new WeakReference<Context> ( context );
this.itemClickListener = clickListener;
}
private static final DiffUtil.ItemCallback<DaftarSaham> DIFF_CALLBACK = new DiffUtil.ItemCallback<DaftarSaham> () {
@Override
public boolean areItemsTheSame(@NonNull DaftarSaham oldItem, @NonNull DaftarSaham newItem) {
return newItem.getTicker ().equals ( oldItem.getTicker () ) && newItem.getCompanyName ().equals ( newItem.getCompanyName () );
}
@SuppressLint("DiffUtilEquals")
@Override
public boolean areContentsTheSame(@NonNull DaftarSaham oldItem, @NonNull DaftarSaham newItem) {
return newItem.equals ( oldItem );
}
};
private  AsyncListDiffer<DaftarSaham> differ = new AsyncListDiffer<DaftarSaham> (this, DIFF_CALLBACK  );
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Context ctx = mContextWeakReference.get ();
View view = LayoutInflater.from ( parent.getContext () ).inflate ( R.layout.list_item,parent,false  );


return new ItemViewHolder ( view, ctx , itemClickListener);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
Context ctx = mContextWeakReference.get ();
if (ctx == null){
return;
}

ItemViewHolder itemViewHolder= (ItemViewHolder) holder;
DaftarSaham daftarSaham =  differ.getCurrentList ().get ( position);
itemViewHolder.txtTickerSaham.setText ( daftarSaham.getTicker () );
itemViewHolder.txtCompanyName.setText ( daftarSaham.getCompanyName () );
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
private TextView txtTickerSaham, txtCompanyName;
private LinearLayout cardView;
ItemClickListener itemClickListener;
public ItemViewHolder(@NonNull View itemView, final Context context, ItemClickListener itemClickListener) {
super ( itemView );
txtTickerSaham = (TextView) itemView.findViewById ( R.id.tickerSaham );
txtCompanyName = (TextView) itemView.findViewById ( R.id.tv_company_name );
cardView = (LinearLayout) itemView.findViewById ( R.id.cvRecycler );
this.itemClickListener = itemClickListener;
}
}
@Override
public int getItemCount() {
return differ.getCurrentList ().size ();
}
public void submitList(List<DaftarSaham> newdataList){
differ.submitList ( newdataList );
daftarSahamList = new ArrayList<> (newdataList);
}

代码片段:

ViewGroup.LayoutParams params=recyclerViewIndexer.getLayoutParams();
params.height= h;
recyclerViewIndexer.setLayoutParams(params);
recyclerViewIndexer.setHasFixedSize ( true );
recyclerViewIndexer.setLayoutManager ( new LinearLayoutManager ( getContext ()) );
StringRequest stringRequest = new StringRequest ( Request.Method.GET, URL,
new Response.Listener<String> () {
@Override
public void onResponse(String response) {
ArrayList<HashMap<String,String>> list = new ArrayList<> ();
try {
JSONObject jsonObject = new JSONObject (response);
JSONArray jsonArray = jsonObject.getJSONArray ( "data_emiten" );
for(int i = 0; i < jsonArray.length (); i++){
JSONObject jo = jsonArray.getJSONObject ( i );
String ticker = jo.getString ( "ticker" );
String companyName = jo.getString ( "companyName" );
daftarNonSection.add ( new DaftarSaham (ticker, companyName, false) );
}
} catch (JSONException e) {
e.printStackTrace ();
}
getHeaderListLetter ( daftarSahamList,daftarNonSection );
adapterSaham = new AdapterSaham ( daftarSahamList, getContext (), new AdapterSaham.ItemClickListener () {
@Override
public void onItemClick(Integer numbers, boolean isSelected) {
String ticker = "";
if (isSelected ){
ticker = daftarSahamList.get ( Integer.valueOf ( numbers) ).ticker;
}
SlidingTab slidingTab = (SlidingTab) getActivity ();
slidingTab.setTicker (ticker);
}
} );
recyclerViewIndexer.setAdapter ( adapterSaham );
adapterSaham.submitList ( daftarSahamList );
Log.d ( "TAG", "onResponse: "+ response );
}
},
new Response.ErrorListener () {
@Override
public void onErrorResponse(VolleyError error) {
Log.d ( "TAG", "onErrorResponse: "+error );
}
} );
int socketTimeOut = 50000;
RetryPolicy policy = new DefaultRetryPolicy (socketTimeOut, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
stringRequest.setRetryPolicy ( policy );
RequestQueue requestQueue = Volley.newRequestQueue ( getContext () );
requestQueue.add ( stringRequest );
}

我的模型:

public class DaftarSaham implements Comparable<DaftarSaham> {
public String ticker;
public String companyName;
public boolean isSection;
private boolean isSelected = false;
public DaftarSaham() {
}
public DaftarSaham(String ticker, String companyName, boolean isSection) {
this.ticker = ticker;
this.companyName = companyName;
this.isSection = isSection;
}
public String getCompanyName() {
return companyName;
}
public void setTicker(String ticker) {
this.ticker = ticker;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}

public String getTicker() {
return ticker;
}
}

我不知道为什么它不工作,因为我以前尝试过使用DiffUtilAsyncListDiffer,没有问题。任何帮助或建议将是伟大的。提前谢谢。

就我从你的代码中看到的,你可能滥用了DiffUtil.ItemCallbackareItemsTheSame(int oldItemPosition, int newItemPosition)的目的是决定两个对象是否代表相同的项目但在你的代码中,你使用.equals方法,这是用于内容比较。在areItemsTheSame中,您应该检查条目id是否相等,因为您没有id,所以您可以简单地通过使用tickerstring来进行检查,但要注意,如果两个项目具有相同的ticker,则两个项目将匹配:

public boolean areItemsTheSame(@NonNull DaftarSaham oldItem, @NonNull DaftarSaham newItem) {
return newItem.getTicker() == oldItem.getTicker()
}

不同的是,areContentsTheSame检查两个条目是否具有相同的数据,并且只有当areItemsTheSame返回true时才调用此方法。在这里,您可能应该检查新旧项之间的类属性是否匹配,例如:

public boolean areContentsTheSame(@NonNull DaftarSaham oldItem, @NonNull DaftarSaham newItem) {
return (newItem.getTicker() == oldItem.getTicker()) && (newItem.getCompanyName() == oldItem.getCompayName())
}

请注意,areContentsTheSame业务逻辑由您决定,根据您确定的属性作为内容的一部分。标准的方法是使用.equals()方法,但似乎不是你的情况。

public boolean areContentsTheSame(@NonNull DaftarSaham oldItem, @NonNull DaftarSaham newItem) {
return (newItem.equals(oldItem))
}

您需要执行此步骤。花了很长时间后,我发现这是因为空清单。更新列表时这样做::

fun updateList(updatedList: List<Notification>) {
if (updatedList.isEmpty()) {
differ.submitList(emptyList())
return
}
differ.submitList(updatedList)
}

最新更新