Android ViewGroup: что мне делать в переопределении onLayout()?
Расширяя класс Android ViewGroup, какова цель переопределения onLayout()
? Я делаю пользовательский контроль в Android, но по какой-то причине контент (дочерние объекты View
) не отображается. Мой подход состоял в том, чтобы расширить класс ViewGroup, добавив child-Views через метод addView()
ViewGroup. Затем, в моем основном действии, у меня есть следующий код:
ChannelController myCC = new ChannelController(this);
setContentView(myCC);
ChannelController - это имя моего пользовательского класса, который расширяет ViewGroup. Я должен делать что-то неправильно, потому что на экране ничего не отображается.
Я понимаю, что я должен переопределить и реализовать метод onLayout(), но с чем? Я знаю там целую страницу, посвященную этому на сайте dev.android, но это не помогло мне, главным образом потому, что я новичок, я думаю. Любое понимание было бы оценено.
Для справки мое расширение ViewGroup выглядит следующим образом:
public class ChannelController extends ViewGroup {
final String TAG = "JAL";
public ChannelController(Context c)
{
super(c);
init(c);
}
public ChannelController(Context c, AttributeSet attibset)
{
super(c);
init(c);
}
public ChannelController(Context c, AttributeSet attribset, int defStyle)
{
super(c);
init(c);
}
public void init(Context c)
{
//RelativeLayout wrap = new RelativeLayout(c);
RelativeLayout.LayoutParams wrapLP = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
RelativeLayout r1 = new RelativeLayout(c);
RelativeLayout.LayoutParams r1LP = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
RelativeLayout r2 = new RelativeLayout(c);
RelativeLayout.LayoutParams r2LP = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
TextView t = new TextView(c);
RelativeLayout.LayoutParams tlp = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
Button m = new Button(c);
RelativeLayout.LayoutParams mlp = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
Button s = new Button(c);
RelativeLayout.LayoutParams slp = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
SeekBar f = new SeekBar(c);
RelativeLayout.LayoutParams flp = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
t.setId(1);
m.setId(2);
s.setId(3);
f.setId(4);
r1.setId(5);
r2.setId(6);
t.setText("CHANNELNAME");
t.setTextColor(Color.BLACK);
tlp.setMargins(30, 0, 0, 0);
tlp.addRule(RelativeLayout.LEFT_OF, m.getId());
tlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
tlp.addRule(RelativeLayout.CENTER_VERTICAL);
tlp.addRule(RelativeLayout.CENTER_HORIZONTAL);
m.setText("M");
m.setBackgroundColor(Color.rgb(237, 155, 31));
m.setTextColor(Color.WHITE);
mlp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
mlp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
m.setTextSize(10);
flp.addRule(RelativeLayout.LEFT_OF, s.getId());
flp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
flp.addRule(RelativeLayout.CENTER_VERTICAL);
s.setText("S");
s.setTextSize(10);
s.setBackgroundColor(Color.rgb(192, 48, 46));
s.setTextColor(Color.WHITE);
slp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
slp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
r1.addView(t, tlp);
r1.addView(m, mlp);
r2.addView(f, flp);
r2.addView(s, slp);
r1.setBackgroundColor(Color.rgb(233, 242, 251));
r2.setBackgroundColor(Color.rgb(233, 242, 251));
r1LP.addRule(RelativeLayout.ALIGN_PARENT_TOP);
r2LP.addRule(RelativeLayout.BELOW, r1.getId());
this.addView(r1, r1LP);
this.addView(r2, r2LP);
this.setLayoutParams(wrapLP);
//this.addView(wrap);
Log.i(TAG, "ChannelController constructor was called");
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
//super.onLayout(changed, l, t, r, b);
}
}
Что мне нужно сделать в переопределении метода onLayout?
Ответы
Ответ 1
В onLayout
вам нужно вызвать метод layout
для каждого дочернего элемента этого ViewGroup
и предоставить для них желаемую позицию (относительно родительской). Вы можете проверить исходный код FrameLayout
(один из самых простых подклассов ViewGroup
), чтобы узнать, как он работает.
Хотя, если вам не нужен какой-либо "специальный" макет, у вас есть другие варианты:
- Расширьте еще один подкласс
ViewGroup
вместо (FrameLayout
например)
- Используйте
LayoutInflater
, если вам просто нужен ваш контроль, чтобы он выглядел точно так же, как в XML (что, я думаю, это именно ваш случай)