简体   繁体   中英

Android SeekBars cropped before rotating

I'm trying to make a vertical mixer-style interface to control different audio sources, using Android SeekBars. I can rotate the SeekBars as many posts describe, and get them into the right position. However, the width of each SeekBar (which we see as height after it is rotated) is getting cropped to the available width of the parent view. The result is that each SeekBar gets a little shorter, because the distance from its start position to the right edge of the parent is less. They should all be the full height of this image:

在此处输入图片说明

Here's the code for setting it up; this is in the parent's setLayoutParams() so the SeekBars will resize whenever the parent is resized:

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 is just a convenience function for adding 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);
}

I'm getting the same results on Android 8.1.0 and 5.1.1.

The parent is a RelativeLayout and had setClipChildren(true) on it, but I removed that and it made no difference.

Another post suggested adding setLayerType(View.LAYER_TYPE_SOFTWARE, null) to the SeekBars, but that made no difference.

It doesn't matter if I rotate before or after setting the sizes. Android still limits the width to the available space as if the SeekBar is not rotated.

I tried creating a new view, adding the SeekBar to the view and rotating the view, but then the view was clipped in the same way that the SeekBar was. So it seems that this is a general problem with Android views, not specific to SeekBars. But I still didn't find a solution through more general searches.

What would limit the SeekBar sizes to their parent view, and how can I work around that?

I just found a workaround that works: I added an inner view that's the same width as the parent view is high, then added the SeekBars to that. The inner view is invisible, so you can't see that it is wider than the parent view, but now the SeekBars aren't clipped. I'll leave this unanswered in case there is a more direct solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM