제가 지적 할 수없는 이상한 문제가 있습니다. 내 앱은 웹 사이트에서 영화 데이터, 특히 포스터 이미지를 가져옵니다. 필자는 RecyclerView를 만들었습니다.이 RecyclerView는 2 열 그리드의 모든 포스터를 표시합니다.RecyclerView 스크롤 할 때 모든 ViewHolders를 만들고 바인딩합니다.
스크롤링 환경이 지루하고, 데이터 목록에 변경 사항이 없는데도 항목이 중간 스크롤 위치를 바꿀 수 있습니다.
내가 응용 프로그램을 디버깅 시도하고, 내 어댑터가 내 목록에 모든 항목에 대한 onCreateViewHolder (...)를 호출 할 것이다) 처음에 나는 notifyDataSetChanged를 (전화 것을 알아 냈다 (약 90 배, 경우에만 6 개 포스터 주어진 순간에 볼 수 있습니다.) onBindViewAdapter (...)도 마찬가지입니다. 그런 다음 스크롤 할 때 모든 ViewHolders를 다시 만들고 다시 바인딩합니다!나는 내 코드를 반복해서 확인 했으므로 그 원인을 파악하지 못했습니다. 귀하의 도움을 크게 주시면 감사하겠습니다.
RecyclerView.adapter :
public class MovieRecyclerViewAdapter extends RecyclerView.Adapter<MovieRecyclerViewAdapter.ViewHolder> {
private final Cinema cinema;
private final List<Movie> movies;
private final Context context;
private final DisplayMetrics displayMetrics;
private final Picasso picasso;
public MovieRecyclerViewAdapter(Context context, Cinema cinema, List<Movie> movies) {
this.context = context;
this.cinema = cinema;
this.movies = movies;
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
displayMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(displayMetrics);
// Set up Picasso with okHttp3
okhttp3.OkHttpClient okHttp3Client = new okhttp3.OkHttpClient();
OkHttp3Downloader okHttp3Downloader = new OkHttp3Downloader(okHttp3Client);
picasso = new Picasso.Builder(context)
.downloader(okHttp3Downloader)
.build();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.fragment_movies, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
Movie movie = movies.get(position);
int imgViewWidth = displayMetrics.widthPixels/2;
int imgViewHeight = (int)(imgViewWidth * 1.4);
picasso.with(context)
.load(cinema.getPosterUrl(movie))
.resize(imgViewWidth, imgViewHeight)
.into(holder.imageView);
}
@Override
public int getItemCount() {
return movies.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ImageView imageView;
public ViewHolder(View view) {
super(view);
this.imageView = (ImageView) view.findViewById(R.id.fragment_movies_poster);
}
}
}
RecyclerView 항목 레이아웃 :
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_movies_poster"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ImageView>
RecyclerView의 XML 정의 :
<android.support.v7.widget.RecyclerView
android:id="@+id/fragment_movies_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/fragment_movies" />
RecyclerView 구성, 설정 어댑터 :
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_movies_grid, container, false);
Context context = view.getContext();
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.fragment_movies_recycler_view);
recyclerView.setLayoutManager(new GridLayoutManager(context, columnCount));
movies = new ArrayList<>();
adapter = new MovieRecyclerViewAdapter(context, cinema, movies);
recyclerView.setAdapter(adapter);
recyclerView.setHasFixedSize(true);
fetchMovies(view); // Populates movies list
return view;
}
편집
내가 비슷한 질문 발견이 질문을 게시 이후 : 나는 오히려 "wrap_content"보다 고정 된 값으로 항목 layout_height를 설정하면, 실제로 Android RecyclerView Creates and Binds all the views on Dataset change
를 문제가 해결 . 분명히 RecyclerView는 높이를 결정하기 위해 모든 뷰를 생성하려고 시도합니다.
그러나이 질문에서 제공하는 솔루션을 시도했지만 layoutManager의 lm.setAutoMeasureEnabled(false)
을 layout_height를 "wrap_content"로 설정하여 문제가 지속되었습니다. 이 문제가 발생하지 않는데 어떻게 적응 형 layout_height를 가질 수 있습니까?
은 여기 – Divers
@Divers 귀하의 요청에 따라 코드를 추가 솔루션을 볼 좋을 것이다. –