11

いくつかのフラグメントを持つ Android アプリケーションがあります。

これらのフラグメントの 1 つに、

  1. レタリング、
  2. カスタムビュー、
  3. ボタン付きの 2 つのパネル。

カスタム ビュー (項目 2) では、いくつかの図形を描画する必要があります。そのうちの 1 つはビューのサイズに関連付けられています。つまり、キャンバスのサイズからパディングを引いたサイズに等しい、角が丸い四角形が必要です。

これを行うには、キャンバスの幅と高さを取得する必要があります。

私は次のことを試しました:

  1. メソッドでビューの寸法を取得しますonSizeChanged(新しい幅/高さ)。
  2. メソッドでビューの寸法を取得しますonLayout
  3. ビューの寸法をonDrawメソッド ( canvas.getWidth()/getHeight(), View.getMeasuredWidth()/getMeasuredHeight()) で取得します。

3 つのメソッドはすべて同じ幅と高さを返しますが、いずれも機能しません。Figure が狭すぎる (使用可能なスペースの 100 % ではなく約 60 % しか占めていない) か、高すぎる (Figure の下部が見えない) ためです。 )。

RectFカスタム ビューの寸法 (インスタンス) を決定する正しい方法は何ですか?

このアプリケーションは、ランドスケープ モードの Nexus 7 エミュレーターでテストしていることに注意してください。

更新プログラム 1 (28.03.2013 21:42 MSK)

対応するフラグメントの XML ファイル:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/simulation_fragment"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Simulation"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <co.mycompany.ccp.android.impl.simulationcanvas.SimulationCanvasView
        android:id="@+id/simulation_canvas_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.8" />

    <LinearLayout
        android:id="@+id/simulationExecutionPanel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.1" >

        <Button
            android:id="@+id/restartSimulationButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/restart_simulation" />

        <Button
            android:id="@+id/simulationStepButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/simulation_step" />

        <Button
            android:id="@+id/pauseButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/pause" />

        <Button
            android:id="@+id/continueButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/continue_button" />

        <Button
            android:id="@+id/simulateAdInfinitumButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/simulate_ad_infinitum" />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/currentCycleLabel" />

        <TextView
            android:id="@+id/currentCycleIndicator"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Cycle"
            android:textAppearance="?android:attr/textAppearanceMedium" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.1" >

        <Button
            android:id="@+id/addCompanyButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/add_company2" />

        <Button
            android:id="@+id/removeCompanyButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/remove_company" />

        <Button
            android:id="@+id/setLabourForceButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/set_labour_force" />
    </LinearLayout>

</LinearLayout>

@+id/simulation_canvas_viewビュー ( )のコードは次のとおりです。

import co.mycompany.ccp.android.api.economypartsdimensioncalculator.EconomyPartsDimensionCalculator;
import co.mycompany.ccp.android.api.systemboundary.SystemBoundaryGraphicsCalculator;
import co.mycompany.ccp.android.impl.economypartsdimensioncalculator.DefaultEconomyPartsDimensionCalculator;
import co.mycompany.ccp.android.impl.systemboundary.DefaultSystemBoundaryGraphicsCalculator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

/**
 * @author DP118M
 * 
 */
public class SimulationCanvasView extends View {

    private static final int SYSTEM_BOUNDARY_COLOUR = Color.LTGRAY;

    [...]

    private int width = -1;
    private int height= -1;
    private SystemBoundaryGraphicsCalculator systemBoundaryGraphicsCalculator = new DefaultSystemBoundaryGraphicsCalculator();
    [...]
    private Rect systemBoundaryDimensions = new Rect(100, 100, 100 + 100,
            100 + 100);
    private Rect externalEconomyDimensions;

    [...]

    public SimulationCanvasView(final Context aContext) {
        super(aContext);
    }

    public SimulationCanvasView(final Context context, final AttributeSet attrs) {
        super(context, attrs);
    }

