ViewPager PageTransformer View getWidth и getMeasuredWidth равны 0

Я реализую компонент Карусель на основе следующего кода: https://github.com/bhaveshjabuvani-credencys/CarouselEffect/blob/master/app/src/main/java/com/carouseleffect/CarouselEffectTransformer.java

Основная проблема заключается в том, что при первом вызове преобразователя страниц и view.getLeft(), и view.getMeasuredWidth() равны 0, поэтому выполнение преобразователя страниц не даст правильных результатов.

Чтобы устранить эту проблему, в макете страницы я добавил следующий вид для каждой страницы, чтобы сохранить индекс / положение представления:

<View
android:id="@+id/pagePosition"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone"/>

Затем, когда преобразованная страница вызывается, pagePosition используется для имитации правильных leftPadding и leftPosition для каждой страницы, и преобразователь страниц работает, как и ожидалось (первая страница центрируется, а следующая сокращается).

Модифицированный код ViewPager.PageTransformer выглядит следующим образом:

public class CarouselEffectTransformer implements ViewPager.PageTransformer {

private int maxTranslateOffsetX;
private int leftPadding;
private int rightPadding;
private ViewPager viewPager;

public CarouselEffectTransformer(Context context) {
    this.maxTranslateOffsetX = dp2px(context, 180);
    this.leftPadding = dp2px(context, 50);
    this.rightPadding = dp2px(context, 50);
}

public void transformPage(View view, float position) {
    if (viewPager == null) {
        viewPager = (ViewPager) view.getParent();
    }

    //********** workaround start ****************
    // get child
    LinearLayout layout = (LinearLayout) view;
    View pagePosition = layout.getChildAt(0);
    int pageIndex = (int) pagePosition.getTag();

    // check if view was measured
    int offsetX = 0;
    if (view.getLeft() == 0 && view.getMeasuredWidth() == 0) {
        int pageWidth = viewPager.getMeasuredWidth() - leftPadding - rightPadding;
        int leftInScreen = leftPadding + pageIndex * pageWidth;
        int centerXInViewPager = leftInScreen + (viewPager.getMeasuredWidth() - leftPadding - rightPadding) / 2;
        offsetX = centerXInViewPager - viewPager.getMeasuredWidth() / 2;
    }
    //********** workaround end ****************
    else {
        int leftInScreen = view.getLeft() - viewPager.getScrollX();
        int centerXInViewPager = leftInScreen + view.getMeasuredWidth()/ 2;
        offsetX = centerXInViewPager - viewPager.getMeasuredWidth() / 2;
    }


    float offsetRate = (float) offsetX * 0.38f / viewPager.getMeasuredWidth();
    float scaleFactor = 1 - Math.abs(offsetRate);

    if (scaleFactor > 0) {
        view.setScaleX(scaleFactor);
        view.setScaleY(scaleFactor);
        view.setTranslationX(-maxTranslateOffsetX * offsetRate);
    }
    ViewCompat.setElevation(view, scaleFactor);
}

    private int dp2px(Context context, float dipValue) {
        float m = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * m + 0.5f);
    }
}

Некоторая информация о макете:

  • ViewPager обновляется путем вызова notifyDataSetChanged() на своем адаптере, поэтому конфигурация хорошая.
  • ViewPager находится внутри Relativelayout, и весь макет надувается фрагментом.

Однако я бы предпочел не делать этот обходной путь, поэтому вопрос:

  • Почему при первом вызове представления getWidth() и getMeasuredWidth () равны 0?
  • Может ли это быть конфликт между ViewPager и жизненным циклом фрагмента?

0 ответов

Другие вопросы по тегам