Вероятно, это самый распространенный вопрос, касающийся Android RecyclerView в stackoverflow, и все же я не смог найти нигде подходящего решения, которое бы отвечало моим требованиям.
Моя проблема
Я использую пейджинг Библиотека с базой данных комнат и модернизация для заполнения содержимого в Recyclerview. Есть два VIEW_TYPE; Одним из них являются фактические данные в виде карты, а другим - макет индикатора выполнения, который отображается в нижней части Recyclerview при вызове API для получения следующего набора данных. Каждый вид карты в списке довольно сложен, содержит изображения и тексты.
Все работает нормально, пока я не начну прокручиваться, когда содержимое запутано. Чтобы быть точным, одно текстовое представление должно отображаться на основе измеренной высоты другого текстового представления. И измеренная высота не приходит должным образом после прокрутки вниз и вверх. Снимок экрана изображения, прикрепленный ниже
Есть 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 всегда будет одинаковой независимо от содержимого текста.
Logi c для того же значения, что и ниже:
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");
}
}