问题描述
扩展Android ViewGroup类时,onLayout()
覆盖的目的是什么?我正在Android中进行自定义控件,但由于某种原因,内容(子View
对象)未显示.我的方法是扩展ViewGroup类,通过ViewGroup的addView()
方法添加子视图.然后,在我的主要活动中,我有以下代码:
When extending an Android ViewGroup class, what is the purpose of the onLayout()
override? I'm making a custom control in Android but for some reason the content (child View
objects) isn't displaying. My approach was to extend the ViewGroup class, adding child-Views via the addView()
method of ViewGroup. Then, in my main activity, I have the following code:
ChannelController myCC = new ChannelController(this);
setContentView(myCC);
ChannelController是扩展ViewGroup的自定义类的名称.我肯定做错了,因为屏幕上什么都没有显示.
ChannelController is the name of my custom class that extends ViewGroup. I must be doing something wrong because nothing is shown on the screen.
我知道我必须重写并实现onLayout()方法,但是要做什么呢?我知道在dev.android网站上有一整个页面专用于此,但是对我没有太大帮助,主要是因为我是新手.任何见识将不胜感激.
I understand that I must override and implement the onLayout() method, but with what? I know there's an entire page dedicated to this on the dev.android site, but it didn't help me much, mostly because I'm a newbie I guess. Any insight would be appreciated.
作为参考,我的ViewGroup扩展如下:
For reference, my ViewGroup extension looks like below:
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方法重写中我需要做什么?
What do I need to do in the onLayout method override?
推荐答案
在onLayout
中,您需要在此ViewGroup
的每个子级上调用layout
方法,并为其提供所需的位置(相对于父级).您可以检查FrameLayout
的源代码(ViewGroup
的最简单子类之一)以了解其工作原理.
In onLayout
you need to call layout
method on each child of this ViewGroup
and provide desired position (relatively to parent) for them. You can check source code of FrameLayout
(one of the simpliest subclasses of ViewGroup
) to find out how it works.
尽管,如果您不需要任何特殊"布局,则还有其他选择:
Although, if you don't need any "special" layouting, you have other options:
- 改为扩展
ViewGroup
的另一个子类(例如,FrameLayout
) - 如果您只需要控件看起来完全像XML一样(我认为这正是您的情况),请使用
LayoutInflater
- Extend some another subclass of
ViewGroup
instead (FrameLayout
for example) - Use
LayoutInflater
if you just need your control to look exactly as in XML (which, I think, is exactly your case)
这篇关于Android ViewGroup:我应该在onLayout()覆盖中做什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!