2009-11-09 58 views
11

Được rồi, vì vậy tôi đã có Bảng này, và đầy đủ dữ liệu - với tất cả các hàng được thêm theo chương trình. Tôi đã có TableLayout bên trong của một HorizontalScrollView, mà lần lượt là bên trong một ScrollView - điều này cho phép tôi di chuyển cả hai chiều ngang và theo chiều dọc. Những gì tôi đang cố gắng làm bây giờ là thêm một hàng tiêu đề vào nó mà sẽ không cuộn. Tôi đã thử di chuyển mọi thứ xung quanh để cả hai chế độ xem cuộn của tôi thực sự nằm trong TableLayout và thêm các TableRows vào HorizontalScrollView; hy vọng của tôi là có thể sau đó thêm hàng tiêu đề bên ngoài chế độ xem cuộn.Android TableLayout Dòng tiêu đề

Điều duy nhất tôi có thể nghĩ là có bố cục bảng thứ hai chỉ dành cho hàng tiêu đề, nhưng việc đưa các cột lên hàng dường như sẽ khó khăn. Ý tưởng nào?

Trả lời

11

Một cách tiếp cận là nhúng một TableLayout trong hàng của TableLayout khác và đặt tiêu đề vào hàng trước như được thấy bên dưới. Căn chỉnh dữ liệu và tiêu đề yêu cầu thuộc tính layout_width của header Xem các đối tượng và các đối tượng View của dữ liệu được đặt thành các giá trị nhúng giống nhau. Ngoài ra, thuộc tính layout_weight của các đối tượng View của TableLayout bên trong phải khớp với tiêu đề tương ứng của nó. Bây giờ, trong XML dưới đây, tôi đã đặt 3 TextViews trong TableLayout bên trong trong một hàng duy nhất để phù hợp với các tiêu đề cột. Đây chỉ là để hiển thị cách căn chỉnh có thể được thực hiện. Bạn có thể điền dữ liệu đó theo cách lập trình bằng cách tăng bố cục và thêm nó vào thời gian chạy.

<?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> 
+0

thử này ans http://stackoverflow.com/questions/20241614/android-fixed-header-horizontal-and-vertical-scrolling-table/26211896#26211896 –

+0

Không hỗ trợ cho cuộn ngang –

13

Tôi thực sự đã tìm ra cách làm tốt hơn.

Đơn giản chỉ cần tạo bảng bình thường với hàng tiêu đề làm hàng đầu tiên, bên trong một LinearLayout định hướng thẳng đứng. Tiếp theo, lập trình loại bỏ hàng đầu tiên sau đó thêm nó làm con đầu tiên vào LinearLayout. Điều này làm việc như một say mê.

Chỉnh sửa: Tính năng này cũng hoạt động mà không phải chỉ định độ rộng cột tĩnh.

+0

Bí quyết tò mò, nhưng điều này thực sự hiệu quả. – Jonik

+0

bạn có thể mở rộng về điều này không? Có lẽ với một số mã? – SoloPilot

+0

Tôi đã làm một ((ViewGroup) tableRow.getParent()). RemoveChild (tableRow); sau đó linearLayout.addView (tableRow); và trong khi nó gỡ bỏ hàng tiêu đề nó không hiển thị nó và cũng không giữ chiều rộng cột. Tôi đã làm điều này onCreate(). Có lẽ nó cần phải ở một vị trí khác. – James

3

Tôi biết rằng câu hỏi cũ, nhưng đó là câu hỏi đầu tiên, mà Google đã cung cấp cho tôi vì tôi đã gặp phải vấn đề tương tự. Và kể từ khi tôi nghĩ rằng tôi đã tìm thấy một giải pháp tốt hơn, tôi muốn chia sẻ nó.

Ý tưởng: đặt TableLayout (bên trong ScrollView) vào RelativeLayout và tạo lớp phủ, sẽ vẽ hàng đầu tiên (tiêu đề) trên mọi thứ khác.

Đây là 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> 

Và đây là đoạn code:

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); 
+0

Thumbs up! Tôi không hoàn toàn hiểu CÁCH này hoạt động, nhưng nó! Rất thanh lịch, thực sự :-) – mmo

+0

Vấn đề với cách tiếp cận này là nó gây ra rò rỉ bộ nhớ! Một tạo và thêm một fakeHeaderView mới vào tableWrapper trên mỗi redraw (danh sách con phát triển và phát triển như một người có thể xác minh với trình gỡ rối). Và - khi tôi phát hiện ra thử nghiệm với điều này - vì một số lý do kỳ lạ, người ta không thể loại bỏ trường hợp cũ hoặc người nào khác người cuối cùng được thêm vào không được vẽ đúng cách và toàn bộ hiệu ứng không hoạt động! Bất kỳ gợi ý về điều đó? – mmo

0

Đối với những người không hài lòng với việc phải xác định trước kích cỡ của bạn, tôi tìm thấy một chút của một hack đang làm việc cho tôi.

Về cơ bản, tạo một bảng riêng biệt cho tiêu đề và đặt nó lên bảng chính của bạn, nhưng với cùng một căn chỉnh trên cùng, sau đó tạo hai bản sao của hàng tiêu đề và sau khi thêm một bản vào bảng chính, thêm phần kia vào bảng tiêu đề và đặt bố cục của chế độ xem conParams thành hàng tạo bảng chính.

Đây là ví dụ cơ bản của tôi.

trong cách bố trí của bạn:

<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> 

Sau đó, khi bạn thêm hàng của bạn:

//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()); 
    } 
0

Sử dụng Hai TableLayout Một trong scrollview thích cho 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> 

sau đó tạo ra một điểm chung cho ROW và đề cập đến quan trọng nhất là 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> 

Bây giờ trong Hoạt động

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); 
Các vấn đề liên quan