    public SimulationCanvasView(final Context context,
            final AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    [...]

    private void updateSystemBoundaryGraphicsCalculatorDimensions() {
        systemBoundaryGraphicsCalculator.setCanvasHeight(height);
        systemBoundaryGraphicsCalculator.setCanvasWidth(width);
        try {
            systemBoundaryGraphicsCalculator.run();
            systemBoundaryDimensions = systemBoundaryGraphicsCalculator
                    .getSystemBoundaryDimensions();
        } catch (final Exception exception) {
            throw new RuntimeException(exception);
        }
    }

    @Override
    protected void onDraw(final Canvas aCanvas) {
        super.onDraw(aCanvas);

        this.width = this.getWidth();
        this.height = this.getHeight();

        updateSystemBoundaryGraphicsCalculatorDimensions();         

        [...]

        drawRectangleWithRoundedEdges(aCanvas, systemBoundaryDimensions,
                SYSTEM_BOUNDARY_COLOUR);

        [...]
    }

    private void drawRectangleWithRoundedEdges(final Canvas aCanvas,
            final Rect aDimensions, int aStrokeColour) {
        final Paint paint = new Paint();

        paint.setColor(aStrokeColour);
        paint.setStrokeWidth(1);
        paint.setStyle(Paint.Style.STROKE);

        aCanvas.drawRoundRect(new RectF(aDimensions), 20, 20, paint);
    }   
}

角丸長方形の寸法を計算するクラスは次のとおりです。

package co.mycompany.ccp.android.impl.systemboundary;

import android.graphics.Rect;
import co.mycompany.ccp.android.api.systemboundary.SystemBoundaryGraphicsCalculator;

/**
 * @author DP118M
 * 
 */
public class DefaultSystemBoundaryGraphicsCalculator implements
        SystemBoundaryGraphicsCalculator {
    private int canvasWidth;
    private int canvasHeight;
    private int xPadding = SYSTEM_BOUNDARY_X_PADDING;
    private int yPadding = SYSTEM_BOUNDARY_Y_PADDING;
    private Rect systemBoundaryDimensions;

    public void setXPadding(final int xPadding) {
        this.xPadding = xPadding;
    }

    public void setYPadding(final int yPadding) {
        this.yPadding = yPadding;
    }

    @Override
    public Rect getSystemBoundaryDimensions() {
        return systemBoundaryDimensions;
    }

    @Override
    public void setCanvasWidth(final int width) {
        this.canvasWidth = width;
    }

    @Override
    public void setCanvasHeight(final int height) {
        this.canvasHeight = height;
    }

    @Override
    public void run() throws Exception {
        this.systemBoundaryDimensions = new Rect(0 + xPadding, 0 + yPadding,
                Math.max(this.canvasWidth - xPadding, 0), Math.max(
                        this.canvasHeight - yPadding, 0));
    }
}

更新 2 :

スクリーンショットは次のとおりです。

スクリーンショット

更新 3 (2013 年 3 月 31 日 19:38 MSK):またはによって報告さonLayoutれた幅から 150 を引くと、四角形が正しく表示されます。onSizeChangedonMeasure

更新 4 (05.04.2013 21:07 MSK):メイン アクティビティのレイアウトは次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <fragment
        android:id="@+id/menu_pane"
        android:layout_width="0px"
        android:layout_height="match_parent"
        android:layout_weight="1"
        class="co.altruix.ccp.android.impl.fragments.MenuFragment" />

    <FrameLayout
        android:id="@+id/content_fragment2"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" 
        class="co.altruix.ccp.android.impl.fragments.ContentFragment2"/>

</LinearLayout>
4

3 に答える 3

2

android:layout_height="wrap_content"カスタムビューが表示されます。

このような場合、親/コンテナーViewGroupは、このビューを測定するときにコンテンツの高さを知りたいと考えています。

ただし、コンテンツを描画するには、レイアウトによって測定された寸法に依存しますが、コンテンツの高さはまだわかりません。

に設定android:layout_heightすると、属性の使用0dpが許可android:layout_weightされ、ビューは使用可能なスペースに応じて事前に測定された高さになります。

また、onSizeChanged()レイアウトを再測定する際に、寸法の変更をお知らせするだけで十分です。

于 2013-04-05T18:04:54.750 に答える
1

これを試して:

view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener(){
        @Override
        public void onGlobalLayout() {

        //capture view width and height here

    }//end onGlobalLayout()

        });

getViewTreeObserver()を参照してください。

于 2013-04-06T05:14:06.700 に答える