BETA

TableView for Android 使い方

投稿日:2018-10-16
最終更新:2019-06-18

ライブラリのgithub

https://github.com/evrencoskun/TableView

初期設定

ライブラリ追加

build.gradle(Module: app)に以下を追加

dependencies {
    implementation 'com.evrencoskun.library:tableview:0.8.8'
}

追加した後、Syncすると、'com.android.support:appcompat-v7:27.1.1'あたりにエラーが発生する。必要なライブラリが足りていない?以下を追加してSyncすることで解決。

dependencies {
    implementation 'com.android.support:animated-vector-drawable:27.1.1'
    implementation 'com.android.support:recyclerview-v7:27.1.1'
}

必要なXML追加

ここの部分が抜け落ちているせいで全くわからない状態になっていた。サンプルがここにあるのでこれを参考にしながら作成していく。

カラーファイル

「app/res/values/colors.xml」を編集。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#15a4fa</color>

    <!-- 追加ここから -->
    <color name="selected_background_color">#15a4fa</color>
    <color name="unselected_background_color">#1c324a</color>
    <color name="shadow_background_color">#28415f</color>
    <color name="unselected_header_background_color">#1f3650</color>

    <color name="unselected_text_color">#537095</color>
    <color name="selected_text_color">#ffffff</color>
    <color name="separator_color">#273e5b</color>

    <color name="popup_menu_item_text_color">#88a5c9</color>

    <color name="female_icon_color">#e9515f</color>
    <color name="male_icon_color">#f28944</color>
    <!-- 追加ここまで -->
</resources>

パラメータファイル

「app/res/values/tableview.xml」を新規作成。ディレクトリ構成があっていればファイル名は自由。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="table_view_cell_height">28dp</dimen>
    <dimen name="table_view_row_header_width">28dp</dimen>
    <dimen name="table_view_default_text_size">11sp</dimen>
</resources>

セルレイアウト

「app/res/layout/tableview_cell_layout.xml」を新規作成。ディレクトリ構成があっていればOK。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        android:id="@+id/cell_container"
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="wrap_content"
        android:layout_height="@dimen/table_view_cell_height"
        android:background="@color/unselected_background_color"
        android:orientation="vertical">


    <TextView
            android:id="@+id/cell_data"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center_vertical"
            android:layout_marginStart="10dp"
            android:layout_marginEnd="10dp"
            android:gravity="center"
            android:maxLines="1"
            android:textColor="@color/unselected_text_color"
            android:textSize="@dimen/table_view_default_text_size"
            tools:text="Cell Data"/>
</LinearLayout>

Row Header レイアウト

「app/res/layout/tableview_row_header_layout.xml」を新規作成。ディレクトリ構成があっていればOK。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/root"
                xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="@dimen/table_view_row_header_width"
                android:layout_height="@dimen/table_view_cell_height"
                android:background="@color/unselected_header_background_color">

    <LinearLayout
        android:id="@+id/row_header_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:orientation="vertical">

        <TextView
            android:id="@+id/row_header_textview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:gravity="center"
            android:maxLines="1"
            android:textColor="@color/unselected_text_color"
            android:textSize="@dimen/table_view_default_text_size"
            tools:text="Row Data"/>

    </LinearLayout>

    <View
        android:layout_width="1px"
        android:layout_height="match_parent"
        android:layout_alignParentRight="true"
        android:background="@color/separator_color"/>
</RelativeLayout>

Column Header ソートアイコン

「app/res/drawable/ic_down.xml」を新規作成。


<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportHeight="512.0"
        android:viewportWidth="512.0">
    <path
        android:fillColor="@color/unselected_text_color"
        android:pathData="M396.6,160l19.4,20.7l-160,171.3l-160,-171.3l19.3,-20.7l140.7,150.5z"/>
</vector>

Column Header レイアウト

