【问题标题】:Make the bitmap get over ImageView borders使位图越过 ImageView 边框
【发布时间】:2018-09-26 06:45:41
【问题描述】:

我正在 ImageView 上运行旋转动画。问题是位图已被剪切以完全适合 ImageView。所以当它旋转时,它并没有完全覆盖 ImageView 以及屏幕。

这就是我想要的

这就是发生的事情

xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".fragments.LevelCompletedFragment">

    <RelativeLayout
        android:id="@+id/vgBackground"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#3f5d68"
        android:alpha="1">
    </RelativeLayout>

    <ImageView
        android:id="@+id/ivStarburst"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:adjustViewBounds="true"
        android:scaleType="centerCrop"
        android:src="@drawable/star" />

</FrameLayout>

运行动画

Animation shake = AnimationUtils.loadAnimation(mContext, R.anim.clockwise_rotation);
        **ivStarburst.startAnimation(shake);

编辑: 遵循@deadfish 的解决方案后,只有当我在 MainActivity 的 onCreate() 中打开片段时,动画才能正确运行。如果我在 onClick() 方法中触发片段,它就不起作用。

MainActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    btn.setOnClickListener(this);
}

@Override
public void onClick(View v) {
    MainFragment frgm = new MainFragment ();
                getSupportFragmentManager().beginTransaction()
                        .replace(R.id.fragment_container, frgm).commit();
}

【问题讨论】:

  • 尝试在 ImageView 中使用 android:background="@drawable/star" 而不是 src 并删除 android:scaleType="centerCrop"
  • 我不希望位图失真。它使该部分看起来很奇怪
  • 然后设置scaleType:fitXY
  • 我尝试了所有不同的比例类型,它不起作用,伙计
  • 让@drawable/star里面包含的rotate drawable,并通过ValueAnimator改变它的rotation属性

标签: android android-layout android-animation android-xml


【解决方案1】:

你几乎做到了,但忘记了两件事:

  1. 将 ImageView 的宽度和高度设置为match_layout 将只匹配父边框。您必须设置自定义尺寸,这样当您将图像居中时,它将填满整个视图。
  2. 在图像旋转过程中,当图像达到 45 度时,我们可以注意到图像没有填满整个视图。为什么?尝试将两个矩形放在自己身上,然后将其中一个旋转 45 度。这是结果。根据正方形的定义,it's diagonal value 大于正方形的一个边。所以我们必须涵盖这一点。

这是解决方案。

  1. 我们根据屏幕最长边为 ImageView 设置自定义尺寸
  2. 我们重写宽度以使用正方形的对角线宽度而不是单边

大部分代码与您的相同。我使用片段来展示示例。

//MainActivity部分

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        this.<Button>findViewById(R.id.btn).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.container, MainFragment.newInstance())
                .commit();
    }
}

//片段部分

public class MainFragment extends Fragment {

    public static MainFragment newInstance() {
        return new MainFragment();
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.main_fragment, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        ImageView imageView = Objects.requireNonNull(view).findViewById(R.id.imageView);

        // Manually set image for ImageView
        setImageForView(imageView, R.drawable.star);

        // Turn ImageView to square where a = Max(Screen.width, Screen.height)
        changeDimensionToSquareForView(imageView);

        // Start rotations
        animateRotation(imageView);
    }

    private void changeDimensionToSquareForView(ImageView imageView) {
        DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
        double maxWidth = Math.max(displayMetrics.widthPixels, displayMetrics.heightPixels);

        //calc diagonal line, x = a * sqrt(2)
        maxWidth = (maxWidth * (Math.sqrt(2)));

        imageView.setLayoutParams(new FrameLayout.LayoutParams((int) maxWidth, (int) maxWidth, Gravity.CENTER));
    }

    private void setImageForView(ImageView imageView, @DrawableRes int imageRes) {
        Context context = imageView.getContext();
        imageView.setImageDrawable(context.getResources().getDrawable(imageRes, context.getTheme()));
    }

    // Call this method in onClick method
    public void animateRotation(ImageView imageView) {
        Context context = imageView.getContext();
        Animation shake = AnimationUtils.loadAnimation(context, R.anim.clockwise_rotation);
        imageView.startAnimation(shake);
    }

}

片段的布局如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.main.MainFragment">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:src="@drawable/star" />

</FrameLayout>

这里是动画xml:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="15000"
    android:fromDegrees="0"
    android:interpolator="@android:anim/linear_interpolator"
    android:pivotX="50%"
    android:pivotY="50%"
    android:startOffset="0"
    android:toDegrees="360" />

结果如下:

【讨论】:

  • 在我第一次运行应用程序时它不起作用,只有在我重新创建旋转屏幕等活动后才能起作用
  • 此示例在开始活动时执行动画,我没有遇到您描述的任何问题。
  • 如果我在 MainActivity 中立即启动片段 onCreate(),一切正常。当我从 MainActivity 中的按钮启动方法 onClick() 上的片段时发生了我的问题
  • 我已经更新了代码。 onClick() 没有启动动画,因为整个代码都在监听器中,监听器正在监听布局变化。现在应该没问题了。
  • 我已经更新了代码。现在每次单击按钮时,它都会启动动画。
猜你喜欢
  • 2017-10-06
  • 1970-01-01
  • 2016-03-20
  • 1970-01-01
  • 2012-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-22
相关资源
最近更新 更多