Android: определение размера холста onDraw

Я удалил свой старый код, так как он работал не так, как я планировал. Я пытался использовать функцию холста onDraw в определенной части экрана, чтобы у меня все еще могли быть кнопки и другой текст вокруг моего рисунка.

***ИЗМЕНИТЬ***

Мне удалось исправить эту проблему сейчас. Многое из того, что было предложено, было полезно, но я просто не мог заставить его работать с тем, что я хотел. Это, вероятно, больше моя вина, чем что-либо еще, так что спасибо всем тем, кто дал совет. Вот как я решил проблему.

*1. Сначала определите представление в файле макета.

<view
class="com.project.MainActivity.Drawing"
android:id="@+id/drawing_area"
android:layout_width="700dp"
android:layout_height="900dp"
android:layout_centerInParent="true"/>

*2. Затем создайте отдельный файл класса Java со следующим кодом:

public class Drawing extends View {
Paint paint = new Paint();

public Drawing(Context context) {
super(context);
}

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

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

//Draw Image Here//

}

*3. Затем вызовите Drawing из основного действия:

public class MainActivity extends Activity {

private Drawing mDrawingArea;

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.percentage_count_layout);
  mDrawingArea = (Drawing)findViewById(R.id.drawing_area);  
}

person AndrewLugs    schedule 23.01.2013    source источник


Ответы (6)


В вашем классе View вам нужно переопределить метод onMeasure(). Здесь вы запрашиваете определенный размер просмотра. На эту тему есть несколько официальных руководств по Android, и я отредактирую этот пост, как только доберусь до своего компьютера со ссылками.

РЕДАКТИРОВАТЬ:

Ознакомьтесь с этой статьей Android о создании пользовательских компонентов. В частности, взгляните на раздел «Расширить onDraw() и onMeasure()». Цитата:

onMeasure() немного более вовлечен. onMeasure() — это важная часть контракта рендеринга между вашим компонентом и его контейнером. onMeasure() следует переопределить, чтобы эффективно и точно сообщать об измерениях содержащихся в нем частей. Это немного усложняется требованиями ограничений от родителя (которые передаются в метод onMeasure()) и требованием вызывать метод setMeasuredDimension() с измеренной шириной и высотой после их вычисления. Если вам не удастся вызвать этот метод из переопределенного метода onMeasure(), результатом будет исключение во время измерения.

Далее в статье:

Метод onMeasure() вашего компонента должен рассчитывать ширину и высоту измерений, которые потребуются для визуализации компонента. Он должен стараться оставаться в пределах спецификаций, переданных в, хотя может и превысить их (в этом случае родитель может выбрать, что делать, включая отсечение, прокрутку, создание исключения или запрос onMeasure() попробовать опять же, возможно, с другими спецификациями измерения).

Существует пример CustomView, доступный в качестве демонстрации, но, к сожалению, веб-сайт разработчика изменился (к худшему!), так что он недоступен, кроме как через загрузку диспетчером SDK. Дополнительные инструкции см. на странице здесь.

person D-Dᴙum    schedule 23.01.2013

Например, ширина 200, высота 150. Переопределить метод onMeasure в представлении.

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(200, 150);
    }
person takluiper    schedule 22.11.2017

Из вашего описания кажется, что проблема в том, что вы не указываете размер своего DemoView, вы просто устанавливаете его как ContentView, который по умолчанию заполняет родителя.

Укажите некоторые LayoutParams при создании DemoView или создайте ViewGroup чтобы дать ему размер.

Вы также можете определить макет/размер через XML и раздуть его. (В этом случае вы должны либо сделать его отдельным классом, либо сделать его общедоступным.) Например.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    Specify container measurements
    ...
    >
    <com.yourpackagename.MainActivity.DemoView
    ...
    Specify layout height / width, etc.
    ...
    />
</LinearLayout>
person PrplRugby    schedule 23.01.2013
comment
Спасибо, что изучили это. У вас есть пример этого, который вы могли бы показать мне? Если я удалю setContentView, изображение не будет загружено, поэтому я не уверен, как определить размер и отобразить его без включения этой строки кода. - person AndrewLugs; 24.01.2013

В Android такие элементы макета, как то, что вы пытаетесь сделать, обычно указываются в xml. Идея состоит в том, что вы настраиваете свой макет в формате xml (в вашем проекте должен быть каталог макета в каталоге res/ вашего проекта), а затем подключаете свой код к этому макету.

Взгляните на эту страницу. Если вы прокрутите вниз, вы увидите раздел о положении макета, размере и отступах.

person ForeverWintr    schedule 23.01.2013

Это метод, который вы можете переопределить, чтобы получить информацию об устройствах экрана, выполняется один раз для каждого устройства.

 @Override
public void onSizeChanged (int w, int h, int oldw, int oldh)
{
    super.onSizeChanged(w, h, oldw, oldh);
    screenW = w;
    screenH = h;

    scaledCardW = (int) (screenW/8); //or whatever scale you need for bitmaps
    scaledCardH = (int) (scaledCardW*1.28);
    bitmap = // load your bitmaps

}
person JRowan    schedule 24.01.2013

Вы используете setContentView(), что само по себе означает, что весь вид является полноэкранным. если вы хотите, чтобы изображение было задано только определенного размера, вам нужно нарисовать его таким образом.

onDraw(Canvas canvas)
{
     super.onDraw(canvas)
     //This code is for straight centering
     //Also please do math outside of onDraw
     //also below math is pseudocode not actual android code
     canvas.drawBitmap(yourImageBitmap, 
         (screenSize.width / 2) - yourImageBitmap.width/2, 
         (screenSize.height / 2) - yourImageBitmap.height / 2),
         yourPaintObject)

    //The above code should draw your bitmap image in the center of the canvas

}

Также, как и ответы выше и ниже, я говорю, что если вы хотите изменить размер холста, вам нужно использовать onMeasure и установить их правильно. Лучше всего посмотреть исходный код класса ImageView http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4./android/widget/ImageView.java и посмотрите, как они это делают

person Raigex    schedule 23.01.2013
comment
Было бы неплохо прочитать размеры изображения один раз и сохранить их в Rect, а не при каждом вызове onDraw. - person PrplRugby; 23.01.2013
comment
правда так будет лучше. - person Raigex; 23.01.2013
comment
Спасибо, что изучили это. У вас есть пример этого, который вы могли бы показать мне? Если я удалю setContentView, изображение не будет загружено, поэтому я не уверен, как определить размер и отобразить его без включения этой строки кода. Несколько строк кода в качестве примера были бы очень полезны. - person AndrewLugs; 24.01.2013