Rom*_*ain 12 android border android-linearlayout
我试图创建一个定制的Android控制是包含一个LinearLayout中.您可以将其视为具有花式边框,背景,左侧图像的扩展LinearLayout ...
我可以用XML完成所有工作(效果很好),但由于我的应用程序中有很多次出现,因此很难维护.我觉得这样的东西会更好:
/* Main.xml */
<MyFancyLayout>
<TextView /> /* what goes inside my control's linear layout */
</MyfancyLayout>
Run Code Online (Sandbox Code Playgroud)
你会怎么做?我想避免在onMeasure/onLayout方法上重写整个线性布局.这就是我现在所拥有的:
/* MyFancyLayout.xml */
<TableLayout>
<ImageView />
<LinearLayout id="container" /> /* where I want the real content to go */
</TableLayout>
Run Code Online (Sandbox Code Playgroud)
和
/* MyFancyLayout.java */
public class MyFancyLayout extends LinearLayout
{
public MyFancyLayout(Context context) {
super(context);
View.inflate(context, R.layout.my_fancy_layout, this);
}
}
Run Code Online (Sandbox Code Playgroud)
您如何在正确的位置(id =容器)插入用户指定的内容(main.xml中的TextView)?
干杯!
罗曼
-----编辑-------
仍然没有运气,所以我改变了我的设计,使用更简单的布局,并决定使用一些重复的XML.仍然非常感兴趣的人知道如何做到这一点!
est*_*why 10
这个确切的问题已经困扰了我一段时间了,但现在我才解决了这个问题.
乍一看,问题在于声明内容(在你的情况下是TextView)在 ctor 之后的某个时候实例化(我们通常会夸大我们的布局),所以现在声明和模板内容都太早了把前者推到后者里面.
我找到了一个可以操纵两者的地方:它是一个onFinishInflate()方法.以下是我的情况:
@Override
protected void onFinishInflate() {
int index = getChildCount();
// Collect children declared in XML.
View[] children = new View[index];
while(--index >= 0) {
children[index] = getChildAt(index);
}
// Pressumably, wipe out existing content (still holding reference to it).
this.detachAllViewsFromParent();
// Inflate new "template".
final View template = LayoutInflater.from(getContext())
.inflate(R.layout.labeled_layout, this, true);
// Obtain reference to a new container within "template".
final ViewGroup vg = (ViewGroup)template.findViewById(R.id.layout);
index = children.length;
// Push declared children into new container.
while(--index >= 0) {
vg.addView(children[index]);
}
// They suggest to call it no matter what.
super.onFinishInflate();
}
Run Code Online (Sandbox Code Playgroud)
上面引用的labeled_layout.xml与以下内容不同:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation ="vertical"
android:layout_width ="fill_parent"
android:layout_height ="wrap_content"
android:layout_marginLeft ="8dip"
android:layout_marginTop ="3dip"
android:layout_marginBottom ="3dip"
android:layout_weight ="1"
android:duplicateParentState ="true">
<TextView android:id ="@+id/label"
android:layout_width ="fill_parent"
android:layout_height ="wrap_content"
android:singleLine ="true"
android:textAppearance ="?android:attr/textAppearanceMedium"
android:fadingEdge ="horizontal"
android:duplicateParentState="true" />
<LinearLayout
android:id ="@+id/layout"
android:layout_width ="fill_parent"
android:layout_height ="wrap_content"
android:layout_marginLeft ="8dip"
android:layout_marginTop ="3dip"
android:duplicateParentState="true" />
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
现在(仍然省略一些细节)我们可能会像这样使用它:
<com.example.widget.LabeledLayout
android:layout_width ="fill_parent"
android:layout_height ="wrap_content">
<!-- example content -->
</com.example.widget.LabeledLayout>
Run Code Online (Sandbox Code Playgroud)
这种方法为我节省了大量代码!:)
正如esteewhy所解释的那样,只需将xml定义的内容交换到您希望它们在您自己的布局中的位置onFinishInflate().例:
我把我在xml中指定的内容:
<se.jog.custom.ui.Badge ... >
<ImageView ... />
<TextView ... />
</se.jog.custom.ui.Badge>
Run Code Online (Sandbox Code Playgroud)
...并将它们移动到我希望它们所在的内部LinearLayout调用 contents:
public class Badge extends LinearLayout {
//...
private LinearLayout badge;
private LinearLayout contents;
// This way children can be added from xml.
@Override
protected void onFinishInflate() {
View[] children = detachChildren(); // gets and removes children from parent
//...
badge = (LinearLayout) layoutInflater.inflate(R.layout.badge, this);
contents = (LinearLayout) badge.findViewById(R.id.badge_contents);
for (int i = 0; i < children.length; i++)
addView(children[i]); //overridden, se below.
//...
super.onFinishInflate();
}
// This way children can be added from other code as well.
@Override
public void addView(View child) {
contents.addView(child);
}
Run Code Online (Sandbox Code Playgroud)
结合自定义XML属性,事物变得非常易于维护.
小智 0
只需使用这样的东西:
<org.myprogram.MyFancyLayout>
...
</org.myprogram.MyFancyLayout>
Run Code Online (Sandbox Code Playgroud)
有用的链接 - http://www.anddev.org/creating_custom_views__-_the_togglebutton-t310.html