2012-01-13 2 views
0

Это заставляло меня сходить с ума в течение последних нескольких часов.
У меня есть FrameLayout, на котором есть одна кнопка. Когда вы нажимаете кнопку, я хочу нарисовать новое слово и получить его измерения, чтобы рисовать вокруг него прямоугольник.Измерения TextView, сверху, слева не обновляются

Это код, который запускается при нажатии на кнопку «Далее»:

private OnClickListener m_onClickNext = new OnClickListener() 
{ 
    public void onClick(View v) 
    { 
     TextView tv = new TextView(context);     
     tv.setTextColor(0xFF000000); 
     tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 100);     
     tv.setText("TEXTSTRING"); 

     m_frameLayout.addView(tv, new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.CENTER)); 

     //tv.measure(0, 0); 
     int left = tv.getLeft(); 
     int top = tv.getTop(); 
     int right = left + tv.getMeasuredWidth(); 
     int bottom = top + tv.getMeasuredHeight(); 
    } 
}; 

слева и сверху равны 0 (ноль).
Добавление tv.measure(0, 0) atleast обновляет ширину и высоту.

Я пробовал звонить invalidate и requestLayout по телефону tv и m_frameLayout, без каких-либо успехов.

Я понимаю, что макет не закончил рисование .. но ПОЧЕМУ ????

ответ

0

Я понимаю, что макет еще не закончил рисование .. но, ПОЧЕМУ ????

Причина, по которой макет не выполнен, заключается в том, что вы используете тот же поток, который использует рисунок пользовательского интерфейса. Все, что вы делаете, это использовать один поток (поток пользовательского интерфейса), если вы не укажете иначе с помощью AsyncTask или другого потока. Invalidate() не является функцией, которая заставляет сразу перерисовывать. Invalidate() помещает все так, что когда поток пользовательского интерфейса свободен, он будет перерисовывать все, что было признано недействительным. Если вы продолжаете давать инструкции по интерфейсу пользовательского интерфейса, тогда перерисовка не имеет шансов произойти.

Другими словами, Invalidate не будет изменять свои номера до тех пор, пока у чертежа не появится возможность запускать, и поскольку ему не дают шанс запустить, прежде чем запрашивать его номера, он не может дать вам правильные номера. Чтобы сделать это по-своему, необходимо сделать пару вещей:

  1. Вы должны разрешить макет рисовать. Это можно сделать тремя способами: a) Вы можете запустить свой клик по другому потоку, но это не гарантирует, когда это будет сделано, только так оно и будет. b) Вы можете переопределить invalidate() так, чтобы он выполнял обратный вызов, чтобы вы знали, чтобы добавить прямоугольник. c) Вы можете реализовать слушателя так, чтобы ваш код выполнялся при изменении размера TextView.

  2. ПОСЛЕ того, как макет перерисовывается, вы можете применить свой специальный прямоугольник. Используя метод c) выше, вы можете сделать это в основном сразу. Тем не менее, вы должны убедиться, что вы снова недействительны(), вызывая потенциальный цикл обработки. Поэтому убедитесь, что у вас есть какой-то индикатор, чтобы сказать вам, что вы уже нарисовали прямоугольник, а не третий раз.

Надеется, что это помогает,

FuzzicalLogic

+0

Спасибо, я реализовал 'OnLayoutChangeListener' – Itsik

Смежные вопросы