我正在构建我的第一个项目(阅读 18+ 内容)并且我想添加某种分页(当用户向下滚动到底部时,它会生成更多图像)并且我注意到当我调用 adapter.notifyDataSetChanged()在执行后,我的适配器中的每个项目都在刷新,这导致了很多滞后(我有超过一千张图像要显示)。我想避免这种情况,只刷新添加的新项目。
这是我的代码:
主类:
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.widget.ProgressBar;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.widget.NestedScrollView;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Objects;
public class MangaList extends AppCompatActivity {
private MangaListAdapter adapter;
private ArrayList<MangaListParseItem> Mangas = new ArrayList<>();
private ProgressBar progressBar;
private RecyclerView recyclerView;
private NestedScrollView nestedScrollView;
Content content = new Content();
int pagelimit = 5, page = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mangalist_recyclerview);
progressBar = findViewById(R.id.progressBar);
recyclerView = findViewById(R.id.recycler_view);
nestedScrollView = findViewById(R.id.idNestedSV);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL));
adapter = new MangaListAdapter(this, Mangas);
recyclerView.setAdapter(adapter);
content.execute();
nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(@NonNull NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
if (scrollY == v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight()) {
page = page + 5;
pagelimit = pagelimit + 5;
Content test = new Content();
test.execute();
}
}
});
}
private class Content extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
progressBar.setVisibility(View.VISIBLE);
progressBar.startAnimation(AnimationUtils.loadAnimation(MangaList.this, android.R.anim.fade_in));
}
@Override
protected void onPostExecute(Void unused) {
super.onPostExecute(unused);
progressBar.setVisibility(View.GONE);
progressBar.startAnimation(AnimationUtils.loadAnimation(MangaList.this, android.R.anim.fade_out));
adapter.notifyItemRangeInserted(Mangas.size() - 5*24, 120);
}
@Override
protected void onCancelled() {
super.onCancelled();
}
@Override
protected Void doInBackground(Void... voids) {
try {
String website = "https://allporncomic.com/porncomic-genre/hentai";
Document mainpage = Jsoup.connect(website).userAgent("Chrome").get();
Elements pagecontent = mainpage.getElementsByClass("wp-pagenavi");
String href = pagecontent.select("a.last").attr("href");
Document lastpage = Jsoup.connect(href).userAgent("Chrome").get();
Elements page2 = lastpage.getElementsByClass("wp-pagenavi");
String href2 = Objects.requireNonNull(page2.select("span").last()).text();
int numpages = Integer.parseInt(href2);
if (pagelimit < numpages) {
for(int i = page; i <= pagelimit; i++) {
Document doc = Jsoup.connect(website + "/page/" + i + "/?m_orderby=views").userAgent("Chrome").get();
Elements body = doc.getElementsByClass("page-item-detail manga ");
int size = body.size();
for(int j = 0; j < size; j++) {
String image = body.select("img").eq(j).attr("data-src");
String title = body.select("h3").eq(j).text();
String url = body.select("h3").select("a").eq(j).attr("href");
Mangas.add(new MangaListParseItem(image, title, url));
}
}
}
}
catch (IOException e) {
throw new RuntimeException(e);
}
return null;
}
}
}
适配器和ViewHolder:
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class MangaListAdapter extends RecyclerView.Adapter<MangaListAdapter.MangaListHolder> {
private ArrayList<MangaListParseItem> Mangas;
private Context context;
public MangaListAdapter(Context context, ArrayList<MangaListParseItem> mangaNames) {
this.Mangas = mangaNames;
this.context = context;
}
@NonNull
@Override
public MangaListHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.mangalist_recyclerview_content, parent, false);
return new MangaListHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MangaListHolder holder, int position) {
MangaListParseItem parseItem = Mangas.get(position);
holder.textView_manga_list.setText(parseItem.getTitle());
holder.textView_manga_list.setSelected(false);
Picasso.get().load(parseItem.getImage()).into(holder.imageView_mangaList);
}
@Override
public int getItemCount() {
return Mangas.size();
}
public interface RecyclerViewClickListener{
void onClick(View view, int position);
}
public class MangaListHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView imageView_mangaList;
TextView textView_manga_list;
public MangaListHolder(@NonNull View itemView) {
super(itemView);
imageView_mangaList = itemView.findViewById(R.id.imageView_mangaList);
textView_manga_list = itemView.findViewById(R.id.textView_mangaList);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
int position = getAdapterPosition();
MangaListParseItem parseItem = Mangas.get(position);
Intent intent = new Intent(context, Chapters.class);
intent.putExtra("title", parseItem.getTitle());
intent.putExtra("image", parseItem.getImage());
intent.putExtra("url", parseItem.getUrl());
context.startActivity(intent);
}
}
}
项目解析:
public class MangaListParseItem {
private String image;
private String title;
private String url;
public MangaListParseItem() {
}
public MangaListParseItem(String image, String title, String url) {
this.image = image;
this.title = title;
this.url = url;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
我尝试实现 adapter.notifyItemRangeInserted() 但之后我无法再生成数据,只显示加载。
adapter.notifyItemRangeInserted(Mangas.size() - 5*24, 120)
(我的分页是5页,每页有24本漫画=>总共加了120本)
这是我得到的结果:
W/View: requestLayout() 在布局过程中被 android.widget.ProgressBar{772bf2c V.ED..... ......ID 0,23080-141,23221 #7f080153 app:id/progressBar} 不当调用:运行第二个布局通道
这个问题我有一段时间了,因为我正在制作 18+ 的东西,所以我不想在 StackOverflow 上提问。但是挫败感太高了:/
我真的很想提前感谢你们,任何帮助都会让我开心:)