You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

计算器应用绘制矩形问题求助:输入值关联尺寸及布局颜色消失

Hey there! Let's dig into why your light blue LinearLayout loses its color when you tap the "Draw NOW" button. The main issue here is almost certainly how you're handling the drawing process—if you're directly drawing on the LinearLayout without preserving its background, the default drawing pipeline wipes out the background color when you trigger a redraw.

Let's walk through two solutions, starting with the most recommended approach:

方案1:使用自定义View(更规范可控)

LinearLayout is a container designed to hold other views, not for custom drawing. A better practice is to create a dedicated custom View that handles both the background and your rectangle rendering. Here's how to implement it:

Step 1: Create the CustomDrawView class

public class CustomDrawView extends View {
    private Paint rectPaint;
    private float sideLength = 0;
    private final int lightBlueBg = Color.parseColor("#ADD8E6");

    public CustomDrawView(Context context) {
        super(context);
        init();
    }

    public CustomDrawView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        // Set up paint for the rectangle
        rectPaint = new Paint();
        rectPaint.setColor(Color.BLACK);
        rectPaint.setStyle(Paint.Style.STROKE); // Switch to FILL if you want a solid rectangle
        rectPaint.setStrokeWidth(2);

        // Set the light blue background
        setBackgroundColor(lightBlueBg);
    }

    public void updateRectSide(float inputNumber) {
        this.sideLength = inputNumber * 10; // Multiply by 10 as required
        invalidate(); // Trigger a redraw to show the new rectangle
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); // This ensures the background color is drawn first

        if (sideLength > 0) {
            // Draw rectangle starting at (50,50) — adjust position as needed
            canvas.drawRect(50, 50, 50 + sideLength, 50 + sideLength, rectPaint);
        }
    }
}

Step 2: Update your layout XML

Replace your existing LinearLayout with this custom view:

<com.yourpackage.name.CustomDrawView
    android:id="@+id/draw_area"
    android:layout_width="match_parent"
    android:layout_height="300dp"
    android:layout_below="@id/calculator_container"/>

Step 3: Hook up the button in MainActivity

public class MainActivity extends AppCompatActivity {
    private CustomDrawView drawArea;
    private EditText firstInputField;

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

        drawArea = findViewById(R.id.draw_area);
        firstInputField = findViewById(R.id.first_input);
        Button drawButton = findViewById(R.id.draw_now_button);

        drawButton.setOnClickListener(v -> {
            String inputText = firstInputField.getText().toString();
            if (!inputText.isEmpty()) {
                try {
                    float firstNumber = Float.parseFloat(inputText);
                    drawArea.updateRectSide(firstNumber);
                } catch (NumberFormatException e) {
                    Toast.makeText(this, "Please enter a valid number!", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

方案2:修复原LinearLayout的绘制(不推荐,但如果必须用)

If you really want to stick with LinearLayout, you need to force it to draw its background before your rectangle. Here's how:

Step 1: Create a custom LinearLayout subclass

public class DrawableLinearLayout extends LinearLayout {
    private Paint rectPaint;
    private float sideLength = 0;

    public DrawableLinearLayout(Context context) {
        super(context);
        init();
    }

    public DrawableLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        rectPaint = new Paint();
        rectPaint.setColor(Color.BLACK);
        rectPaint.setStrokeWidth(2);
        rectPaint.setStyle(Paint.Style.STROKE);
        
        setWillNotDraw(false); // Tell the ViewGroup to trigger onDraw()
        setBackgroundColor(Color.parseColor("#ADD8E6"));
    }

    public void setRectSide(float inputNumber) {
        this.sideLength = inputNumber * 10;
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); // Draw the background first
        
        if (sideLength > 0) {
            canvas.drawRect(50, 50, 50 + sideLength, 50 + sideLength, rectPaint);
        }
    }
}

Then update your layout to use DrawableLinearLayout instead of the standard LinearLayout, and adjust your MainActivity code to reference this class (similar to方案1).

Why your original code broke the background

Chances are you were either:

  • Overriding onDraw() without calling super.onDraw(canvas), which skips rendering the background color.
  • Or not setting setWillNotDraw(false) on the LinearLayout—ViewGroup subclasses don't call onDraw() by default, so your custom drawing code wasn't even running, and some other logic was clearing the background.

Either way, using a dedicated custom View is the cleaner, more maintainable approach for custom shape drawing.

内容的提问来源于stack exchange,提问作者Huntix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:59:59