以编程方式创建布局资源 Kotlin Android [英] Create Layout Resource Programmatically Kotlin Android
问题描述
我在尝试完全以编程方式制作此布局时遇到问题,每次进程运行都没有成功结束并且应用程序崩溃.
I'm having problems trying to make this Layout totally programmatically, every time the process run end without success and the app crashes.
我试图以编程方式创建的 XML 部分是:
The Part of XML im trying to create programmatically is it :
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/idImagenPlay0"
android:layout_width="62dp"
android:layout_height="54dp"
android:layout_marginRight="10dp"
android:layout_marginTop="15dp"
android:src="@drawable/ic_action_play" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/idNombre0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="Description"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/idInfo0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:layout_marginRight="10dp"
android:text="Title" />
</LinearLayout>
<ImageView
android:id="@+id/idImagenShare0"
android:layout_width="54dp"
android:layout_height="48dp"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:layout_marginTop="15dp"
android:src="@drawable/ic_action_share" />
</RelativeLayout>
</LinearLayout>
我正在尝试使用以下 kotlin 代码重新创建它:
I'm trying to recreate it with the following kotlin code:
fun createXmlElement(title:String,description:String){
val parent = LinearLayout(this)
parent.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT)
parent.orientation = LinearLayout.HORIZONTAL
//children of parent linearlayout
val iv = ImageView(this)
val lp = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT)
lp.setMargins(0, 11, 7, 0)
iv.setLayoutParams(lp)
iv.setImageResource(R.drawable.ic_action_play)
iv.getLayoutParams().height = 40;
iv.getLayoutParams().width = 46;
parent.addView(iv); // lo agregamos al layout
val relativeP = RelativeLayout(this)
relativeP.layoutParams = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT)
val linearCH = LinearLayout(this)
linearCH.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT)
// TextView1
val tv1 = TextView(this)
val lptv1 = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT)
lptv1.setMargins(0, 7, 0, 0)
tv1.setLayoutParams(lptv1)
tv1.setText(title) // nombre de la musica
tv1.setTextSize(TypedValue.COMPLEX_UNIT_SP,25F)
tv1.setTypeface(null, Typeface.BOLD);
// TextView2
val tv2 = TextView(this)
val lptv2 = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT)
lptv2.setMargins(0, 11, 7, 0)
tv2.setLayoutParams(lptv1)
tv2.setText(description) // Descripcion de la musica
tv2.setTextSize(TypedValue.COMPLEX_UNIT_SP, 25F)
tv2.setTypeface(null, Typeface.BOLD);
linearCH.addView(tv1)
linearCH.addView(tv2)
relativeP.addView(linearCH)
// last ImageView
val iv2 = ImageView(this)
val lpiv2 = RelativeLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT)
lpiv2.setMargins(0, 11, 7, 0)
lpiv2.addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
iv2.setLayoutParams(lpiv2)
iv2.setImageResource(R.drawable.ic_action_share)
iv2.getLayoutParams().height = 40;
iv2.getLayoutParams().width = 46;
parent.addView(iv)
parent.addView(relativeP)
parent.addView(iv2)
}
这是我在 logcat 中遇到的错误
This is the error I'm getting in logcat
04-27 10:51:01.224 6973-6973/com.klystru.app.appE/AndroidRuntime: FATAL EXCEPTION: main
Process: com.klystru.app.app, PID: 6973
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.klystru.app.app/com.klystru.app.app.MainActivity}: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2583)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1499)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5765)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.view.ViewGroup.addViewInner(ViewGroup.java:4453)
at android.view.ViewGroup.addView(ViewGroup.java:4281)
at android.view.ViewGroup.addView(ViewGroup.java:4222)
at android.view.ViewGroup.addView(ViewGroup.java:4195)
at com.klystru.app.app.MainActivity.createXmlElement(MainActivity.kt:284)
at com.klystru.app.app.MainActivity.onCreate(MainActivity.kt:121)
at android.app.Activity.performCreate(Activity.java:6309)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2530)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1499)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5765)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
我仍在研究它可能是什么,我怀疑它可能是错误的 LayoutParams,但并不清楚如何以编程方式正确设置这些资源.
I still research what it can be, I'm suspecting it may be wrong LayoutParams, but it's not really clear about how to set up correctly those resources programmatically.
提前致谢.
PD:如果我发现了什么我会更新.
PD: If I found something I will update.
非常欢迎任何帮助!
更新 1.0:
好的,按照 logcat,我必须在孩子的父母中调用 removeView
,但我不知道确切的位置.我正在寻找那个.
Ok following the logcat I have to call removeView
in child's parent, but I don't know exactly where. I am looking for that.
推荐答案
好的解决方案如下:
只需要在添加子项之前在所有父项上添加 removeAllView
Just need to add removeAllView on all parents before adding the childs
protected fun createXmlElement(title:String,description:String){
val parent = LinearLayout(this)
parent.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT)
parent.orientation = LinearLayout.HORIZONTAL
//children of parent linearlayout
val iv = ImageView(this)
val lp = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT)
lp.setMargins(0, 11, 7, 0)
iv.setLayoutParams(lp)
iv.setImageResource(R.drawable.ic_action_play)
iv.getLayoutParams().height = 40
iv.getLayoutParams().width = 46
parent.addView(iv); // lo agregamos al layout
val relativeP = RelativeLayout(this)
relativeP.layoutParams = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT)
val linearCH = LinearLayout(this)
linearCH.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT)
// TextView1
val tv1 = TextView(this)
val lptv1 = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT)
lptv1.setMargins(0, 7, 0, 0)
tv1.setLayoutParams(lptv1)
tv1.setText(title) // title
tv1.setTextSize(TypedValue.COMPLEX_UNIT_SP,25F)
tv1.setTypeface(null, Typeface.BOLD)
// TextView2
val tv2 = TextView(this)
val lptv2 = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT)
lptv2.setMargins(0, 11, 7, 0)
tv2.setLayoutParams(lptv1)
tv2.setText(description) // description
tv2.setTextSize(TypedValue.COMPLEX_UNIT_SP, 25F)
tv2.setTypeface(null, Typeface.BOLD)
linearCH.removeAllViews()
linearCH.addView(tv1)
linearCH.addView(tv2)
relativeP.removeAllViews()
relativeP.addView(linearCH)
// last ImageView
val iv2 = ImageView(this)
val lpiv2 = RelativeLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT)
lpiv2.setMargins(0, 11, 7, 0)
lpiv2.addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
iv2.setLayoutParams(lpiv2)
iv2.setImageResource(R.drawable.ic_action_share)
iv2.getLayoutParams().height = 40
iv2.getLayoutParams().width = 46
parent.removeAllViews()
parent.addView(iv)
parent.addView(relativeP)
parent.addView(iv2)
val finalParent = this.findViewById(R.id.contenedor) as ViewGroup
finalParent.addView(parent)
}
感谢 Nsion,logcat 上的错误为我指明了正确的方向!
Thanks NSion, the error on logcat point to me the right direction!
这篇关于以编程方式创建布局资源 Kotlin Android的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!