当带有VideoView的幻灯片时,Viewpager会在Fragment上显示整个下一张幻灯片

时间:2016-04-27 17:30:48

标签: android android-layout android-fragments android-viewpager

您好Stackoverflow。

我一直试图解决这个问题两天了。

我们有一个 UnswipableViewPager ,它是 ViewPager 的自定义实现,用于拦截触摸事件并停止它们(没有别的),就在它的右边我们有一个 FrameLayout 我们要用我们的片段替换(通过 FragmentTransaction )。如果不是因为我们的 ViewPager 必须缩小以适应新的 Fragment ,那么这里没什么特别的。我们有一个名为 ResizableLayout RelativeLayout 的自定义实现,我们用它来做。它可以正常使用图像,请注意,当我们通过 VideoView 加载带有视频的幻灯片时,会出现问题。

This is how it looks from a design perspective。首先我们让它不受影响,然后我们正确缩小它,最后我们会在每次尝试加载带有VideoView的幻灯片时发生的事情。

XML 布局文件中的代码段:

  <RelativeLayout
        android:id="@+id/content_relative_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clipChildren="false"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true">

        <br.com.i9algo.taxiadv.v2.views.widgets.ResizableLayout
            android:id="@+id/slideshow_frame"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentStart="true"
            android:layout_alignParentTop="true"
            android:clickable="true"
            android:clipChildren="false"
            android:orientation="horizontal"
            android:scaleType="fitXY"
            layout="@layout/slideshow_item_fragment">

            <mypackage.widgets.UnswipableViewPager
                android:id="@+id/playlist_viewpager"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                layout="@layout/slideshow_item_fragment"
                android:clipChildren="false"
                android:clickable="true"
                android:scaleType="fitXY"
                />
        </mypackage.widgets.ResizableLayout>

        <FrameLayout
            android:id="@+id/sidebar_frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentBottom="true"
            android:clipChildren="false"
            android:layout_toEndOf="@+id/slideshow_frame"
            android:scaleType="fitXY" />

    </RelativeLayout>

我们的 ResizableLayout 类:

public class ResizableLayout extends RelativeLayout {


private int originalHeight = 0;
private int originalWidth = 0;
private int minWidth = 0;
private static final float SLIDE_TOP = 0f;
private static final float SLIDE_BOTTOM = 1f;
private boolean mMinimized = false;

public ResizableLayout(Context context) {
    this(context, null, 0);
}

public ResizableLayout(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public ResizableLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

@Override
protected void onFinishInflate() {
    super.onFinishInflate();
    if (!isInEditMode()) {
        minWidth = getContext().getResources().getDimensionPixelSize(R.dimen.playlist_min_width);
    }
}

@Override
protected void onDetachedFromWindow() {
    super.onDetachedFromWindow();
}

public boolean smoothSlideTo(@NonNull float slideOffset) {
    final int topBound = getPaddingTop();
    int x = (int) (slideOffset * (getWidth() - getOriginalWidth()));
    int y = (int) (topBound + slideOffset * getVerticalDragRange());
    ViewCompat.postInvalidateOnAnimation(this);
    return true;
}

public void minimize() {
    if (isMinimized())
        return;

    mMinimized = true;

    try {
        ResizeAnimation resizeAnimation = new ResizeAnimation(this, minWidth, getOriginalHeight(), false);
        resizeAnimation.setDuration(500);
        resizeAnimation.setTopMargin(20);

        setAnimation(resizeAnimation);

        smoothSlideTo(SLIDE_BOTTOM);
        requestLayout();


    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

public void maximize() {
    if (isMaximized())
        return;

    mMinimized = false;

    try {
        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) getLayoutParams();
        params.width = getOriginalWidth();
        params.topMargin = 0;
        setLayoutParams(params);
        measure(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);

        smoothSlideTo(SLIDE_TOP);
        requestLayout();

    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

public int getOriginalHeight() {
    if (originalHeight == 0) {
        originalHeight = getMeasuredHeight();
    }
    return originalHeight;
}

public int getOriginalWidth() {
    if (originalWidth == 0) {
        originalWidth = getMeasuredWidth();
    }
    return originalWidth;
}

public boolean isMinimized() {
    return mMinimized;
}

public boolean isMaximized() {
    return !mMinimized;
}

private float getVerticalDragRange() {
    return getHeight() - getOriginalHeight();
}

这是 ResizeAnimation 以防任何人想知道

public class ResizeAnimation extends Animation {

private final int mOriginalWidth;
private final int mOriginalHeight;
private final int mTargetWidth;
private final int mTargetHeight;

private int topMargin, leftMargin, bottomMargin, rightMargin;

private boolean mDown;

private View mView;

public ResizeAnimation(View view, int targetWidth, int targetHeight, boolean down) {
    this.mView = view;
    this.mTargetWidth   = targetWidth;
    this.mTargetHeight  = targetHeight;

    mOriginalWidth      = view.getWidth();
    mOriginalHeight         = view.getHeight();

    this.mDown          = down;
}

public void setTopMargin(int value) {
    this.topMargin = value;
}

@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
    int newWidth = (int) (mOriginalWidth + (mTargetWidth - mOriginalWidth) * interpolatedTime);
    int newHeight = (int) (mOriginalHeight + (mTargetHeight - mOriginalHeight) * interpolatedTime);

    if (mDown) {
        newWidth = mTargetWidth;
        newHeight = mTargetHeight;
    }

    mView.getLayoutParams().width = newWidth;
    mView.getLayoutParams().height = newHeight;
    try {
        ((RelativeLayout.LayoutParams) mView.getLayoutParams()).topMargin = topMargin;
        ((RelativeLayout.LayoutParams) mView.getLayoutParams()).leftMargin = leftMargin;
        ((RelativeLayout.LayoutParams) mView.getLayoutParams()).bottomMargin = bottomMargin;
        ((RelativeLayout.LayoutParams) mView.getLayoutParams()).rightMargin = rightMargin;
    } catch (Exception e) {
        e.printStackTrace();
    }
    mView.requestLayout();
    //mView.invalidate();
}

@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
    super.initialize(width, height, parentWidth, parentHeight);
}

@Override
public boolean willChangeBounds() {
    return true;
}

}

这是处理 FragmentTransaction 的方法。

    @Override
public void showSidebarFragment() {
    resizableLayout.minimize();
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.replace(R.id.sidebar_frame, sidebarFragment, "sidebarFragment");
    ft.commit();
    mContentRelativeLayout.requestLayout();
    sidebarframe.requestLayout();
}

请注意 Sidebarframe 是通过 Butterknife 注入的, sidebarFragment 是通过 Dagger2 注入的 - 我们使用相同的一切的片段实例。

我不知道发生了什么事。我已经尝试了几种将 Fragment 带到前面的方法,但似乎没有任何效果。如果有人能帮我解决问题,或者如何通过其他方式达到同样的效果,我会很高兴 - 不管有什么作用。

0 个答案:

没有答案