您好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 带到前面的方法,但似乎没有任何效果。如果有人能帮我解决问题,或者如何通过其他方式达到同样的效果,我会很高兴 - 不管有什么作用。