AdaptiveTableLayout

repository·master·Indexed 23 days ago

https://github.com/cleveroad/adaptivetablelayout

An Android library for reading, editing, and writing CSV files in a table format. It features fixed headers, solid row headers, and drag-and-drop reordering of rows and columns. The library includes AdaptiveTableLayout for the UI, LinkedAdaptiveTableAdapter for managing heavy data without mutation, and AdaptiveTableManager for handling row and column dimensions and coordinate mapping.

Tokens
2.8K
Snippets
3
Records
13
Agent score
83%

What's inside AdaptiveTableLayout

  1. How AdaptiveTableLayout components work together

    master

    The library is composed of three main parts that work in tandem to render and manage table data:

    1. AdaptiveTableLayout (View): The primary UI component used in your XML layouts or programmatically to display the table.
    2. LinkedAdaptiveTableAdapter (Adapter): The bridge between your data and the view. It manages how data is mapped to rows and columns.
    3. ViewHolderImpl (ViewHolder): Handles the individual cell representations and recycling logic.
  2. Choose the right Adapter type

    master

    The library provides different adapter strategies depending on your data size and mutability requirements:

    • BaseDataAdaptiveTableLayoutAdapter: A simple adapter for light data. Warning: Every time a row or column is switched, the original data is modified directly.
    • LinkedAdaptiveTableAdapter: Designed for heavy data. It does not change the original data. Instead, it maintains a matrix of modifications using links. To extract the final state of the data, you must call AdaptiveTableLayout.getLinkedAdapterRowsModifications() and AdaptiveTableLayout.getLinkedAdapterColumnsModifications().

    Important: For both adapter types, you must know all row/column widths, heights, and counts before setting the adapter to the AdaptiveTableLayout.

  3. Use LinkedAdaptiveTableAdapter to reorder rows and columns without data mutation

    master

    The LinkedAdaptiveTableAdapter acts as a decorator (wrapper) for an existing AdaptiveTableAdapter. It allows you to visually reorder rows and columns in the table layout without actually modifying the underlying data source. It maintains internal mapping (redirection) between the original data indices and the new visual indices.

    Key capabilities:

    • Reorder Rows/Columns: Use changeRows and changeColumns to swap positions.
    • Row Header Behavior: You can configure whether row headers are fixed to the specific row data or to the row number via the isSolidRowHeader parameter.
    • State Persistence: It implements onSaveInstanceState and onRestoreInstanceState to preserve reordering after configuration changes (like screen rotation).
  4. Coordinate mapping in AdaptiveTableManager

    master

    To determine which cell a user has interacted with based on touch coordinates, use the coordinate mapping methods. These methods automatically account for the header offsets (mHeaderRowWidth for X and mHeaderColumnHeight for Y).

    • getRowByY(int y): Use this to find the row index for a given Y coordinate.
    • getColumnByX(int x): Use this to find the column index for a given X coordinate.
    • getRowByYWithShift(int y, int shiftEveryStep): Use this if your layout involves a consistent shift (e.g., spacing or padding) between rows.
    • getColumnByXWithShift(int x, int shiftEveryStep): Use this if your layout involves a consistent shift between columns.
  5. How to use AdaptiveTableManager

    master

    The AdaptiveTableManager is used to manage the dimensions (heights and widths) of rows and columns in an adaptive table.

    Workflow:

    1. Create an instance of AdaptiveTableManager.
    2. Initialize it with the total number of rows and columns using init(int rowCount, int columnCount).
    3. Define dimensions for specific rows and columns using putRowHeight(int row, int height) and putColumnWidth(int column, int width).
    4. Call invalidate() to recalculate the total width and height of the table.

    Note: If the total number of rows, columns, or the overall table width changes, you must re-run the initialization steps (steps 2 through 4).

  6. Implement AdaptiveTableLayout in an Activity or Fragment

    master

    To use the library in your code, find the view, initialize your adapter (e.g., a LinkedAdaptiveTableAdapter), set listeners, and attach it to the layout.

    mTableLayout = (AdaptiveTableLayout) view.findViewById(R.id.tableLayout);
    ...
    mTableAdapter = new SampleLinkedTableAdapter(getContext(), mCsvFileDataSource);
    mTableAdapter.setOnItemClickListener(...);
    mTableAdapter.setOnItemLongClickListener(...);
    mTableLayout.setAdapter(mTableAdapter);
    ...
    mTableLayout.setHeaderFixed(true);
    mTableLayout.setSolidRowHeader(true);
    mTableAdapter.notifyDataSetChanged();
  7. Use AdaptiveTableLayout API methods

    master

    The AdaptiveTableLayout class provides several methods to control layout behavior and data updates programmatically:

    Header and Drag/Drop Configuration:

    • setHeaderFixed(boolean headerFixed): Enables or disables fixed headers mode.
    • setSolidRowHeader(boolean solidRowHeader): Enables or disables solid row headers mode.
    • setDragAndDrow(boolean enabled): Enables or disables drag and drop mode (Note: method name is setDragAndDrow).

    Data Management:

    • setAdapter(@Nullable AdaptiveTableAdapter adapter): Sets an adapter with IMMUTABLE data. Use this for heavy data; it uses links to track changes without modifying the original source. To retrieve changes, use getLinkedAdapterRowsModifications() and getLinkedAdapterColumnsModifications().
    • setAdapter(@Nullable DataAdaptiveTableLayoutAdapter adapter): Sets an adapter with MUTABLE data. Use this for light data. Warning: On each row/column switch, the original data will be changed. Do not use with large datasets.

    Notification Methods:

    • notifyDataSetChanged(): Notifies observers that the entire data set has changed.
    • notifyItemChanged(int rowIndex, int columnIndex): Notifies observers that a specific cell has changed.
    • notifyRowChanged(int rowIndex): Notifies observers that a specific row has changed.
    • notifyColumnChanged(int columnIndex): Notifies observers that a specific column has changed.
  8. Configure AdaptiveTableLayout in XML

    master

    You can define the table layout in your XML files using the com.cleveroad.adaptivetablelayout.AdaptiveTableLayout tag. Use the following attributes to control the table behavior:

    • app:cellMargin: The margin between cells (e.g., 1dp).
    • app:fixedHeaders: If true, headers will always be displayed in the corners.
    • app:solidRowHeaders: If true, the row header will change its position when dragging a row.
    • app:dragAndDropEnabled: If true, users can change column or row positions by long-pressing a header.
    <com.cleveroad.adaptivetablelayout.AdaptiveTableLayout
            android:id="@+id/tableLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"      
            app:cellMargin="1dp"
            app:fixedHeaders="true"
            app:solidRowHeaders="true"
            app:dragAndDropEnabled="true"/>
  9. Configure AdaptiveTableLayoutSettings

    master

    Use AdaptiveTableLayoutSettings to customize the appearance and behavior of the table layout. The class uses a builder-like pattern for most configuration methods, allowing you to chain calls to set dimensions, margins, and interaction modes.

    Available configuration options:

    • setLayoutWidth(int): Sets the layout width.
    • setLayoutHeight(int): Sets the layout height.
    • setHeaderFixed(boolean): If true, the header remains fixed during scrolling.
    • setCellMargin(int): Sets the margin between cells.
    • setSolidRowHeader(boolean):
      • If true: The row header is fixed to the data (the value of the row header is tied to the data).
      • If false: The row header is fixed to the row number (fixed to the index from 0 to n).
    • setDragAndDropEnabled(boolean): If true, enables editing via drag and drop; otherwise, editing is disabled.
  10. Manage table dimensions with AdaptiveTableManager

    master

    The AdaptiveTableManager class provides methods to set, get, and manipulate the dimensions of a table grid.

    Initialization and Reset

    • init(int rowCount, int columnCount): Initializes the internal arrays for rows and columns with the specified counts.
    • clear(): Resets all dimensions, counts, and header settings.

    Setting Dimensions

    • putRowHeight(int row, int height): Sets the height for a specific row index.
    • putColumnWidth(int column, int width): Sets the width for a specific column index.
    • setHeaderColumnHeight(int headerColumnHeight): Sets the height of the column header.
    • setHeaderRowWidth(int headerRowWidth): Sets the width of the row header.

    Retrieving Dimensions

    • getRowHeight(int row): Returns the height of the specified row.
    • getColumnWidth(int column): Returns the width of the specified column.
    • getRowsHeight(int from, int to): Returns the sum of heights from the from index (inclusive) to the to index (exclusive).
    • getColumnsWidth(int from, int to): Returns the sum of widths from the from index (inclusive) to the to index (exclusive).
    • getFullWidth(): Returns the total width of the table, including the row header width.
    • getFullHeight(): Returns the total height of the table, including the column header height.
    • getRowCount(): Returns the total number of rows.
    • getColumnCount(): Returns the total number of columns.

    Coordinate Mapping

    • getRowByY(int y): Returns the row index that contains the vertical coordinate y.
    • getColumnByX(int x): Returns the column index that contains the horizontal coordinate x.
    • getRowByYWithShift(int y, int shiftEveryStep): Returns the row index for coordinate y, accounting for a constant shift between steps.
    • getColumnByXWithShift(int x, int shiftEveryStep): Returns the column index for coordinate x, accounting for a constant shift between steps.

    Manipulating Order

    • switchTwoRows(int rowIndex, int rowToIndex): Swaps the heights of two rows.
    • switchTwoColumns(int columnIndex, int columnToIndex): Swaps the widths of two columns.
  11. Reorder rows and columns with LinkedAdaptiveTableAdapter

    master

    To change the visual order of rows or columns, use the following methods on your LinkedAdaptiveTableAdapter instance:

    • changeColumns(int columnIndex, int columnToIndex): Swaps the visual position of a column.
    • changeRows(int rowIndex, int rowToIndex, boolean solidRowHeader): Swaps the visual position of a row and allows you to set whether the row header is fixed to the data or the row number.

    Note: The implementation internally handles the mapping so that your underlying data remains untouched.