如何增强和提高回收器的性能查看适配器



我有这个适配器,到目前为止工作得很好,但我在上面做了一些糟糕的练习代码,比如:-在OnBindView中使用onClickListener。

  • 使用GC清理内存,这也是一种糟糕的做法
  • 我已经为适配器设置了一个列表和其他列表,以便在滚动时加载。是这样吗?或者我应该在设置适配器之前加载所有需要的列表
  • 当更新适配器时,我通常会为notifyDataSetChanged设置一个新的适配器,因为它并不总是有效的
  • 注意整个项目,我有一个类别适配器,它设置itemViewAdapter
  • itemViewAdapter设置colorItemsAdapter(如果项有多个颜色)

我需要提高代码的性能,因为我觉得它在滚动大量数据时会变得滞后。

这是itemViewAdapter的代码:

public class ItemViewAdapter extends RecyclerView.Adapter<ItemViewAdapter.imagesHolder> {
List<iItem> Items;
Context context;
ExecutorService pool;
boolean isAdmin;
public ItemViewAdapter(List<iItem> items) {
Items = items;
}
@NonNull
@Override
public ItemViewAdapter.imagesHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_main_items, parent, false);
context = parent.getContext();
isAdmin = ((Activity) context).getIntent().getBooleanExtra("isAdmin", false);
return new imagesHolder(view);
}
@Override
public void onBindViewHolder(@NonNull imagesHolder holder, int position) {
if (pool == null) {
pool = Executors.newFixedThreadPool(10);
}
pool.execute(() -> {
holder.colorItems = iItemDatabase.getDB(context).iItemDAO().getColorItems(Items.get(holder.getAdapterPosition()).getItemID());
if (holder.colorItems != null) {
if (holder.colorItems.size() != 0) {
holder.tvItemName.setText(holder.colorItems.get(0).getItemName());
if (holder.colorItems.get(0).getItemBPrice().equals("0")) {
holder.tvItemPriceB.setVisibility(View.INVISIBLE);
} else {
holder.tvItemPriceB.setText(holder.colorItems.get(0).getItemBPrice() + " L.E");
}
holder.tvItemPriceA.setText(holder.colorItems.get(0).getItemAPrice() + " L.E");
pool.execute(() -> {
holder.getImages = (List<iItemImages>) iItemDatabase.getDB(context).iItemImagesDAO().getImages(holder.colorItems.get(0).getItemID());
holder.semaphore.release();
});
holder.semaphore.acquireUninterruptibly();
((Activity) context).runOnUiThread(() -> {
if (holder.getImages.size() != 0) {
holder.tvImageSize.setText("1/" + holder.getImages.size());
holder.imageAdapter = new ImageAdapter(holder.getImages, isLongCLick -> {
if (!isLongCLick) {
onImageClick(holder.colorItems.get(holder.colorItemPosition).getItemID());
} else {
if (isAdmin) {
onImageLongClick(holder.btnAddColor, holder.btnEdit, holder.btnDelete, holder.btnDeleteAll,
holder.colorItems, holder.colorItemPosition, holder.alertDialog);
}
}
});
holder.rvItemImages1.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false));
holder.rvItemImages1.setAdapter(holder.imageAdapter);
if (holder.getImages.size() > 1) {
if (holder.handler == null) {
holder.handler = new Handler(Looper.getMainLooper());
holder.handler.postDelayed(holder.runnable, 4000);
}
}
}
holder.semaphore.release();
});
holder.semaphore.acquireUninterruptibly();
if (holder.colorItems.size() >= 1) {
holder.imagesURL.clear();
for (iItem colorItem : holder.colorItems) {
holder.imagesURL.addAll(iItemDatabase.getDB(context).iItemImagesDAO().getFirstImageURL(colorItem.getItemID()));
}
holder.colorItemsAdapter = new ColorItemsAdapter(holder.colorItems, holder.imagesURL, position1 -> {
holder.colorItemPosition = position1;
holder.tvItemName.setText(holder.colorItems.get(position1).getItemName());
if (holder.colorItems.get(position1).getItemBPrice().equals("0")) {
holder.tvItemPriceB.setVisibility(View.INVISIBLE);
} else {
holder.tvItemPriceB.setText(holder.colorItems.get(position1).getItemBPrice() + " L.E");
}
holder.tvItemPriceA.setText(holder.colorItems.get(position1).getItemAPrice() + " L.E");
pool.execute(() -> {
holder.getImages = (List<iItemImages>) iItemDatabase.getDB(context).iItemImagesDAO().getImages(holder.colorItems.get(position1).getItemID());
holder.semaphore.release();
});
holder.semaphore.acquireUninterruptibly();
if (holder.getImages.size() != 0) {
holder.tvImageSize.setText("1/" + holder.getImages.size());
holder.imageAdapter = new ImageAdapter(holder.getImages, isLongCLick -> {
if (!isLongCLick) {
onImageClick(holder.colorItems.get(holder.colorItemPosition).getItemID());
} else {
if (isAdmin) {
onImageLongClick(holder.btnAddColor, holder.btnEdit, holder.btnDelete, holder.btnDeleteAll,
holder.colorItems, holder.colorItemPosition, holder.alertDialog);
}
}
});
holder.rvItemImages1.setAdapter(holder.imageAdapter);
if (holder.getImages.size() > 1) {
if (holder.handler == null) {
holder.handler = new Handler(Looper.getMainLooper());
holder.handler.postDelayed(holder.runnable, 4000);
}
}
}
holder.colorItemsAdapter.notifyDataSetChanged();
});
((Activity) context).runOnUiThread(() -> {
holder.rvColorItems.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false));
holder.rvColorItems.setAdapter(holder.colorItemsAdapter);
holder.semaphore.release();
});
holder.semaphore.acquireUninterruptibly();
Runtime.getRuntime().gc();
}
}
}
holder.rvItemImages1.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull @NotNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
holder.tvImageSize.setText((((LinearLayoutManager) Objects.requireNonNull(recyclerView.getLayoutManager())).findFirstVisibleItemPosition() + 1) + "/" + Objects.requireNonNull(recyclerView.getAdapter()).getItemCount());
}
}
});
});
Runtime.getRuntime().gc();
}
void onImageClick(String ItemID) {
Fragment fragment = new ItemsFragment2();
Bundle bundle = new Bundle();
bundle.putString("selectedItem", ItemID);
fragment.setArguments(bundle);
FragmentManager fragmentManager = ((AppCompatActivity) context).getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment fragment1 = fragmentManager.findFragmentByTag("ItemsFragment1");
fragmentTransaction.hide(fragment1);
fragmentTransaction.add(R.id.fl_MainItems, fragment, "ItemsFragment2").addToBackStack(null);
fragmentTransaction.commit();
}
void onImageLongClick(Button btnAddColor, Button btnEdit, Button btnDelete, Button btnDeleteAll,
List<iItem> colorItems, int colorItemPosition, AlertDialog alertDialog) {
Semaphore semaphore = new Semaphore(0);
btnAddColor.setOnClickListener(v1 -> {
Intent in = new Intent(context, AEDItem.class);
in.putExtra("type", (byte) 3);
in.putExtra("itemID", colorItems.get(0).getItemID());
in.putExtra("colorID", colorItems.get(0).getColorID());
context.startActivity(in);
alertDialog.dismiss();
});
btnEdit.setOnClickListener(v1 -> {
Intent in = new Intent(context, AEDItem.class);
in.putExtra("type", (byte) 2);
in.putExtra("itemID", colorItems.get(colorItemPosition).getItemID());
in.putExtra("colorID", colorItems.get(colorItemPosition).getColorID());
in.putExtra("itemName", colorItems.get(colorItemPosition).getItemName());
context.startActivity(in);
alertDialog.dismiss();
});
btnDelete.setOnClickListener(v12 -> {
pool.execute(() -> {
saveAdminUpdate(context,true);
iItemDatabase.getDB(context).iItemDAO().DeleteItem(colorItems.get(colorItemPosition).getItemID());
iItemDatabase.getDB(context).iItemImagesDAO().DeleteItemImage(colorItems.get(colorItemPosition).getItemID());
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection("Items").document(colorItems.get(colorItemPosition).getItemID())
.delete()
.addOnSuccessListener(aVoid ->
{
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReference();
StorageReference desertRef = storageRef.child("itemImages/" + colorItems.get(colorItemPosition).getItemID());
Task<ListResult> listResultTask = desertRef.listAll();
listResultTask.addOnSuccessListener(listResult -> {
for (StorageReference item : listResult.getItems()) {
item.delete().addOnSuccessListener(l -> {
});
}
});
semaphore.release();
});
semaphore.acquireUninterruptibly();
final int[] ExternalVersion = {retrieveVersion(context)};
if (ExternalVersion[0] == 0) {
// not found on shared, get it from server
db.collection("Version").document("items")
.get()
.addOnCompleteListener(task -> {
pool.execute(() -> {
if (task.isSuccessful()) {
if (task.getResult().get("v") != null) {
// if found, add 1 to it
ExternalVersion[0] = Integer.parseInt(task.getResult().get("v").toString());
ExternalVersion[0]++;
} else {
// not found, create it
ExternalVersion[0] = 1;
}
}
semaphore.release(2);
});
});
semaphore.acquireUninterruptibly();
} else {
// found on shared, add 1 to it
ExternalVersion[0]++;
}
// update version on server and local
Map<String, Integer> externalVersion = new HashMap<>();
externalVersion.put("v", ExternalVersion[0]);
db.collection("Version")
.document("items")
.set(externalVersion)
.addOnSuccessListener(documentReference1 -> {
pool.execute(() -> {
saveVersion(context, ExternalVersion[0]);
semaphore.release();
});
});
semaphore.acquireUninterruptibly();
((Activity) context).runOnUiThread(() -> {
View view = View.inflate(context, R.layout.rv_main_items, null);
Snackbar.make(view, "Item deleted successfully", Snackbar.LENGTH_LONG).show();
alertDialog.dismiss();
});
});
});
btnDeleteAll.setOnClickListener(v12 -> {
pool.execute(() -> {
saveAdminUpdate(context,true);
List<String> itemIDs = new ArrayList<>();
for (iItem colorItem : colorItems) {
itemIDs.add(colorItem.getItemID());
}
iItemDatabase.getDB(context).iItemDAO().DeleteItems(itemIDs);
iItemDatabase.getDB(context).iItemImagesDAO().DeleteItemImages(itemIDs);
FirebaseFirestore db = FirebaseFirestore.getInstance();
for (String itemID : itemIDs) {
db.collection("Items").document(itemID)
.delete()
.addOnSuccessListener(aVoid ->
{
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReference();
StorageReference desertRef = storageRef.child("itemImages/" + itemID);
Task<ListResult> listResultTask = desertRef.listAll();
listResultTask.addOnSuccessListener(listResult -> {
for (StorageReference item : listResult.getItems()) {
item.delete().addOnSuccessListener(l -> {
});
}
});
semaphore.release();
});
semaphore.acquireUninterruptibly();
}
itemIDs.clear();
final int[] ExternalVersion = {retrieveVersion(context)};
if (ExternalVersion[0] == 0) {
// not found on shared, get it from server
db.collection("Version").document("items")
.get()
.addOnCompleteListener(task -> {
pool.execute(() -> {
if (task.isSuccessful()) {
if (task.getResult().get("v") != null) {
// if found, add 1 to it
ExternalVersion[0] = Integer.parseInt(task.getResult().get("v").toString());
ExternalVersion[0]++;
} else {
// not found, create it
ExternalVersion[0] = 1;
}
}
semaphore.release(2);
});
});
semaphore.acquireUninterruptibly();
} else {
// found on shared, add 1 to it
ExternalVersion[0]++;
}
// update version on server and local
Map<String, Integer> externalVersion = new HashMap<>();
externalVersion.put("v", ExternalVersion[0]);
db.collection("Version")
.document("items")
.set(externalVersion)
.addOnSuccessListener(documentReference1 -> {
pool.execute(() -> {
saveVersion(context,ExternalVersion[0]);
semaphore.release();
});
});
semaphore.acquireUninterruptibly();
((Activity) context).runOnUiThread(() -> {
View view = View.inflate(context, R.layout.rv_main_items, null);
Snackbar.make(view, "Items deleted successfully", Snackbar.LENGTH_LONG).show();
alertDialog.dismiss();
});
});
});
alertDialog.show();
Runtime.getRuntime().gc();
}
@Override
public int getItemCount() {
return Items.size();
}
class imagesHolder extends RecyclerView.ViewHolder {
TextView tvItemName, tvItemPriceA, tvItemPriceB, tvImageSize;
RecyclerView rvItemImages1, rvColorItems;
Handler handler;
Runnable runnable;
List<iItem> colorItems;
List<iItemImages> getImages;
Semaphore semaphore;
ImageAdapter imageAdapter;
ColorItemsAdapter colorItemsAdapter;
List<String> imagesURL;
int colorItemPosition = 0;
AlertDialog.Builder alert;
View mView;
Button btnAddColor;
Button btnEdit;
Button btnDelete;
Button btnDeleteAll;
AlertDialog alertDialog;

public imagesHolder(@NonNull View itemView) {
super(itemView);
rvItemImages1 = itemView.findViewById(R.id.rvItemImages1);
rvColorItems = itemView.findViewById(R.id.rvColorItems);
tvItemName = itemView.findViewById(R.id.tvItemName);
tvItemPriceA = itemView.findViewById(R.id.tvItemPriceA);
tvItemPriceB = itemView.findViewById(R.id.tvItemPriceB);
tvImageSize = itemView.findViewById(R.id.tvImageSize);
alert = new AlertDialog.Builder(itemView.getContext());
mView = ((Activity) itemView.getContext()).getLayoutInflater().inflate(R.layout.custom_dialog, null);
btnAddColor = mView.findViewById(R.id.btnAddColor);
btnEdit = mView.findViewById(R.id.btnEdit);
btnDelete = mView.findViewById(R.id.btnDelete);
btnDeleteAll = mView.findViewById(R.id.btnDeleteAll);
alert.setView(mView);
alertDialog = alert.create();
imagesURL = new ArrayList<>();
semaphore = new Semaphore(0);
runnable = new Runnable() {
@Override
public void run() {
try {
if ((((LinearLayoutManager) Objects.requireNonNull(rvItemImages1.getLayoutManager())).findFirstVisibleItemPosition() + 1) < Objects.requireNonNull(imageAdapter).getItemCount()) {
rvItemImages1.smoothScrollToPosition((((LinearLayoutManager) rvItemImages1.getLayoutManager()).findFirstVisibleItemPosition() + 1));
} else {
rvItemImages1.smoothScrollToPosition(0);
}
handler.postDelayed(this, 4000);
} catch (Exception ignored) {
}
}
};

Runtime.getRuntime().gc();
}
}

}

您不应该运行数据库查询onBindViewHolder()。适配器应该已经知道这些数据。用数据绑定库替换每个视图持有者上的UI操作,最好一次设置所有数据。首先,删除这个被严重滥用的行:Semaphore semaphore,并学习如何编写异步代码。此外,这通常不是必需的:Runtime.getRuntime().gc(),而且在查看代码的功能时,它不会提高性能。

或者在createViewHolder()中使用isAdmin == true时,只需膨胀一个完全不同的XML。

最新更新