AndroidでWindowsのGridVew的な表示を行うには

Androidで、WindowsのGridVew的な表示(HTMLでいうTable)を行う方法が、他記事にあまり見られなかったのでレポートします。他に良い方法があるのかもしれません …

  • TableLayoutTableRow、TextView を使う。
  • データ部はプログラムコードにて生成する。
  • ヘッダ部とデータ部で列幅は合せてくれない。
  • ヘッダ部の列幅の取得はうまくいかないため、データ部列幅は現物合せするしかない。
  • スクロールするには、ヘッダ用とデータ部用で TableLayout を分け、データ部用をScrollViewに載せる。
  • 格子線の描画はうまく行かなかった。res/drawable/*.xml に android:width=”1dp” を記述しても Table全体の外枠しか描画されず。


図にすると以下のように構成します。

xmlの記述例は、

		<!-- データ部。高さはmatch_parentとする -->
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:orientation="vertical" >

		    <!-- 表題 -->
        <TextView
            android:id="@+id/editTextTextPersonName"
            android:layout_width="match_parent"
            android:layout_height="32dp"
            android:layout_marginTop="1dp"
            android:gravity="center"
            android:text="CAN Frames View"
            android:textSize="20sp"
            android:visibility="visible"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="1.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

 		    <!-- ヘッダ部。高さを固定にする -->
        <TableLayout
            android:id="@+id/tblCANFramesHead"
            android:layout_width="match_parent"
            android:layout_height="35dp"
            android:layout_marginStart="1dp"
            android:layout_marginEnd="1dp"
            android:layout_marginBottom="1dp"
            android:gravity="top|left"
            android:padding="5dip"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent">

        	<TableRow android:id="@+id/viewHeader">
            	<TextView
                	android:layout_weight="2"
                	android:gravity="center_horizontal|center_vertical"
                	android:padding="1dip"
                	android:text="ID" />
            	<TextView
                	android:layout_weight="4"
                	android:gravity="center_horizontal|center_vertical"
                	android:padding="1dip"
                	android:text="TIME" />
                	
             ・・・中略・・・
             
        	</TableRow>
        </TableLayout>

  		  <!-- データ部。高さはmatch_parentとする -->
        <ScrollView
            android:id="@+id/srcView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginStart="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            android:layout_marginBottom="76dp"
            android:scrollbars="vertical"
            app:layout_constraintBottom_toTopOf="@+id/tblCANFrames"
            app:layout_constraintEnd_toEndOf="@+id/tblCANFrames"
            app:layout_constraintHorizontal_bias="1.0">

            <TableLayout
                android:id="@+id/tblCANFrames"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginStart="1dp"
                android:layout_marginEnd="1dp"
                android:layout_marginBottom="1dp"
                android:gravity="top|left"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent">

                <!-- ダミーData部 無いとコケる -->
                <TableRow android:id="@+id/viewData" >
                    <TextView
                        android:layout_weight="2"
                        android:gravity="center_horizontal|center_vertical"
                        android:padding="1dip" />
                    <TextView
                        android:layout_weight="4"
                        android:gravity="center_horizontal|center_vertical"
                        android:padding="1dip" />
                        
                    ・・・中略・・・
                    
                  </TableRow>
            </TableLayout>
        </ScrollView>
    </LinearLayout>


セル一つづつ生成していきます。ダミーデータ行は最後に削除します。以下コードです。

       TableLayout frameTbl = this.findViewById(R.id.tblCANFrames);

        for (int i = 1; i <= 64 ; i++) {
            TableRow tblRow = new TableRow(this);

            // CAN-ID
            TextView viewId = new TextView(this);
            viewId.setText("000");
            tblRow.addView(viewId, 0);

            ・・・中略・・・

            // DATA
            for (int j = 0, k = 3; j < CAN_DATA_BYTE_NUM; j ++, k ++) {
                TextView viewDat = new TextView(this);
                viewDat.setText("00");
                tblRow.addView(viewDat, k);
            }

            frameTbl.addView(tblRow, i );     // 行追加、Heightき変更不要
        }

        // ダミーデータを削除。
        // ※removeAllするとコケる。TableRow無しのTableLayoutをつくるとコケる。
        frameTbl.removeViewAt(0);


列幅は setPadding で以下のように調整します。

       // CAN-ID
       TextView viewId = new TextView(this);
       viewId.setText("000");
       viewId.setPadding(5,0,5,0); // <- 列幅調整
       tblRow.addView(viewId, 0);

Wordwrapが効いて複数行になってしまう列は、行数を強制します。

      // 受信TIME
      TextView viewTim = new TextView(this);
      viewTim.setText("00000000");
      viewTim.setLines(1);    // <- 1行に強制する
      viewTim.setBackgroundColor( bgclr[i%2] );
      tblRow.addView(viewTim, 1);

格子線描画はうまく行かないため、代わりに見易くするため1行毎に色替えします。

     // 一行を見やすくするため交互に色替え。
     int[] bgclr = new int[2];
     bgclr[0] = Color.rgb(0xFF,0xFF, 0x88);
     bgclr[1] = Color.rgb(0x88,0xFF, 0xFF);
        
     for (int i = 1; i <= CAN_FRAME_MAX_NUM ; i++) {
          TableRow tblRow = new TableRow(this);
          // CAN-ID
          TextView viewId = new TextView(this);
          viewId.setText("000");
          viewId.setPadding(5,0,5,0);
          viewId.setBackgroundColor( bgclr[i%2] ); // <-- 1行毎に色替え
          tblRow.addView(viewId, 0);
          
          ・・・後略・・・


レイアウトのみの実行結果です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です