Update # 1RecyclerView mit GridLayoutManager und Picasso falsches Bild
Added hasStableIds (true) und aktualisiert Picasso auf Version 2.5.2 zeigt. Es löst das Problem nicht.
Fortpflanzung:
RecyclerView mit GridLayoutManager (spanCount = 3). Listenelemente sind CardViews mit ImageView.
Wenn alle Elemente nicht passen, ruft der Aufruf von notifyItemChanged für einen Eintrag mehr als einen Aufruf von onBindViewHolder() auf. Ein Aufruf bezieht sich auf die Position von notifyItemChanged für Positionen, die auf dem Bildschirm nicht sichtbar sind.
Ausgabe:
Manchmal wird das Element an der Position der notifyItemChanged weitergegeben geladen mit einem Bild zu einem Element gehören, die nicht auf dem Bildschirm (höchstwahrscheinlich auf das Recycling der Ansicht Halter ist - obwohl ich würde Nehmen wir an, dass der übergebene Viewholder derselbe wäre, wenn der Artikel an seinem Platz bleibt.
Ich habe Jakes Kommentar zu einem anderen Thema hier über den Aufruf von load() gefunden, auch wenn die Datei/uri null ist. Das Bild wird hier auf jeden onBindViewHolder geladen.
einfache Beispielanwendung:
git clone https://github.com/gswierczynski/recycler-view-grid-layout-with-picasso.git
Tippen Sie auf ein Element Anrufe notifyItemChanged mit dem Parameter gleich der Position dieses Elements.
Code:
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
}
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
RecyclerView rv = (RecyclerView) rootView.findViewById(R.id.rv);
rv.setLayoutManager(new GridLayoutManager(getActivity(), 3));
rv.setItemAnimator(new DefaultItemAnimator());
rv.setAdapter(new ImageAdapter());
return rootView;
}
}
private static class ImageAdapter extends RecyclerView.Adapter<ImageViewHolder> implements ClickableViewHolder.OnClickListener {
public static final String TAG = "ImageAdapter";
List<Integer> resourceIds = Arrays.asList(
R.drawable.a0,
R.drawable.a1,
R.drawable.a2,
R.drawable.a3,
R.drawable.a4,
R.drawable.a5,
R.drawable.a6,
R.drawable.a7,
R.drawable.a8,
R.drawable.a9,
R.drawable.a10,
R.drawable.a11,
R.drawable.a12,
R.drawable.a13,
R.drawable.a14,
R.drawable.a15,
R.drawable.a16,
R.drawable.a17,
R.drawable.a18,
R.drawable.a19,
R.drawable.a20);
@Override
public ImageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ImageViewHolder(v, this);
}
@Override
public void onBindViewHolder(ImageViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder position: " + position + " | holder obj:" + holder.toString());
Picasso.with(holder.iv.getContext())
.load(resourceIds.get(position))
.fit()
.centerInside()
.into(holder.iv);
}
@Override
public int getItemCount() {
return resourceIds.size();
}
@Override
public void onClick(View view, int position) {
Log.d(TAG, "onClick position: " + position);
notifyItemChanged(position);
}
@Override
public boolean onLongClick(View view, int position) {
return false;
}
}
private static class ImageViewHolder extends ClickableViewHolder {
public ImageView iv;
public ImageViewHolder(View itemView, OnClickListener onClickListener) {
super(itemView, onClickListener);
iv = (ImageView) itemView.findViewById(R.id.iv);
}
}
}
public class ClickableViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
OnClickListener onClickListener;
public ClickableViewHolder(View itemView, OnClickListener onClickListener) {
super(itemView);
this.onClickListener = onClickListener;
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
}
@Override
public void onClick(View view) {
onClickListener.onClick(view, getPosition());
}
@Override
public boolean onLongClick(View view) {
return onClickListener.onLongClick(view, getPosition());
}
public static interface OnClickListener {
void onClick(View view, int position);
boolean onLongClick(View view, int position);
}
}
hast du eine lösung gefunden? Ich habe das gleiche Problem. Passiert das nur mit RecyclerView? Hast du es mit ListView versucht? –
Noch nicht. Da ich mir nicht sicher bin, ob dies ein Problem mit Picasso oder GridLayoutManager ist, habe ich Probleme sowohl auf der PIcasso github Projektseite (https://github.com/square/picasso/issues/954) als auch im AOSP Google Code (https: // code.google.com/p/android/issues/detail?id=162699). Ich glaube nicht, dass dieses Problem auf ListView existiert. – gswierczynski
Haben Sie dieses Problem behoben, ich sehe immer noch, dass dieses Problem in com.squadeup.picasso existiert: picasso: 2.5.2 setSupportsChangeAnimations (false) und setHasStableIds (true) scheinen dies zu verhindern – Harkish