首页 > 解决方案 > Android SeekBars 在旋转前被裁剪

问题描述

我正在尝试使用 Android SeekBars 制作一个垂直混音器样式的界面来控制不同的音频源。我可以像许多帖子描述的那样旋转 SeekBars,并将它们放在正确的位置。然而,每个 SeekBar 的宽度(我们在旋转后看到的高度)被裁剪为父视图的可用宽度。结果是每个 SeekBar 都变短了一点,因为从它的起始位置到父节点右边缘的距离更小。它们都应该是这张图片的完整高度:

在此处输入图像描述

这是设置它的代码;这是在父级中,setLayoutParams()因此只要调整父级的大小,SeekBars 就会调整大小:

public void setLayoutParams (ViewGroup.LayoutParams params) {
    super.setLayoutParams(params);

    int sliderWidth = ViewUtils.scalePixels(this.app, 24);
    int sliderPadding = ViewUtils.scalePixels(this.app, 24);
    int iconSize = ViewUtils.scalePixels(this.app, 24);
    int iconPadding = ViewUtils.scalePixels(this.app, 8);
    int nextPosition = sliderPadding / ViewUtils.scalePixels(this.app, 2);

    // all the widths and heights are backwards here due to the rotation
    // rotating from the center created weirdness with the positioning
    this.masterSlider.setPivotX(0);
    this.recordingSlider.setPivotX(0);
    this.tempoSlider.setPivotX(0);
    this.pitchSlider.setPivotX(0);
    this.videoSlider.setPivotX(0);
    this.masterSlider.setPivotY(0);
    this.recordingSlider.setPivotY(0);
    this.tempoSlider.setPivotY(0);
    this.pitchSlider.setPivotY(0);
    this.videoSlider.setPivotY(0);
    this.masterSlider.setRotation(-90);
    this.recordingSlider.setRotation(-90);
    this.tempoSlider.setRotation(-90);
    this.pitchSlider.setRotation(-90);
    this.videoSlider.setRotation(-90);

    ViewUtils.setRelativeFrame(this.masterSlider, nextPosition, params.height - iconSize - iconPadding, params.height - iconSize - iconPadding, sliderWidth);
    ViewUtils.setRelativeFrame(this.masterIcon, nextPosition, params.height - iconSize, iconSize, iconSize);

    nextPosition += sliderWidth + sliderPadding;
    ViewUtils.setRelativeFrame(this.recordingSlider, nextPosition, params.height - iconSize - iconPadding, params.height - iconSize - iconPadding, sliderWidth);
    ViewUtils.setRelativeFrame(this.recordingIcon, nextPosition, params.height - iconSize, iconSize, iconSize);

    nextPosition += sliderWidth + sliderPadding;
    ViewUtils.setRelativeFrame(this.tempoSlider, nextPosition, params.height - iconSize - iconPadding, params.height - iconSize - iconPadding, sliderWidth);
    ViewUtils.setRelativeFrame(this.tempoIcon, nextPosition, params.height - iconSize, iconSize, iconSize);

    nextPosition += sliderWidth + sliderPadding;
    ViewUtils.setRelativeFrame(this.pitchSlider, nextPosition, params.height - iconSize - iconPadding, params.height - iconSize - iconPadding, sliderWidth);
    ViewUtils.setRelativeFrame(this.pitchIcon, nextPosition, params.height - iconSize, iconSize, iconSize);

    nextPosition += sliderWidth + sliderPadding;
    ViewUtils.setRelativeFrame(this.videoSlider, nextPosition, params.height - iconSize - iconPadding, params.height - iconSize - iconPadding, sliderWidth);
    ViewUtils.setRelativeFrame(this.videoIcon, nextPosition, params.height - iconSize, iconSize, iconSize);
}

setRelativeFrame只是添加RelativeLayoutParams的便利功能:

public static void setRelativeFrame(View view, int x, int y, int w, int h) {
    RelativeLayout.LayoutParams layoutParams = null;
    if (view.getLayoutParams() instanceof RelativeLayout.LayoutParams) {
        layoutParams = (RelativeLayout.LayoutParams)view.getLayoutParams();
    }
    if (layoutParams == null) {
        layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
    }
    layoutParams.leftMargin = x;
    layoutParams.topMargin = y;
    layoutParams.width = w;
    layoutParams.height = h;
    view.setLayoutParams(layoutParams);
}

我在 Android 8.1.0 和 5.1.1 上得到了相同的结果。

父级是一个RelativeLayout 并且有setClipChildren(true)它,但我删除了它,它没有任何区别。

另一篇文章建议添加setLayerType(View.LAYER_TYPE_SOFTWARE, null)到 SeekBars,但这没有任何区别。

在设置尺寸之前或之后旋转都没有关系。Android 仍然将宽度限制为可用空间,就好像 SeekBar 没有旋转一样。

我尝试创建一个新视图,将 SeekBar 添加到视图并旋转视图,但随后视图以与 SeekBar 相同的方式被剪辑。所以这似乎是 Android 视图的普遍问题,而不是特定于 SeekBars。但是我仍然没有通过更一般的搜索找到解决方案。

什么会将 SeekBar 大小限制为它们的父视图,我该如何解决这个问题?

标签: androidclippingandroid-seekbarandroid-vertical-seekbar

解决方案


我刚刚找到了一种可行的解决方法:我添加了一个与父视图高度相同的内部视图,然后将 SeekBars 添加到该视图中。内部视图是不可见的,因此您看不到它比父视图宽,但现在 SeekBars 没有被剪裁。如果有更直接的解决方案,我将不予回答。


推荐阅读