【问题标题】:Android TableLayout Header rowAndroid TableLayout 标题行
【发布时间】:2010-12-14 12:19:56
【问题描述】:

好的,我已经得到了这个 TableLayout,它充满了数据——所有的行都以编程方式添加。我在 Horizo​​ntalScrollView 内有 TableLayout,而后者又在 ScrollView 内 - 这让我可以水平和垂直滚动。我现在要做的是向它添加一个不会滚动的标题行。我尝试移动一些东西,以便我的两个滚动视图实际上都在 TableLayout 内部,并将 TableRows 添加到 Horizo​​ntalScrollView;我希望能够在滚动视图之外添加标题行。

我能想到的唯一另一件事是为标题行设置第二个表格布局,但让列对齐似乎很困难。有什么想法吗?

【问题讨论】:

    标签: android android-layout android-tablelayout


    【解决方案1】:

    一种方法是将 TableLayout 嵌入到另一个 TableLayout 的行中,并将标题放在前一行中,如下所示。对齐数据和标题需要标题视图对象的 layout_width 属性和数据的视图对象设置为相同的倾角值。此外,内部 TableLayout 的 View 对象的 layout_weight 属性必须与其对应的标题匹配。 现在,在下面的 XML 中,我在单行的内部 TableLayout 中放置了 3 个 TextView,以与列标题匹配。这只是为了说明如何进行对齐。您可以通过扩展布局并在运行时添加它来以编程方式填充该数据。

    <?xml version="1.0" encoding="utf-8"?>
    <TableLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent">
    
    
      <TableRow>
        <TextView android:text="Name"
            android:layout_width="100dp"        
            android:layout_column="0"
            android:layout_weight="1"/>
        <TextView android:text="Score"
            android:layout_width="30dp"
            android:layout_column="1"
            android:layout_weight="1">
        </TextView>
        <TextView android:text="Level"
            android:layout_width="30dp"
            android:layout_column="2"
            android:layout_weight="1">
        </TextView>
      </TableRow>
    
        <ScrollView android:layout_height="120dp">      
        <TableLayout android:id="@+id/score_table"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent">          
        <TableRow>
            <TextView android:text="Al"
            android:layout_width="100dp"        
            android:layout_column="0"
            android:layout_weight="1">
            </TextView>
            <TextView android:text="1000"
            android:layout_width="30dp"
            android:layout_column="1"
            android:layout_weight="1">
            </TextView>
            <TextView android:text="2"
            android:layout_width="30dp"
            android:layout_column="2"
            android:layout_weight="1">
            </TextView>
        </TableRow>
      </TableLayout>
      </ScrollView>     
    </TableLayout>
    

    【讨论】:

    【解决方案2】:

    我实际上想出了另一种不错的方法。

    只需在垂直方向的 LinearLayout 内以标题行作为第一行正常构建表格。接下来,以编程方式删除第一行,然后将其作为第一个子元素添加到 LinearLayout。这就像一个魅力。

    编辑:这也可以在不必指定静态列宽的情况下工作。

    【讨论】:

    • 我做了一个 ((ViewGroup)tableRow.getParent()).removeChild(tableRow);然后是linearLayout.addView(tableRow);虽然它删除了标题行,但它没有显示它,也没有保持列宽。我做了这个 onCreate()。也许它需要在另一个位置。
    • 我喜欢这个想法,但不幸的是,这对我来说根本不起作用。标题列总是只有最小宽度,并且没有与数据列对齐。本来就太好了……
    【解决方案3】:

    我知道这个问题很老,但它是第一个,因为我遇到了同样的问题,所以 Google 给了我。由于我认为我找到了更好的解决方案,因此我想分享它。

    想法:将 TableLayout(在 ScrollView 内)放入 RelativeLayout 并创建一个叠加层,将第一行(标题)绘制在其他所有内容上。

    这是 layout.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
    
        android:id="@+id/table_wrapper"
    
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    >
        <ScrollView
    
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
    
            tools:ignore="UselessParent"
        >
            <TableLayout
    
                android:id="@+id/table"
    
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
            />
        </ScrollView>
    </RelativeLayout>
    

    这里是代码:

    TableLayout table = (TableLayout)view.findViewById(R.id.table);
    
    final TableRow headerRow = new TableRow(context);
    table.addView(headerRow);
    
    table.addView(new TableRow(context));
    table.addView(new TableRow(context));
    table.addView(new TableRow(context));
    
    
    RelativeLayout tableWrapper = (RelativeLayout)view.findViewById(R.id.table_wrapper);
    
    View fakeHeaderView = new View(context) {
        @Override
        public void draw(Canvas canvas) {
            headerRow.draw(canvas);
        }
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
            int width = headerRow.getMeasuredWidth();
            int height = headerRow.getMeasuredHeight();
    
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
    
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    };
    
    tableWrapper.addView(fakeHeaderView);
    

    【讨论】:

    • 点赞!我不太明白这是如何工作的,但确实如此!非常优雅,确实:-)
    • 这种方法的问题是它会导致内存泄漏!在每次重绘时创建一个新的 fakeHeaderView 并将其添加到 tableWrapper (子列表会随着调试器的验证而增长和增长)。而且-正如我在试验时发现的那样-由于某种奇怪的原因,无法删除旧实例,否则添加的最后一个实例未正确绘制并且整个效果不起作用!有什么提示吗?
    【解决方案4】:
    <?xml version="1.0" encoding="utf-8"?>
    <TableLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent">
    
    
      <TableRow>
        <TextView android:text="Name"
            android:layout_width="100dp"        
            android:layout_column="0"
            android:layout_weight="1"/>
        <TextView android:text="Score"
            android:layout_width="30dp"
            android:layout_column="1"
            android:layout_weight="1">
        </TextView>
        <TextView android:text="Level"
            android:layout_width="30dp"
            android:layout_column="2"
            android:layout_weight="1">
        </TextView>
      </TableRow>
    
        <ScrollView android:layout_height="120dp">      
        <TableLayout android:id="@+id/score_table"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent">          
        <TableRow>
            <TextView android:text="Al"
            android:layout_width="100dp"        
            android:layout_column="0"
            android:layout_weight="1">
            </TextView>
            <TextView android:text="1000"
            android:layout_width="30dp"
            android:layout_column="1"
            android:layout_weight="1">
            </TextView>
            <TextView android:text="2"
            android:layout_width="30dp"
            android:layout_column="2"
            android:layout_weight="1">
            </TextView>
        </TableRow>
      </TableLayout>
      </ScrollView>     
    </TableLayout>
    

    【讨论】:

      【解决方案5】:

      对于那些不满意必须预先定义尺寸的人,我发现了一些对我有用的技巧。

      基本上,为标题制作一个单独的表格并将其放在主表格上,但顶部对齐方式相同,然后创建标题行的两个副本,在将一个添加到主表后,将另一个添加到标题表并将子视图的 layoutParams 设置为主表的行。

      这是我的基本示例。

      在你的布局中:

      <HorizontalScrollView
          android:id="@+id/table_horizontal_scroll_view"
          android:layout_alignParentTop="true"
          android:layout_width="wrap_content"
          android:layout_height="match_parent"
          android:clickable="false">
      
          <RelativeLayout
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              >
      
              <ScrollView
                  android:layout_alignParentTop="true"
                  android:layout_marginTop="0dp"
                  android:id="@+id/table_vertical_scroll_view"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content">
      
                  <TableLayout
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:id="@+id/grid_table_layout"
                      />
      
              </ScrollView>
      
              <TableLayout
                  android:layout_alignLeft="@+id/table_vertical_scroll_view"
                  android:layout_alignRight="@+id/table_vertical_scroll_view"
                  android:layout_alignStart="@+id/table_vertical_scroll_view"
                  android:layout_alignEnd="@+id/table_vertical_scroll_view"
                  android:layout_alignParentTop="true"
                  android:background="@color/grid_view_background"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:id="@+id/grid_floating_row_layout"
                  />
      
          </RelativeLayout>
      
      
      </HorizontalScrollView>
      

      然后当你添加你的行时:

          //clear out any views
          tableLayout.removeAllViews();
          floatingRowLayout.removeAllViews();
      
          TableRow[] rows = getTableContentRows() // content of your table
          TableRow[] titleRows = {getTitleRow(), getTitleRow()}; //two copies of your title row
          tableLayout.addView(titleRows[0]); // first add the first title to the main table
          addRows(rows) // add any other rows
      
          floatingRowLayout.addView(titleRows[1]); // floatingRowLayout is connected to id/grid_floating_row_layout
      
          titleRows[0].setVisibility(View.INVISIBLE); // make the title row added to the main table invisible
      
          // Set the layoutParams of the two title rows equal to each other. 
          // Since this is done after the first is added to the main table, they should be the correct sizes.
          for(int i = 0; i < titleRows[0].getChildCount(); i++) {
            titleRows[1].getChildAt(i).setLayoutParams(titleRows[0].getChildAt(i).getLayoutParams());
          }
      

      【讨论】:

        【解决方案6】:

        在ScrollView中使用两个tableLayout一个就像给android:stretchColumns="*"

           <RelativeLayout
                    android:layout_width="match_parent"
                    android:orientation="vertical"
                    android:paddingTop="5dp"
                    android:layout_height="match_parent"
                    android:layout_below="@+id/llSpinner">
                    <TableLayout
                        android:layout_width="match_parent"
                        android:id="@+id/tableHead"
        android:stretchColumns="*" 
                        android:layout_height="wrap_content">
                    </TableLayout>
        
                <ScrollView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_above="@+id/tableTotal"
                    android:layout_below="@+id/tableHead"
                    android:id="@+id/scrolltable">
        
        
                </ScrollView>
            <TableLayout
                        android:layout_width="match_parent"
                        android:id="@+id/tableTotal"
        android:stretchColumns="*" 
                        android:layout_alignParentBottom="true"
                        android:layout_height="wrap_content">
                    </TableLayout>
                </RelativeLayout>
        

        然后为 ROW 创建一个通用视图,最重要的是 android:layout_width="0dp"

        <TableRow
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="fill_parent"
            android:layout_height="?android:attr/listPreferredItemHeight"
            android:focusable="true"
            android:focusableInTouchMode="false"
            android:clickable="true"
            android:background="@android:drawable/list_selector_background">
        
            <TextView
                android:text="S.No"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:id="@+id/tbsNo"
                android:layout_weight="1"
                android:gravity="center"
                android:layout_column="1" />
        
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:text="Date"
                android:layout_weight="1"
                android:gravity="center"
                android:id="@+id/tbDate"
                android:layout_column="2" />
        
        
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:text="Count"
                android:layout_weight="1"
                android:gravity="center"
                android:id="@+id/tbMrCount"
                android:layout_column="3" />
        </TableRow>
        

        活动中

         Tablelayout tableHeading =(TableLayout)findViewById(R.id.tableHead);
        
        
                       Tablelayout    table =(TableLayout) findViewById(R.id.table_repots);
                           trHeading = (TableRow) getLayoutInflater().inflate(R.layout.table_row_item, null);
                        trHeading.setBackgroundColor(Color.parseColor("#6688AC"));
                        trHeading.setPadding(0,10,0,10);
        
                        TextView tv;
                        tv = (TextView) trHeading.findViewById(R.id.tbsNo);
                        tv.setText("S.No");
                    tv = (TextView) trHeading.findViewById(R.id.tbDate);
                   tv.setText("Date");
                  table.addView(tv);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多