TextView MeasuredHeight не вычисляется должным образом при прокрутке Android RecyclerView
Вероятно, это самый распространенный вопрос, касающийся Android RecyclerView в stackru, и все же я нигде не нашел подходящего решения, которое бы удовлетворяло моим требованиям.
Моя проблема
Я использую библиотеку подкачки с базой данных комнаты и дооснащением для заполнения содержимого в Recyclerview. Есть два VIEW_TYPE; Один - это фактические данные в представлении карты, а другой - макет индикатора выполнения, который отображается в нижней части Recyclerview, когда API вызывается для получения следующего набора данных. Каждая карта в списке представляет собой довольно сложное изображение и текст.
Все работает нормально, пока я не начну прокручивать, когда содержимое запутается. Чтобы быть точным, одно текстовое представление должно отображаться на основе измеренной высоты другого textView. И измеренная высота не подходит должным образом после прокрутки вниз и вверх. Изображение Скриншот прилагается ниже
Я нашел 2 решения, которые предлагали почти все.
переопределить getItemViewType(int position) в адаптере и вернуть позицию
~ Я не могу использовать это решение, так как мне нужно сохранить 2 VIEW_TYPES. Мой код getItemViewType выглядит следующим образом:
public int getItemViewType(int position) { if (hasExtraRow() && position == getItemCount() - 1) { return R.layout.item_network_state; } else { return R.layout.card_post_timeline; } }
Используйте setIsRecyclable(false) в ViewHolder
~ Если я использую это решение, оно решает мою проблему, но я не хочу его использовать, так как это противоречит всей цели Recyclerview и плохо влияет на производительность, когда будет большой набор данных.
Мой код
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
if (viewType == R.layout.card_post_timeline) {
View view = layoutInflater.inflate(R.layout.card_post_timeline, parent, false);
TimelinePostViewHolder viewHolder = new TimelinePostViewHolder(view, context,optionsSelected );
return viewHolder;
} else if (viewType == R.layout.item_network_state) {
View view = layoutInflater.inflate(R.layout.item_network_state, parent, false);
return new NetworkStateItemViewHolder(view);
} else {
throw new IllegalArgumentException("unknown view type");
}
}
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (getItemViewType(position)) {
case R.layout.card_post_timeline:
((TimelinePostViewHolder) holder).bindTo(getItem(position)); // Data binding happens here
break;
case R.layout.item_network_state:
((NetworkStateItemViewHolder) holder).bindView(networkState);
break;
}
}`
Вопрос
Какую альтернативу мы можем использовать для решения этой извечной проблемы Recyclerview?
Обновлено -
Единственная проблема заключается в том, что видимость текстового поля "Показать больше", которая рассчитывается по измеренной высоте postBody textview. После прокрутки вниз и затем вверх измеренная высота Textview всегда будет одинаковой, независимо от текстового содержимого.
Логика такая же, как ниже:
private void renderPostContent(Post post) {
tvPostBody.fromHtml(post.getPostContent());
Log.d(StringConstants.LOG_TAG, tvPostBody.getText().toString());
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(IntegerConstants.SCREEN_WIDTH, View.MeasureSpec.AT_MOST);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
tvPostBody.measure(widthMeasureSpec, heightMeasureSpec);
int measuredTextViewHeight = tvPostBody.getMeasuredHeight();
Log.d(StringConstants.LOG_TAG, "list position - " + getAdapterPosition() + " measuredHeight - " + measuredTextViewHeight);
if (measuredTextViewHeight > IntegerConstants.SCREEN_WIDTH) {
tvPostBody.setMaxHeight(IntegerConstants.SCREEN_WIDTH);
tvShowMore.setVisibility(View.VISIBLE);
// setIsRecyclable(false);
Log.d(StringConstants.LOG_TAG, "ShowMore visibile");
} else {
tvPostBody.setMaxHeight(IntegerConstants.SCREEN_WIDTH);
tvShowMore.setVisibility(View.GONE);
//setIsRecyclable(true);
Log.d(StringConstants.LOG_TAG, "ShowMore gone");
}
}