RecyclerView Recycled ViewHolder Image Просмотр неправильного размера

У меня есть просмотр ресайклеров с разными держателями.

У нескольких держателей просмотров есть изображения, которые я передаю в Glide для отображения изображений.

Проблема заключается в том, что, когда представление recycler начинает перерабатывать виды, ширина / высота изображения – это вид переработанного вида, который затем отображает изображение неправильно.

Вот мой ImageView:

<ImageView android:id="@+id/image" android:layout_marginTop="@dimen/feed_item_margin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"/> 

Это передается в Glide

 Glide.with(itemView.getContext()) .load(Uri.parse(MediaUtils .getMedia(feedContent).getMediaUrl())) .placeholder(R.drawable.placeholder) .diskCacheStrategy(DiskCacheStrategy.SOURCE) .crossFade().into(image); 

Это хорошо работает, пока Recyclerview не начнет переработку, поэтому первое изображение в recyclerview выглядит так, как это должно выглядеть.

Введите описание изображения здесь

Однако, когда вы переходите от элемента и прокручиваете назад, он выглядит так:

Введите описание изображения здесь

Таким образом, изображение стало искаженным и не является полной шириной родителя.

Я хочу, чтобы просмотр изображения обертывал контент, потому что все изображения будут разными высотами и т. Д. Чтобы проверить это, я добавил эту строку holder.setIsRecyclable(false); Чтобы предотвратить рециркуляцию этого конкретного держателя, и все изображения, отображаемые как следует, однако, как и ожидалось, это дало эффект jarring.

Поэтому я попытался сбросить параметры изображения в методе OnViewRecycled например:

 @Override public void onViewRecycled(AbstractHolder viewHolder){ super.onViewRecycled(viewHolder); int position = viewHolder.getAdapterPosition(); IFeedContent content = mFeedContentList.get(position); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.setMargins(0, (int) Utils.dpTopx(mContext,10),0,0); params.gravity = Gravity.CENTER; if(isImage(content)){ viewHolder.getImageView().setImageURI(null); viewHolder.getImageView().setImageDrawable(null); viewHolder.getImageView().setImageResource(0); viewHolder.getImageView().setLayoutParams(params); } } 

В этом я воссоздаю params в xml, но он не работает. Метод isImage() это просто проверяет тип изображения объекта.

Может ли кто-нибудь помочь в этом? Это очень расстраивает.

Любая помощь по этому поводу оценивается.

Добавлен адаптер EDIT

 public class ContentFeedAdapter extends RecyclerView.Adapter<AbstractHolder> { private List<IFeedContent> mFeedContentList; private Context mContext; private Activity mMainActivity; private UserHomeFragment mUserHomeFragment; private UserStreamFragment mUserStreamFragment; private AbstractHolder mAbstractHolder; private final Map<YouTubeThumbnailView, YouTubeThumbnailLoader> mThumbnailViewToLoaderMap; private ArrayList<MyMediaPlayer> mMediaPlayerList = new ArrayList<>(); public ContentFeedAdapter(Context ctx, List<IFeedContent> contentList, Activity mainActivity, UserHomeFragment userHomeFragment, UserStreamFragment userStreamFragment){ this.mContext = ctx; this.mFeedContentList = contentList; this.mMainActivity = mainActivity; this.mThumbnailViewToLoaderMap = new HashMap<YouTubeThumbnailView, YouTubeThumbnailLoader>(); this.mUserHomeFragment = userHomeFragment; this.mUserStreamFragment = userStreamFragment; } @Override public AbstractHolder onCreateViewHolder(ViewGroup parent, int viewType) { mAbstractHolder = createAbstractHolder(viewType, parent); return mAbstractHolder; } @Override public void onBindViewHolder(final AbstractHolder holder, final int position) { final IFeedContent content = mFeedContentList.get(position); holder.bindData(content); if((content.getMedia()!=null) && !content.getMedia().isEmpty()){ String mimeType = MediaUtils.getMedia(content).getMimeType(); if(mimeType.contains(mContext.getString(R.string.video)) || mimeType.contains(mContext.getString(R.string.audio)) && !mimeType.contains(mContext.getString(R.string.youtube))){ final ProgressBar progressBar = holder.getProgress(); final ImageView playButton = holder.getPlayImage(); final Button retryButton = holder.getRetryImage(); final RelativeLayout playerOverLay = holder.getPlayerOverlay(); final ImageView mediaThumb = holder.getMediaThumbnail(); final MyMediaPlayer player = new MyMediaPlayer(mContext, holder.getTextureView(), holder.getMediaControllerAnchor(), holder.getProgress(), mimeType, MyConstants.SEEK_TO_DEFAULT, retryButton, playButton, playerOverLay, mediaThumb); player.setRecyclerViewPosition(position); mMediaPlayerList.add(player); playButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { player.startVideo(MediaUtils.getMedia(content).getMediaUrl()); holder.getPlayImage().setVisibility(View.GONE); progressBar.setVisibility(View.VISIBLE); } }); } } } /** * Release all holders used for the * thumbnail views */ public void releaseYouTubeHolders(){ mAbstractHolder.releaseHolders(); } @Override public int getItemViewType(int position){ int viewType = -1; //Instantiate ViewHolder Utils // viewType = ViewHolderUtils.selectViewHolder(mFeedContentList.get(position)); return viewType; } @Override public int getItemCount() { return mFeedContentList.size(); } @Override public void onViewRecycled(AbstractHolder viewHolder){ super.onViewRecycled(viewHolder); int position = viewHolder.getAdapterPosition(); IFeedContent content = mFeedContentList.get(position); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.setMargins(0, (int) Utils.dpTopx(mContext,10),0,0); params.gravity = Gravity.CENTER; if(isImage(content)){ viewHolder.getImageView().setImageURI(null); viewHolder.getImageView().setImageDrawable(null); viewHolder.getImageView().setImageResource(0); viewHolder.getImageView().setLayoutParams(params); } } /** * Create instance of * compatible viewholder * * @param viewType * @param parent * @return */ private AbstractHolder createAbstractHolder(int viewType, ViewGroup parent) { AbstractHolder holder = null; switch (viewType) { case MyConstants.HOLDER_TYPE_1: holder = ViewHolder_Var1.create(parent, mUserHomeFragment, mUserStreamFragment); break; case MyConstants.HOLDER_TYPE_2: holder = ViewHolder_Var2.create(parent, mUserHomeFragment, mUserStreamFragment); break; case MyConstants.HOLDER_TYPE_3: holder = ViewHolder_Var3.create(parent, mUserHomeFragment, mUserStreamFragment); Li(getClass().getSimpleName(), "HOLDER 3"); //holder.setIsRecyclable(false); break; case MyConstants.HOLDER_TYPE_4: holder = ViewHolder_Var4.create(parent, mUserHomeFragment, mUserStreamFragment); Li(getClass().getSimpleName(), "HOLDER 4"); break; case MyConstants.HOLDER_TYPE_5: holder = ViewHolder_Var5.create(parent, mUserHomeFragment, mUserStreamFragment); Li(getClass().getSimpleName(), "HOLDER 5"); break; case MyConstants.HOLDER_TYPE_6: holder = ViewHolder_Var6.create(parent, mUserHomeFragment, mUserStreamFragment); Li(getClass().getSimpleName(), "HOLDER 6"); break; case MyConstants.HOLDER_TYPE_7: holder = ViewHolder_Var7.create(parent, mUserHomeFragment, mUserStreamFragment); Li(getClass().getSimpleName(), "HOLDER 7"); break; case MyConstants.HOLDER_TYPE_8: holder = ViewHolder_Var8.create(parent, mUserHomeFragment, mUserStreamFragment); Li(getClass().getSimpleName(), "HOLDER 8"); break; case MyConstants.HOLDER_TYPE_9: holder = ViewHolder_Var9.create(parent, mUserHomeFragment, mUserStreamFragment); break; case MyConstants.HOLDER_TYPE_10: holder = ViewHolder_Var10.create(parent, mThumbnailViewToLoaderMap, mUserHomeFragment, mUserStreamFragment); } return holder; } private boolean isImage(IFeedContent contentItem) { if (MediaUtils.getMedia(contentItem) != null) { String mimeType = MediaUtils.getMedia(contentItem).getMimeType(); if (mimeType.contains("image")) { Li(getClass().getSimpleName(), "IMAGE HERE"); return true; } else { Li(getClass().getSimpleName(), "NO IMAGE HERE"); } } return false; } } 

EDIT 2 ViewHolder 3

 public class ViewHolder_Var3 extends AbstractHolder { @Bind(R.id.text_holder1) TextView heading; @Bind(R.id.text_holder2) TextView body; @Bind(R.id.image)ImageView image; @Bind(R.id.tabs_layout)LinearLayout tabsLayout; @Bind(R.id.hot)TextView hot; @Bind(R.id.comments)TextView children; @Bind(R.id.gif_label)TextView gifTag; @Bind(R.id.user_name)TextView userName; @Bind(R.id.tag1)TextView tag1; @Bind(R.id.tag2)TextView tag2; @Bind(R.id.tag3)TextView tag3; @Bind(R.id.profile_pic) SimpleDraweeView profilePic; private boolean mEllipsize; private boolean mExpanded; private UserHomeFragment mUserHomeFragment; private UserStreamFragment mUserStreamFragment; public ViewHolder_Var3(View itemView, UserHomeFragment userHomeFragment, UserStreamFragment userStreamFragment) { super(itemView); ButterKnife.bind(this, itemView); mUserHomeFragment = userHomeFragment; this.mUserStreamFragment = userStreamFragment; } @Override public void bindData(final IFeedContent feedContent) { userName.setText(feedContent.getAuthor().getDisplayName()); image.setImageResource(0); image.setImageDrawable(null); image.setImageURI(null); TextView [] tagsArray = {tag1, tag2, tag3}; if (feedContent.getName() != null) { heading.setText(feedContent.getName()); } else { heading.setText(feedContent.getUrl()); } if (feedContent.getName() != null) { body.setText((feedContent.getMessage())); } else { body.setText(feedContent.getUrl()); } Log.i(ViewHolder_Var3.class.getSimpleName(), "Number of lines: " + String.valueOf(body.getLineCount())); if(!MediaUtils.getMedia(feedContent).getMimeType().equals("image/gif")){ gifTag.setVisibility(View.GONE); Glide.with(itemView.getContext()).load(Uri.parse(MediaUtils.getMedia(feedContent).getMediaUrl())).placeholder(R.drawable.placeholder).diskCacheStrategy(DiskCacheStrategy.SOURCE).crossFade().into(image); }else { Glide.with(itemView.getContext()).load(Uri.parse(MediaUtils.getMedia(feedContent).getMediaUrl())).asGif().placeholder(R.drawable.placeholder).diskCacheStrategy(DiskCacheStrategy.RESULT).crossFade().into(image); } displayProfilePic(feedContent, profilePic); Glide.with(itemView.getContext()).load(Uri.parse(MediaUtils.getMedia(feedContent).getMediaUrl())).placeholder(R.drawable.placeholder).diskCacheStrategy(DiskCacheStrategy.ALL).crossFade().into(image); if(mUserHomeFragment==null){ userName.setEnabled(false); profilePic.setEnabled(false); }else{ userName.setEnabled(true); profilePic.setEnabled(true); } userName.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivityForResult(mUserHomeFragment, feedContent.getAuthor().getId(), feedContent.getParentId()); } }); profilePic.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivityForResult(mUserHomeFragment, feedContent.getAuthor().getId(), feedContent.getParentId()); } }); long hotAmt = feedContent.getLikeCount() - feedContent.getDislikeCount(); hot.setText(String.valueOf(hotAmt)); children.setText(String.valueOf(feedContent.getChildCount())); List<String> tagsList = feedContent.getTags(); populateTags(tagsList, tagsArray); // if (feedContent.getTags().size() > 0) addTags(tags, tabsLayout); ViewTreeObserver vto = body.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { ViewTreeObserver obs = body.getViewTreeObserver(); obs.removeOnGlobalLayoutListener(this); Layout layout = body.getLayout(); if(layout!=null){ int lines = layout.getLineCount(); if(lines>0){ if(layout.getEllipsisCount(lines-1)>0){ mEllipsize = true; } } } } }); body.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mEllipsize) { if (!mExpanded) { ObjectAnimator animation = ObjectAnimator.ofInt(body, "maxLines", 20); //animation.setInterpolator(new BounceInterpolator()); animation.setDuration(200).start(); // Toast.makeText(itemView.getContext(), "I AM CLICKED", Toast.LENGTH_LONG).show(); mExpanded = true; } else { ObjectAnimator animation = ObjectAnimator.ofInt(body, "maxLines", 4); //animation.setInterpolator(new BounceInterpolator()); animation.setDuration(200).start(); // Toast.makeText(itemView.getContext(), "I AM CLICKED", Toast.LENGTH_LONG).show(); mExpanded = false; } } } }); } @Override public ImageView getImageView(){ return image; } public static ViewHolder_Var3 create(ViewGroup parent, UserHomeFragment homeFragment, UserStreamFragment userStreamFragment){ View root = LayoutInflater.from(parent.getContext()).inflate(R.layout.feed_content_item_layout_var3, parent, false); return new ViewHolder_Var3(root, homeFragment, userStreamFragment); } } 

Добавьте эту строку

 android:adjustViewBounds="true" 

Для imageview в файле макета автоматически изменится размер изображения.

В изменении скольжения .crossFade() в .fitCenter()

Я столкнулся с тем же вопросом, и я решил его, как показано ниже,

 Glide.with(mContext) .load(model.getImage()) .asBitmap() .fitCenter() .placeholder(R.drawable.ic_placeholder) .error(R.drawable.ic_placeholder) .into(holder.ivImage); 

Я просто добавил .asBitmap () и .fitCenter (), проблема решена.

Вы должны в onBindViewHolder задать ширину изображения

например:

 yourImageView.getLayoutParams().width = GetScreenWidthPx(); public int GetScreenWidthPx() { DisplayMetrics displayMetrics = MyApp.GetContext().getResources().getDisplayMetrics(); return displayMetrics.widthPixels - DpToPx(your_margin_in_dp); } public static int DpToPx(int dp) { DisplayMetrics displayMetrics = MyApp.GetContext() .getResources() .getDisplayMetrics(); return (int) (dp * displayMetrics.density + 0.5f); }