与儿童一起定制 Android 控件
我正在尝试创建一个自定义 Android 控件,其中包含 LinearLayout。您可以将其视为带有精美边框、背景、左侧图像的扩展 LinearLayout...
我可以在 XML 中完成所有操作(效果很好),但由于我的应用程序中出现了数十次,因此很难维护。我认为有这样的东西会更好:
/* Main.xml */
<MyFancyLayout>
<TextView /> /* what goes inside my control's linear layout */
</MyfancyLayout>
你会如何处理这个问题?我想避免重写整个线性布局 onMeasure / onLayout 方法。这就是我目前所拥有的:
/* MyFancyLayout.xml */
<TableLayout>
<ImageView />
<LinearLayout id="container" /> /* where I want the real content to go */
</TableLayout>
以及
/* MyFancyLayout.java */
public class MyFancyLayout extends LinearLayout
{
public MyFancyLayout(Context context) {
super(context);
View.inflate(context, R.layout.my_fancy_layout, this);
}
}
如何将用户指定的内容(main.xml 中的 TextView)插入到正确的位置(id=container)?
干杯!
Romain
----- 编辑 -------
仍然没有运气,所以我改变了我的设计以使用更简单的布局,并决定接受一些重复的 XML。但仍然对任何人知道如何做到这一点非常感兴趣!
I'm trying to create a custom Android control that contains a LinearLayout. You can think of it as an extended LinearLayout with fancy borders, a background, an image on the left...
I could do it all in XML (works great) but since I have dozens of occurences in my app it's getting hard to maintain. I thought it would be nicer to have something like this:
/* Main.xml */
<MyFancyLayout>
<TextView /> /* what goes inside my control's linear layout */
</MyfancyLayout>
How would you approach this? I'd like to avoid re-writing the whole linear layout onMeasure / onLayout methods. This is what I have for the moment:
/* MyFancyLayout.xml */
<TableLayout>
<ImageView />
<LinearLayout id="container" /> /* where I want the real content to go */
</TableLayout>
and
/* MyFancyLayout.java */
public class MyFancyLayout extends LinearLayout
{
public MyFancyLayout(Context context) {
super(context);
View.inflate(context, R.layout.my_fancy_layout, this);
}
}
How would you go about inserting the user-specified content (the TextView in main.xml) in the right place (id=container)?
Cheers!
Romain
----- edit -------
Still no luck on this, so I changed my design to use a simpler layout and decided to live with a bit of repeated XML. Still very interested in anyone knows how to do this though!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这个确切的问题已经困扰我一段时间了,但直到现在我才解决了它。
乍一看,问题在于这样一个事实:声明性内容(在您的例子中为 TextView)是在 ctor 之后的某个时间实例化的(我们通常会在其中膨胀我们的布局),因此现在同时拥有这两者还为时过早手头的声明性内容和模板内容将前者推入后者。
我发现了一个这样的地方,我们可以操纵这两者:它是一个 onFinishInflate() 方法。在我的例子中,它是这样的:
上面引用的labeled_layout.xml与这样的东西没有什么不同:
现在(仍然省略一些细节)在其他地方我们可以像这样使用它:
This exact question bugged me for some time already but it's only now that I've solved it.
From a first glance, the problem lies in the fact that a declarative content (TextView in Your case) is instantiated sometime after ctor (where we're usually inflating our layouts), so it's too early have both declarative and template content at hand to push the former inside the latter.
I've found one such place where we can manipulate the both: it's a onFinishInflate() method. Here's how it goes in my case:
A labeled_layout.xml referenced above is not unlike something like this:
Now (still omitting some details) elsewhere we might use it like this:
这种方法节省了我很多代码! :)
正如 esteewhy 所解释的,只需将 xml 定义的内容交换到您自己的布局中您想要的内部位置,即
onFinishInflate()
中。示例:我获取在 xml 中指定的内容:
... 并将它们移动到名为
contents
的内部LinearLayout
中,我希望它们位于以下位置:与 自定义 XML 属性变得非常易于维护。
This approach saves me a lot of code! :)
As esteewhy explains, just swap the xml-defined contents into where you want them internally in your own layout, in
onFinishInflate()
. Example:I take the contents that I specify in the xml:
... and move them to my internal
LinearLayout
calledcontents
where I want them to be:Combined with custom XML attributes things gets very maintainable.
您可以通过扩展 LinearLayout 来创建 MyFancyLayout 类。添加三个调用方法(在本例中为“初始化”)的构造函数来设置其余视图:
在初始化中,您可以执行任何需要添加额外视图的操作。您可以获取 LayoutInflater 并膨胀另一个布局:
或者您可以在代码中创建视图并添加它们:
如果您要大量使用 Context,您可以在构造函数中存储对它的引用并使用它而不是
getContext()
以节省一点开销。You can create your MyFancyLayout class by extending LinearLayout. Add the three constructors which call a method ("initialize" in this case) to set up the rest of the Views:
Within initialize, you do anything you need to to add the extra views. You can get the LayoutInflater and inflate another layout:
Or you can create Views in code and add them:
If you're going to use the Context a lot, you can store a reference to it in your constructors and use that rather than
getContext()
to save a little overhead.只需使用这样的东西:
有用的链接 - http://www.anddev.org/creating_custom_views_- _the_togglebutton-t310.html
just use something like this:
Useful link - http://www.anddev.org/creating_custom_views_-_the_togglebutton-t310.html