GetWidth() возвращает 0, если установлено android: layout_width = "match_parent"
У меня есть класс под названием FractalView, который расширяет ImageView. Моя цель - нарисовать фрактал с этим классом, который имеет размер всего экрана. Это единственный вид в моем файле макета активности, отличный от LinearLayout верхнего уровня:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFFFF">
<com.antonc.fractal_wallpaper.FractalView
android:id="@+id/fractal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"/>
</LinearLayout>
Как вы можете видеть, я использую "match_parent" для layout_width и layout_height как FractalView, так и LinearLayout. В этот момент я предположил, что размер FractalView установлен на определенное значение, так как он соответствует ему parent, который сопоставляет его родительским (это весь экран).
Затем я пытаюсь определить размер, доступный для FractalView, используя getWidth() и getHeight():
public class FractalView extends ImageView {
private Context mContext;
private Handler mHandler;
private int mScrWidth;
private int mScrHeight;
public FractalView(Context context) {
super(context);
mContext = context;
init();
}
private void init() {
mScrWidth = getWidth();
mScrHeight = getHeight();
// Breakpoint
}
@Override
protected void onDraw(Canvas canvas) {
[...]
}
}
Но когда мой код достигает точки останова, отладчик показывает, что mScrWidth и mScrHeight равны нулю. Я пробовал использовать getMeasuredWidth() и getMaxWidth(), но они также возвращают неверные значения. Я прочитал несколько ответов на похожие вопросы, т.е. этот, и все они объясняют, что getWidth() возвращает размер изображения после его рисования, а то, что я на самом деле нужна ширина области, доступной для этого вида, прежде чем я начну рисовать.
Есть ли способ получить такие значения для ширины и высоты?
Ответы
Ответ 1
Размер представления недоступен только после onMeasure()
, особенно если его установить на wrap_content
или fill_parent
.
Вы должны либо получить доступ к размеру в или после onMeasure()
в коде просмотра, либо в обозревателе дерева макетов:
LinearLayout layout = (LinearLayout)findViewById(R.id.mylayout);
ViewTreeObserver vto = layout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
this.layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
int width = layout.getMeasuredWidth();
int height = layout.getMeasuredHeight();
}
});
Вам также нужно добавить android:id="@+id/mylayout"
к вашему LinearLayout для второго, чтобы он работал.
Ответ 2
Я понял способ сделать это, пока я печатал вопрос.
Вместо того, чтобы пытаться получить размер в методе конструктора, я переместил код в метод onDraw()
следующим образом:
private void init() {
}
@Override
protected void onDraw(Canvas canvas) {
mScrWidth = canvas.getWidth();
mScrHeight = canvas.getHeight();
[...]
}
Это возвращает правильные размеры.