开发者

Where to set bounds of a drawable in a custom view

Overview: I`m trying to create some simple shapes (squares and triangles) and then use them as the background image for an activity. The sizes of the shapes depend on the width and height of the screen. The problem is, even though I am setting the bounds of these shapes, they are all being drawn as big as possible while still fitting inside the screen.

Details: I am trying to create a very simple background image with a couple of shapes on it in an overridden view class called ControlsOverlayView.java. I am figuring out what the size of the canvas and then calling my paint method in the onDraw method, because this is when I first know how big the canvas is. I have double checked by stepping through the code that each shape has the correct bounds, but the problem is that none of the shapes are obeying their bounds, and each shape is drawing as big as it can possibly go on the screen.

public class ControlsOverlayView extends View{

    // graphical constants
    private static int SIDE_ARROW_WIDTH;
    ...
    ...

    public ControlsOverlayView(Context context, AttributeSet attrs) {
        super(context, attrs);

    }

    @Override
    protected void onDraw(Canvas canvas) {

        resize(canvas.getWidth(), canvas.getHeight());
        paintControls();
        super.onDraw(canvas);
    }

    private void resize(int width, int height) {
        // initialize screen size
        SCREEN_WIDTH = width;
        SCREEN_HEIGHT = height;

        HALF_WIDTH = SCREEN_WIDTH / 2;
        HALF_HEIGHT = SCREEN_HEIGHT / 2;

        SIDE_ARROW_HEIGHT = SCREEN_WIDTH/6;
        SIDE_ARROW_WIDTH = SIDE_ARROW_HEIGHT/2;

        // calculate constants
        TEXT_FONT_HEIGHT = Utils.Font_getHeight(TEXT_FONT);

        SCREEN_FRAMED_WIDTH = SCREEN_WIDTH-(2*FRAME_SIZE);
        SCREEN_FRAMED_HEIGHT = SCREEN_HEIGHT-(2*FRAME_SIZE);
    }

    // Creates a background drawable for the control layout including the different coloured panels and the next page arrows
    public void paintControls(){
        // Calculated layout values
        int panelWidth = SIDE_ARROW_WIDTH*3, textViewHeight = (SCREEN_HEIGHT-SIDE_ARROW_HEIGHT)/2;
        int leftArrowX = (SCREEN_WIDTH/8)+(SIDE_ARROW_WIDTH/3), rightArrowX = SCREEN_WIDTH-(SCREEN_WIDTH/4)+(SCREEN_WIDTH/8)-(SIDE_ARROW_WIDTH/3), arrowY = (SCREEN_HEIGHT/2)-(SIDE_ARROW_HEIGHT/2);  

        // Rect array that stores the bounds of each layer of the background
        Rect [] bounds = new Rect[3];
        int i = 0;

        // background
        ShapeDrawable background = new ShapeDrawable(new RectShape());
        bounds[i++] = new Rect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
        background.getPaint().setColor(CONTROLS_BACKGROUND_COLOR);

        // left panel
        ShapeDrawable leftPanel = new ShapeDrawable(new RectShape());
        bounds[i++] = new Rect(0, 0, panelWidth, SCREEN_HEIGHT);
        leftPanel.getPaint().setColor(CONTROLS_PANEL_COLOR);


        // right arrow
        Path rightArrowPath = new Path();
        rightArrowPath.moveTo(SIDE_ARROW_WIDTH, SIDE_ARROW_HEIGHT/2);
        rightArrowPath.lineTo(0, SIDE_ARROW_HEIGHT);
        rightArrowPath.lineTo(0, 0);
        rightArrowPath.lineTo(SIDE_ARROW_WIDTH, SIDE_ARROW_HEIGHT/2);
        rightArrowPath.close();
        ShapeDrawable rightArrow = new ShapeDrawable(new PathShape(rightArrowPath, SIDE_ARROW_WIDTH, SIDE_ARROW_HEIGHT));
        bounds[i++] = new Rect(rightArrowX, arrowY, rightArrowX+SIDE_ARROW_WIDTH, arrowY+SIDE_ARROW_HEIGHT);
        rightArrow.getPaint().setColor(CONTROLS_ARROW_COLOR);

        Drawable [] layers = new Drawable[] { background, left开发者_运维知识库Panel, rightArrow };
        LayerDrawable controlsBackground = new LayerDrawable(layers);
        controlsBackground.setBounds(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
        // set the bounds of each layer
        for (i=0;i<controlsBackground.getNumberOfLayers();i++) {
            controlsBackground.getDrawable(i).setBounds(bounds[i]);
        }
        controlsBackground.setAlpha(100);
        controlsLayout.setBackgroundDrawable(controlsBackground);

        controlsLayout.setVisibility(View.VISIBLE);
    }

}

The activity is called ControlsOverlayActivity.java and looks like:

public class ControlsOverlayActivity extends Activity {

    private ControlsOverlayView overlay;
    private static WattpadApp appState;


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

        setContentView(R.layout.controls_overlay);

        // initialize the controls overlay
        ControlsOverlayView.controlsLayout = (LinearLayout) findViewById(R.id.controls_layout);
        ControlsOverlayView.controlsLayout.setOnClickListener(controlsListener);
        ControlsOverlayView.controlsTextViews = new TextView[] {
                (TextView) findViewById(R.id.controls_text_left_above),
                (TextView) findViewById(R.id.controls_text_right_above),
                (TextView) findViewById(R.id.controls_text_middle),
                (TextView) findViewById(R.id.controls_text_left_below),
                (TextView) findViewById(R.id.controls_text_right_below)
        };
        // initialize the fade in/out animations for the controls overlay
        ControlsOverlayView.controlsFadeIn = new AlphaAnimation(0,1);
        ControlsOverlayView.controlsFadeIn.setDuration(ControlsOverlayView.CONTROLS_FADE_DURATION);
        ControlsOverlayView.controlsFadeOut = new AlphaAnimation(1,0);
        ControlsOverlayView.controlsFadeOut.setDuration(ControlsOverlayView.CONTROLS_FADE_DURATION);
        ControlsOverlayView.controlsFadeOut.setAnimationListener(new AnimationListener(){
            public void onAnimationEnd(Animation animation) {
                //ControlsOverlayView.controlsLayout.setVisibility(View.GONE);
            }
            public void onAnimationRepeat(Animation animation) {}
            public void onAnimationStart(Animation animation) {}
        });
    }

    private OnClickListener controlsListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            finish();
        }
    };

}

And the xml file is called controls_overlay.xml and looks like:

<?xml version="1.0" encoding="utf-8"?>
<!--  Controls Overlay -->
<FrameLayout 
 xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/controls_overlay"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <wp.wattpad.ui.ControlsOverlayView
                android:layout_width="1dp"
                android:layout_height="1dp"
             />
    <LinearLayout
            android:id="@+id/controls_layout"
            android:orientation="horizontal"
            android:visibility="invisible"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" >

            <!--  Left Panel -->
            <LinearLayout
                android:orientation="vertical"
                android:gravity="left"
                android:layout_width="wrap_content"
                android:layout_height="fill_parent" >
                <TextView android:id="@+id/controls_text_left_above"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center_horizontal|bottom"
                    android:text="@string/controls_prevpage" />
                <TextView android:id="@+id/controls_text_left_below"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center_horizontal|top"
                    android:text="@string/controls_scrollslower" />
            </LinearLayout>
            <!--  Middle Panel -->
            <LinearLayout
                android:orientation="vertical"
                android:layout_width="wrap_content"
                android:layout_height="fill_parent" >
                <TextView android:id="@+id/controls_text_middle"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:gravity="center_horizontal|center_vertical"
                    android:text="@string/taptoscroll" />
            </LinearLayout>
            <!--  Right Panel -->
            <LinearLayout
                android:orientation="vertical"
                android:gravity="right"
                android:layout_width="wrap_content"
                android:layout_height="fill_parent" >
                <TextView android:id="@+id/controls_text_right_above"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center_horizontal|bottom"
                    android:text="@string/controls_nextpage" />
                <TextView android:id="@+id/controls_text_right_below"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center_horizontal|top"
                    android:text="@string/controls_scrollfaster" />
            </LinearLayout>
        </LinearLayout>

I am really stuck here and I am wondering if maybe calling resize and paint from the onDraw() method is not the best place to do it, however I am not sure where else I could do it since I need to know the height and width of the screen. I have also tried moving around the call to super.onDraw() which didn`t change anything.


Found the answer after several frustrating hours. I was calling resize() with resize(canvas.getWidth(), canvas.getHeight()); and it should have been controlsLayout.getWidth() and controlsLayout.getHeight(). Even though the height of the canvas height was a few pixels off of the view's height it was completely ignoring the bounds. No idea why this is the case and it is severely frustrating, but problem solved.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