android TableLayout 根本没有出现

android TableLayout does not appear at all

我希望单击按钮后,出现包含 table 的片段。 除 Table 布局外,所有内容均已显示。 没弄明白为什么。

这是我的 table 布局:

<android.support.v4.widget.NestedScrollView
        android:id="@+id/nested_scroll_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="none"
        android:scrollingCache="true">
        <TableLayout android:id="@+id/simpleTableLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            xmlns:android="http://schemas.android.com/apk/res/android" >
            <TableRow
                android:layout_height="wrap_content"
                android:layout_width="fill_parent"
                android:gravity="center_horizontal">
                <TextView
                    android:layout_width="wrap_content" android:layout_height="wrap_content"
                    android:textSize="18dp" android:text="Row 1"  android:layout_span="3"
                    android:padding="18dip" android:background="#b0b0b0"
                    android:textColor="#000"/>
                <TextView
                    android:layout_width="wrap_content" android:layout_height="wrap_content"
                    android:textSize="18dp" android:text="Row 1"  android:layout_span="3"
                    android:padding="18dip" android:background="#b0b0b0"
                    android:textColor="#000"/>
            </TableRow>
        </TableLayout>
    </android.support.v4.widget.NestedScrollView>

这里是我片段的重要方法:

class TablePresentation : DialogFragment(),tableContract.View
{
...
override fun onCreateView(inflater: LayoutInflater?, parent: ViewGroup?, state: Bundle?): View? {
    super.onCreateView(inflater, parent, state)
    val view = activity.layoutInflater.inflate(R.layout.table_fragment, parent, false)
    view.findViewById<View>(R.id.button_close)?.setOnClickListener({ dismiss() })
    return view
}

override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    table = view?.findViewById<View>(R.id.simpleTableLayout) as TableLayout
    row = LayoutInflater.from(context).inflate(R.layout.attrib_row, null) as TableRow
    attName= (row?.findViewById<View>(R.id.attrib_name) as TextView)
    attVal=(row?.findViewById<View>(R.id.attrib_value) as TextView)
}


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setStyle(DialogFragment.STYLE_NORMAL, R.style.FullScreenDialogStyle)
}
...
}

考虑到第一个答案后 table 出现了,但是一旦我尝试使用此代码动态地做到这一点:

class TablePresentation : DialogFragment(),tableContract.View
{
...
    var table: TableLayout?=null
    var row:TableRow?=null
    var attName:TextView?=null
    var attVal:TextView?=null

...
    override fun updateTable(temps: ArrayList<Double>) {
        for (i in 0 until temps.size) {
            attName?.setText((i+1).toString())
            attVal?.setText(temps.get(i).toString())
            table?.addView(row)
        }
        table?.requestLayout()
    }
}

第一次点击没有显示任何内容。

and in the second clik it crashes and shows: 
E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.tharwa.tdm2_exo2, PID: 10114
                  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:4454)
                      at android.view.ViewGroup.addView(ViewGroup.java:4295)
                      at android.widget.TableLayout.addView(TableLayout.java:426)
                      at android.view.ViewGroup.addView(ViewGroup.java:4235)
                      at android.widget.TableLayout.addView(TableLayout.java:408)
                      at android.view.ViewGroup.addView(ViewGroup.java:4208)
                      at android.widget.TableLayout.addView(TableLayout.java:399)
                      at com.tharwa.tdm2_exo2.TableAgent.TablePresentation.updateTable(TablePresentation.kt:63)
...

我不明白如何先在 child 的 parent 上调用 removeView(),以及如何使其动态显示。

尝试在 xml.

中使用以下代码
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/nested_scroll_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="none"
    android:scrollingCache="true">

    <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/simpleTableLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:stretchColumns="*">

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:weightSum="2">

            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#b0b0b0"
                android:padding="18dip"
                android:text="Row 1"
                android:textColor="#000"
                android:textSize="18dp" />

            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#b0b0b0"                
                android:text="Row 2"
                android:textColor="#000"
                android:textSize="18dp" />
        </TableRow>
    </TableLayout>
