我在尝试以编程方式完成此布局时遇到问题,每次进程运行应用程序崩溃都没有成功。
我尝试以编程方式创建的XML部分是:
<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代码重新创建它:
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)
}
这是我获得tru 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,但它并不是很清楚如何以编程方式正确设置这些资源......
提前致谢。
PD:如果我找到了我会更新的内容。真的欢迎任何帮助!
更新1.0:
好了关注logcat我必须在孩子的父母那里调用removeView,但是我不知道究竟在哪里......寻找那个......
答案 0 :(得分:1)
好的解决方案如下:
只需在添加子项之前在所有父项上添加removeAllView
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上的错误指向了我正确的方向!
答案 1 :(得分:0)
从以上答案中得到启发。 这是我的助手功能。
在OnViewCreated
val titleCard = createNumberCard()
val verse1Card:CardView = createVerseCard()
detailLinearLayout.addView(titleCard, 0)
detailLinearLayout.addView(verse1Card, 1)
private fun createVerseCard(): CardView {
//verseCard
val verseCard = CardView(requireActivity())
verseCard.setId(View.generateViewId())
val verseCardLayout = ConstraintLayout(activity)
verseCardLayout.layoutParams = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.MATCH_PARENT,
ConstraintLayout.LayoutParams.MATCH_PARENT
)
verseCard.addView(verseCardLayout)
val set = ConstraintSet()
val verseView = TextView(activity)
verseView.text = "Verse 1"
verseView.setId(View.generateViewId())
verseCardLayout.addView(verseView, 0)
set.clone(verseCardLayout)
set.connect(
verseView.getId(),
ConstraintSet.TOP,
verseCardLayout.getId(),
ConstraintSet.TOP,
0
)
set.applyTo(verseCardLayout)
return verseCard
}
我在片段中使用它们。