在自定义视图中设置drawable边界的位置

时间:2011-07-19 19:32:38

标签: android drawable bounds ondraw

概述:我试图创建一些简单的形状(正方形和三角形),然后将它们用作活动的背景图像。形状的大小取决于屏幕的宽度和高度。问题是,即使我设置了这些形状的边界,它们都被绘制得尽可能大,同时仍然适合屏幕内部。

详细信息:我正在尝试在一个名为ControlsOverlayView.java的重写视图类中创建一个非常简单的背景图像,其上有几个形状。我正在弄清楚画布的大小,然后在onDraw方法中调用我的paint方法,因为这是我第一次知道画布有多大。我通过逐步完成每个形状具有正确边界的代码进行了双重检查,但问题是没有一个形状符合它们的边界,并且每个形状都绘制得尽可能大到可能出现在屏幕上。

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, leftPanel, 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);
    }

}

该活动名为ControlsOverlayActivity.java,如下所示:

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();
        }
    };

}

xml文件名为controls_overlay.xml,如下所示:

<?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>

我真的被困在这里,我想知道是否可能从onDraw()方法调用resize和paint不是最好的地方,但是我不知道我还能做什么,因为我需要知道屏幕的高度和宽度。我也尝试过调用super.onDraw(),它没有改变任何东西。

1 个答案:

答案 0 :(得分:2)

经过几个令人沮丧的时间后找到答案。我使用resize()致电resize(canvas.getWidth(), canvas.getHeight());,应该是controlsLayout.getWidth()controlsLayout.getHeight()。即使画布高度的高度与视图高度相差几个像素,也完全忽略了边界。不知道为什么会这样,而且非常令人沮丧,但问题已经解决了。