</android.support.v4.widget.NestedScrollView>

更新问题 删除你的循环并尝试它。

for (int i = 0; i < temps.size(); i++) {
TableRow row = new TableRow(getActivity());
row.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT));
row.setWeightSum(2.0f);
tv1 = new TextView(getActivity());
tv2= new TextView(getActivity());

tv1.setLayoutParams(new TableRow.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f));
tv2.setLayoutParams(new TableRow.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f));

tv1.setGravity(Gravity.CENTER);
tv2.setGravity(Gravity.CENTER);

tv1.setText((i+1).toString());
tv2.setText(temps.get(i).toString());

// finally add our textviews to TableRow
row.addView(tv1); 
row.addView(tv2); 

//finally add our TableRow to Tablelayout
table.addView(row, i);
}

谢谢@ZarNi Myo Sett Win 的回答。 Kotlin will 上的代码是这样的:

 fun updateTable()
 {
     val temps=controller?.getTemps()
     for (i in 0 until temps!!.size) {
    val row =  TableRow( activity)
    row.layoutParams=(LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
            LinearLayout.LayoutParams.WRAP_CONTENT))
    row.weightSum=2.0f
    val tv1 = TextView( activity)
    val tv2= TextView(activity)
    tv1.layoutParams=(TableRow.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f))
    tv2.layoutParams=(TableRow.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f))


    tv1.gravity=(Gravity.CENTER)
    tv2.gravity=(Gravity.CENTER)

    tv1.text=(i+1).toString()
    tv2.text=temps[i].toString()
    // finally add our textviews to TableRow
    row.addView(tv1)
    row.addView(tv2)
    //finally add our TableRow to Tablelayout
    table!!.addView(row, i)
    }
 }

并且应该在创建时调用它

  override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        table = view?.findViewById<View>(R.id.simpleTableLayout) as TableLayout
        updateTable()
    }

但是为了最小化代码行并使我们可以使用更多awsom: 这是 table 视图

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/nested_scroll_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="none"
    android:scrollingCache="true">
    <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/simpleTableLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="45dp"
        android:layout_marginRight="45dp"
        android:stretchColumns="*"
        >
    </TableLayout>
</android.support.v4.widget.NestedScrollView>

这里是要使用的行 "attrib_row.xml"

<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@drawable/border"
    >
    <TextView
        android:id="@+id/attrib_name"
        android:textStyle="bold"
        android:height="30dp"
        android:background="@drawable/border"
        android:gravity="center"
        />
    <TextView
        android:id="@+id/attrib_value"
        android:gravity="center"
        android:height="30dp"
        android:textStyle="bold"
        android:background="@drawable/border"
        />
</TableRow>

我们可以将这个 xml 文件添加到可绘制对象中,为我们的 table "border.xml"

添加边框
<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape= "rectangle">
    <solid android:color="@color/colorAccent"/>
    <stroke android:width="1dp" android:color="#000000"/>
</shape>

最后是压缩代码

fun updateTable()
{
    val temps=controller?.getTemps()
    val rowHead = LayoutInflater.from(context).inflate(R.layout.attrib_row, null) as TableRow
    (rowHead.findViewById<View>(R.id.attrib_name) as TextView).text=("time")
    (rowHead.findViewById<View>(R.id.attrib_value) as TextView).text=("Value")
    table!!.addView(rowHead)
    for (i in 0 until temps!!.size) {

        val row = LayoutInflater.from(context).inflate(R.layout.attrib_row, null) as TableRow
        (row.findViewById<View>(R.id.attrib_name) as TextView).text=((i+1).toString())
        (row.findViewById<View>(R.id.attrib_value) as TextView).text=(temps[i].toString())
        table!!.addView(row)
    }
    table!!.requestLayout()
}