以编程方式创建布局资源 Kotlin Android [英] Create Layout Resource Programmatically Kotlin Android

查看:32
本文介绍了以编程方式创建布局资源 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