「app/res/layout/tableview_column_header_layout.xml」を新規作成。ディレクトリ構成があっていればOK。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        android:id="@+id/column_header_container"
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="wrap_content"
        android:layout_height="@dimen/table_view_cell_height"
        android:background="@color/unselected_header_background_color"
        android:orientation="vertical">

    <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal">

        <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="center"
                android:layout_marginEnd="10dp"
                android:layout_marginStart="10dp"
                android:orientation="horizontal">

            <TextView
                    android:id="@+id/column_header_textView"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_gravity="center"
                    android:layout_weight="4"
                    android:gravity="center"
                    android:textColor="@color/unselected_text_color"
                    android:textSize="@dimen/table_view_default_text_size"
                    tools:text="Header Data"/>

            <ImageButton
                    android:id="@+id/column_header_sort_imageButton"
                    android:layout_width="15dp"
                    android:layout_height="15dp"
                    android:layout_gravity="end|center"
                    android:layout_marginLeft="4dp"
                    android:background="@android:color/transparent"
                    android:paddingRight="-5dp"
                    android:scaleType="fitXY"
                    android:visibility="gone"
                    app:srcCompat="@drawable/ic_down"/>
        </LinearLayout>

        <View
                android:layout_width="match_parent"
                android:layout_height="1px"
                android:layout_gravity="bottom"
                android:background="@color/separator_color"/>
    </FrameLayout>
</LinearLayout>

Corner レイアウト

表左上の部分。「app/res/layout/tableview_corner_layout.xml」を新規作成。ディレクトリ構成があっていればOK。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="@dimen/table_view_row_header_width"
                android:layout_height="@dimen/table_view_cell_height"
                android:background="@color/unselected_header_background_color">

    <View
            android:layout_width="1px"
            android:layout_height="match_parent"
            android:layout_alignParentRight="true"
            android:background="@color/separator_color"/>

    <View
            android:layout_width="match_parent"
            android:layout_height="1px"
            android:layout_alignParentBottom="true"
            android:background="@color/separator_color"/>
</RelativeLayout>

データクラス作成

「RowHeader」「ColumnHeader」「Cell」に関して、それぞれ専用のクラスを用意する。

RowHeader

package com.practice.maccyo.tableviewpractice.tableview

data class RowHeaderModel(val mData: String)

ColumnHeader

package com.practice.maccyo.tableviewpractice.tableview

data class ColumnHeaderModel(val mData: String)

※上記2つは共通でも良さそう。

Cell

package com.practice.maccyo.tableviewpractice.tableview

import com.evrencoskun.tableview.sort.ISortableModel

class CellModel(pId: String, private val mData: String) : ISortableModel{
    private val mId: String = pId

    fun getData(): String{
        return mData
    }

    override fun getContent(): Any {
        return mData
    }

    override fun getId(): String {
        return mId
    }
}

テーブルアダプター作成

基本的にはチュートリアルと同じだが、一部情報がtypoしていると思われる。

package com.practice.maccyo.tableviewpractice.tableview

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import com.evrencoskun.tableview.adapter.AbstractTableAdapter
import com.evrencoskun.tableview.adapter.recyclerview.holder.AbstractViewHolder
import com.practice.maccyo.tableviewpractice.R

class TableViewAdapter(val context: Context) : AbstractTableAdapter<ColumnHeaderModel, RowHeaderModel, CellModel>(context){
    // Cell関連
    class CellViewHolder(itemView: View) : AbstractViewHolder(itemView){
        val cell = itemView.findViewById<TextView>(R.id.cell_data)
    }

    override fun onCreateCellViewHolder(parent: ViewGroup?, viewType: Int): AbstractViewHolder {
        val layout = LayoutInflater.from(context).inflate(R.layout.tableview_cell_layout, parent, false )
        return CellViewHolder(layout)
    }

    override fun onBindCellViewHolder(
        holder: AbstractViewHolder?,
        cellItemModel: Any?,
        columnPosition: Int,
        rowPosition: Int
    ) {
        val cell = cellItemModel as CellModel
        val viewHolder = holder as CellViewHolder
        viewHolder.cell.text = cell.getData()

        viewHolder.itemView.layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT
        viewHolder.cell.requestLayout()
    }

    // ColumnHeader関連
    class ColumnHeaderViewHolder(itemView: View) : AbstractViewHolder(itemView){
        // チュートリアルと異なる
        val columnHeader = itemView.findViewById<TextView>(R.id.column_header_textView)
    }

