Intereting Posts
Может ли новый конструктор File () возвращать null на Android? Как использовать универсальный загрузчик изображений для списка видео эскизов в android? Volley – загрузка непосредственно в файл (нет в массиве байтов памяти) Перемещение с помощью RecyclerView + AppBarLayout Как сделать вложенный объект Json в Java? Есть ли стандартный способ намекнуть, что число должно читаться по одному символу за раз? Как отключить MediaPlayer в android Не удалось найти adb.exe – после обновления до Android SDK 2.3 Программно скрыть / показать поддержку поддержки Android в TabLayout внутри AppBarLayout Recyclerview внутри просмотра прокрутки влияет на положение прокрутки Уверенный способ переопределить onMeasure ()? Android: расшифровать текст RSA с помощью открытого ключа, хранящегося в файле Исключение исключенного события цикла в плагине org.eclipse.ui Android: тема подключения к приложениям – диалог, когда большой Не удалось разрешить целевой «android-XX»

Размер холста

У меня есть приложение для Android, которое содержит несколько фрагментов.

В одном из этих фрагментов существует

  1. Надпись,
  2. Пользовательский вид,
  3. Две панели с кнопками.

В пользовательском представлении (пункт 2) мне нужно нарисовать несколько цифр, один из которых привязан к размеру вида, т. Е. Должен быть прямоугольник с закругленными краями, размер которого равен размеру холста минус заполнение.

Для этого мне нужно получить ширину и высоту холста.

Я пробовал следующие вещи:

  1. Получите размеры представления в методе onSizeChanged (новая ширина / высота).
  2. Получите размеры представления в методе onLayout .
  3. Получите размеры представления в методе onDraw ( canvas.getWidth()/getHeight(), View.getMeasuredWidth()/getMeasuredHeight() ).

Все три метода возвращают ту же ширину и высоту, и все они не работают – фигура слишком узкая (заполняет только около 60% доступного пространства вместо 100%) и слишком высока (нижняя часть фигуры не видна ).

Каков правильный способ определения размеров (экземпляр 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 (31.03.2013 19:38 MSK): Если я onLayout 150 из ширины, о которой сообщает onLayout , onSizeChanged или onMeasure , прямоугольник отображается правильно.

Обновление 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> 

Solutions Collecting From Web of "Размер холста"

В соответствии с моим комментарием по вопросу:

Ваш макет верхнего уровня: вы установили ширину content_fragment2 в fill_parent, поэтому он будет иметь ту же ширину, что и его parent linearlayout. Вероятно, вы хотите, чтобы в menu_pane была фиксированная ширина, нет layout_weight, а для content_fragment2 – layout_width = 0px и layout_weight = 1.

Рад, что это помогло!

Я вижу android:layout_height="wrap_content" для пользовательского представления.

В этом случае родительский / контейнер ViewGroup хотел бы знать высоту содержимого при измерении этого представления.

Но, чтобы нарисовать контент, вы зависите от размеров, измеренных макетом, которые до сих пор не имеют представления о высоте контента.

Установите android:layout_height в 0dp , что позволит android:layout_weight атрибут android:layout_weight , и тогда представление будет иметь предварительно измеренную высоту в соответствии с доступным пространством.

Кроме того, onSizeChanged() достаточно, чтобы информировать вас об изменениях размеров, когда макет снова измеряется.

Попробуй это:

 view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener(){ @Override public void onGlobalLayout() { //capture view width and height here }//end onGlobalLayout() }); 

См. GetViewTreeObserver ().