TextView MeasuredHeight не вычисляется должным образом при прокрутке Android RecyclerView

Вероятно, это самый распространенный вопрос, касающийся Android RecyclerView в stackru, и все же я нигде не нашел подходящего решения, которое бы удовлетворяло моим требованиям.

Моя проблема

Я использую библиотеку подкачки с базой данных комнаты и дооснащением для заполнения содержимого в Recyclerview. Есть два VIEW_TYPE; Один - это фактические данные в представлении карты, а другой - макет индикатора выполнения, который отображается в нижней части Recyclerview, когда API вызывается для получения следующего набора данных. Каждая карта в списке представляет собой довольно сложное изображение и текст.

Все работает нормально, пока я не начну прокручивать, когда содержимое запутается. Чтобы быть точным, одно текстовое представление должно отображаться на основе измеренной высоты другого textView. И измеренная высота не подходит должным образом после прокрутки вниз и вверх. Изображение Скриншот прилагается ниже

Я нашел 2 решения, которые предлагали почти все.

  1. переопределить 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; } }

  2. Используйте 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");
        }
    }

0 ответов