    override fun onCreateColumnHeaderViewHolder(parent: ViewGroup?, viewType: Int): AbstractViewHolder {
        val layout = LayoutInflater.from(context).inflate(R.layout.tableview_column_header_layout,parent,false)
        return ColumnHeaderViewHolder(layout)
    }

    override fun onBindColumnHeaderViewHolder(
        holder: AbstractViewHolder?,
        columnHeaderItemModel: Any?,
        columnPosition: Int
    ) {
        val colHeader = columnHeaderItemModel as ColumnHeaderModel
        val colViewHolder = holder as ColumnHeaderViewHolder
        colViewHolder.columnHeader.text = colHeader.mData

        colViewHolder.itemView.layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT
        colViewHolder.itemView.requestLayout()
    }

    // RowHeader関連
    class RowHeaderViewHolder(itemView: View) : AbstractViewHolder(itemView){
        val rowHeader = itemView.findViewById<TextView>(R.id.row_header_textview)
    }

    override fun onCreateRowHeaderViewHolder(parent: ViewGroup?, viewType: Int): AbstractViewHolder {
        val layout = LayoutInflater.from(context).inflate(R.layout.tableview_row_header_layout,parent,false)
        return RowHeaderViewHolder(layout)
    }

    override fun onBindRowHeaderViewHolder(holder: AbstractViewHolder?, rowHeaderItemModel: Any?, rowPosition: Int) {
        val rowHeader = rowHeaderItemModel as RowHeaderModel
        val rowViewHolder = holder as RowHeaderViewHolder
        rowViewHolder.rowHeader.text = rowHeader.mData
    }

    override fun onCreateCornerView(): View {
        return LayoutInflater.from(context).inflate(R.layout.tableview_corner_layout, null)
    }

    override fun getColumnHeaderItemViewType(position: Int): Int {
        return 0
    }

    override fun getRowHeaderItemViewType(position: Int): Int {
        return 0
    }

    override fun getCellItemViewType(position: Int): Int {
        return 0
    }
}

これで準備完了。

使い方

  1. 使いたい部分に以下のXMLを差し込む。

     <com.evrencoskun.tableview.TableView
             android:id="@+id/content_container"
             android:layout_width="match_parent"
             android:layout_height="0dp"
    
             app:column_header_height="@dimen/table_view_cell_height"
             app:row_header_width="@dimen/table_view_row_header_width"
             app:selected_color="@color/selected_background_color"
             app:shadow_color="@color/shadow_background_color"
             app:unselected_color="@color/unselected_background_color" />
  2. Kotlinで必要な情報の配列を用意する。

    val colValues: List<ColumnHeaderModel>
    val rowValues: List<RowHeaderModel>
    val cellValues: List<List<CellModel>>
    // cellはジャグ配列
  3. バインド

例としてActivityでバインドする場合

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // テスト用データ作成
        val colValues = mutableListOf<ColumnHeaderModel>()
        colValues.add(ColumnHeaderModel("Col - 1"))
        colValues.add(ColumnHeaderModel("Col - 2"))
        colValues.add(ColumnHeaderModel("Col - 3"))

        val rowValues = mutableListOf<RowHeaderModel>()
        rowValues.add(RowHeaderModel("Row - 1"))
        rowValues.add(RowHeaderModel("Row - 2"))
        rowValues.add(RowHeaderModel("Row - 3"))

        val cellValues = mutableListOf<MutableList<CellModel>>()
        for (xIndex in 1..3) {
            val addCache = mutableListOf<CellModel>()
            for (yIndex in 1..3) {
                addCache.add(CellModel("$xIndex$yIndex", "$xIndex - $yIndex"))
            }
            cellValues.add(addCache)
        }

        // バインド用の変数用意
        val tableView = content_container
        val adapter = TableViewAdapter(this)

        // バインド
        tableView.adapter = adapter
        // 値の割当
        adapter.setAllItems(colValues, rowValues, cellValues)
    }

これで表示される。

課題

  • RowHeaderのWidthとColumnHeaderのHeightが固定になっている。特にRowHeader-Widthは内容によって自動的に調整する機能は無いのか。
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@maccyoの技術ブログ(予定) C#/VB.NET/Kotlin/Delphi

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう