У меня есть вид ресайклера с разными держателями вида.
У пары держателей представлений есть представления изображений, которые я передаю в Glide для отображения изображений.
Проблема в том, что когда представление ресайклера начинает повторное использование представлений, ширина / высота просмотра изображения соответствуют повторно используемому представлению, которое затем отображает изображение некорректно.
Вот мой 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 не начнет Recycling, поэтому первое изображение в recyclerview будет выглядеть так, как оно и должно было выглядеть.
однако, когда вы прокручиваете от элемента и прокручиваете назад, это выглядит так:
Таким образом, изображение стало искаженным и не на всю ширину родительского элемента.
Я хочу, чтобы представление изображения обернуло содержимое, потому что все изображения будут разной высоты и т. Д. Чтобы проверить это, я добавил эту строку holder.setIsRecyclable(false);
, чтобы предотвратить повторное использование этого конкретного держателя и всех изображений, отображаемых должным образом, однако, как и ожидалось, это дало резкий эффект.
Затем я попытался сбросить параметры представления изображения в методе 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);
}
}
Здесь я воссоздаю параметры в xml, но это не работает. Метод isImage()
this просто проверяет mimetype объекта.
Может ли кто-нибудь помочь в этом? Это очень неприятно.
Любая помощь по этому поводу приветствуется.
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);
L.i(getClass().getSimpleName(), "HOLDER 3");
//holder.setIsRecyclable(false);
break;
case MyConstants.HOLDER_TYPE_4:
holder = ViewHolder_Var4.create(parent, mUserHomeFragment, mUserStreamFragment);
L.i(getClass().getSimpleName(), "HOLDER 4");
break;
case MyConstants.HOLDER_TYPE_5:
holder = ViewHolder_Var5.create(parent, mUserHomeFragment, mUserStreamFragment);
L.i(getClass().getSimpleName(), "HOLDER 5");
break;
case MyConstants.HOLDER_TYPE_6:
holder = ViewHolder_Var6.create(parent, mUserHomeFragment, mUserStreamFragment);
L.i(getClass().getSimpleName(), "HOLDER 6");
break;
case MyConstants.HOLDER_TYPE_7:
holder = ViewHolder_Var7.create(parent, mUserHomeFragment, mUserStreamFragment);
L.i(getClass().getSimpleName(), "HOLDER 7");
break;
case MyConstants.HOLDER_TYPE_8:
holder = ViewHolder_Var8.create(parent, mUserHomeFragment, mUserStreamFragment);
L.i(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")) {
L.i(getClass().getSimpleName(), "IMAGE HERE");
return true;
} else {
L.i(getClass().getSimpleName(), "NO IMAGE HERE");
}
}
return false;
}
}
РЕДАКТИРОВАТЬ 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);
}
}