An Android library containing a simple TableView and an advanced SortableTableView providing a lot of customisation possibilities to fit all needs.

Overview

Android Arsenal API Build Status

SortableTableView for Android

An Android library providing a TableView and a SortableTableView.

SortableTableView Example

Minimum SDK-Version: 11 |  Compile SDK-Version: 25 |  Latest Library Version: 2.8.0  

New version available! Check version 3.1.0 of the pro version.

Repository Content

tableview - contains the android library sources and resources
app - contains an example application showing how to use the SortableTableView

Example App

Setup

To use the this library in your project simply add the following dependency to your build.gradle file.

    dependencies {
        ...
        compile 'de.codecrafters.tableview:tableview:2.8.0'
        ...
    }

Pro Version

If you want to have the best TableView experience, we offer you the possibility to get the pro version of the SortableTableView. This is what the pro version offers you:

Open-Source Version Pro Version
render simple data
render custom data
header styling
data row styling
data sorting
data loading
searching
paging
selection
view recycling
support
maintenance
quick start guide
full documentation

To get more information visit the SortableTableView-Page.

Features

Layouting

Column Count

The provided TableView is very easy to adapt to your needs. To set the column count simple set the parameter inside your XML layout.

<de.codecrafters.tableview.TableView
    xmlns:table="http://schemas.android.com/apk/res-auto"
    android:id="@+id/tableView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    table:tableView_columnCount="4" />

A second possibility to define the column count of your TableView is to set it directly in the code.

TableView tableView = (TableView) findViewById(R.id.tableView);
tableView.setColumnCount(4);

Column Width

To define the column widths you can set a TableColumnModel that defines the width for each column. You can use a predefined TableColumnModel or implement your custom one.

TableColumnWeightModel
This model defines the column widths in a relative manner. You can define a weight for each column index. The default column weight is 1.

TableColumnWeightModel columnModel = new TableColumnWeightModel(4);
columnModel.setColumnWeight(1, 2);
columnModel.setColumnWeight(2, 2);
tableView.setColumnModel(columnModel);

TableColumnDpWidthModel
This model defines the column widths in a absolute manner. You can define a width in density-independent pixels for each column index. The default column width is 100dp. You can pass a different default to the constructor.

TableColumnDpWidthModel columnModel = new TableColumnDpWidthModel(context, 4, 200);
columnModel.setColumnWidth(1, 300);
columnModel.setColumnWidth(2, 250);
tableView.setColumnModel(columnModel);

TableColumnPxWidthModel
This model defines the column widths in a absolute manner. You can define a width in pixels for each column index. The default column width is 200px. You can pass a different default to the constructor.

TableColumnPxWidthModel columnModel = new TableColumnPxWidthModel(4, 350);
columnModel.setColumnWidth(1, 500);
columnModel.setColumnWidth(2, 600);
tableView.setColumnModel(columnModel);

Showing Data

Simple Data

For displaying simple data like a 2D-String-Array you can use the SimpleTableDataAdapter. The SimpleTableDataAdapter will turn the given Strings to TextViews and display them inside the TableView at the same position as previous in the 2D-String-Array.

public class MainActivity extends AppCompatActivity {
    
    private static final String[][] DATA_TO_SHOW = { { "This", "is", "a", "test" }, 
                                                     { "and", "a", "second", "test" } };
        
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TableView<String[]> tableView = (TableView<String[]>) findViewById(R.id.tableView);
        tableView.setDataAdapter(new SimpleTableDataAdapter(this, DATA_TO_SHOW));
    }
}        

Custom Data

For displaying more complex custom data you need to implement your own TableDataAdapter. Therefore you need to implement the getCellView(int rowIndex, int columnIndex, ViewGroup parentView) method. This method is called for every table cell and needs to returned the View that shall be displayed in the cell with the given rowIndex and columnIndex. Here is an example of an TableDataAdapter for a Car object.

public class CarTableDataAdapter extends TableDataAdapter<Car> {

    public CarTableDataAdapter(Context context, List<Car> data) {
        super(context, data);
    }

    @Override
    public View getCellView(int rowIndex, int columnIndex, ViewGroup parentView) {
        Car car = getRowData(rowIndex);
        View renderedView = null;

        switch (columnIndex) {
            case 0:
                renderedView = renderProducerLogo(car);
                break;
            case 1:
                renderedView = renderCatName(car);
                break;
            case 2:
                renderedView = renderPower(car);
                break;
            case 3:
                renderedView = renderPrice(car);
                break;
        }

        return renderedView;
    }
    
}

The TableDataAdapter provides several easy access methods you need to render your cell views like:

  • getRowData()
  • getContext()
  • getLayoutInflater()
  • getResources()

Sortable Data

If you need to make your data sortable, you should use the SortableTableView instead of the ordinary TableView. To make a table sortable by a column, all you need to do is to implement a Comparator and set it to the specific column.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // ...
    sortableTableView.setColumnComparator(0, new CarProducerComparator());
}

private static class CarProducerComparator implements Comparator<Car> {
    @Override
    public int compare(Car car1, Car car2) {
        return car1.getProducer().getName().compareTo(car2.getProducer().getName());
    }
}

By doing so the SortableTableView will automatically display a sortable indicator next to the table header of the column with the index 0. By clicking this table header, the table is sorted ascending with the given Comparator. If the table header is clicked again, it will be sorted in descending order.

Empty Data Indicator

If you want to show a certain view if there is no data available in the table, you can use the setEmptyDataIndicatorView method. Therefore you first have to add this view to your layout (preferable with visibility gone) and then pass it to the TableView.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // ...
    tableView.setEmptyDataIndicatorView(findViewById(R.id.empty_data_indicator));
}

This view is automatically shown if no data is available and hidden if there is some data to show.

Header Data

Setting data to the header views is identical to setting data to the table cells. All you need to do is extending the TableHeaderAdapter which is also providing the easy access methods that are described for the TableDataAdapter.
If all you want to display in the header is the column title as String (like in most cases) the SimpleTableHeaderAdapter will fulfil your needs. To show simple Strings inside your table header, use the following code:

public class MainActivity extends AppCompatActivity {
    
    private static final String[] TABLE_HEADERS = { "This", "is", "a", "test" };
        
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // ...
        tableView.setHeaderAdapter(new SimpleTableHeaderAdapter(this, TABLE_HEADERS));
    }
}  

To show Strings from resources inside your table header, use the following code:

public class MainActivity extends AppCompatActivity {
    
    private static final int[] TABLE_HEADERS = { R.string.header_col1, R.string.header_col2, R.string.header_col3 };
        
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // ...
        tableView.setHeaderAdapter(new SimpleTableHeaderAdapter(this, TABLE_HEADERS));
    }
}  

Interaction Listening

Data Click Listening

To listen for clicks on data items you can register a TableDataClickListener. TheTableView provides a method called addDataClickListener() to register this listeners.

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
    // ...
    tableView.addDataClickListener(new CarClickListener());
}

private class CarClickListener implements TableDataClickListener<Car> {
    @Override
    public void onDataClicked(int rowIndex, Car clickedCar) {
        String clickedCarString = clickedCar.getProducer().getName() + " " + clickedCar.getName();
        Toast.makeText(getContext(), clickedCarString, Toast.LENGTH_SHORT).show();
    }
}

Long Data Click Listening

To listen for clicks on data items you can register a TableDataLongClickListener. TheTableView provides a method called addDataLongClickListener() to register this columns.

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
    // ...
    tableView.addDataLongClickListener(new CarLongClickListener());
}

private class CarLongClickListener implements TableDataLongClickListener<Car> {
    @Override
    public boolean onDataLongClicked(int rowIndex, Car clickedCar) {
        String clickedCarString = clickedCar.getProducer().getName() + " " + clickedCar.getName();
        Toast.makeText(getContext(), clickedCarString, Toast.LENGTH_SHORT).show();
        return true;
    }
}

The main difference to the TableDataClickListener#onDataClicked() method is, that the onDataLongClicked() method has a boolean as return value. This boolean indicates, if the TableDataLongClickListener has "consumed" the click event. If none of the registered TableDataLongClickListeners has consumed the click event, the TableDataClickListeners are informed in addition.

Header Click Listening

To listen for clicks on headers you can register a TableHeaderClickListner. The TableView provides a method called addHeaderClickListener() to do so.

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
    // ...
    tableView.addHeaderClickListener(new MyHeaderClickListener());
}

private class MyHeaderClickListener implements TableHeaderClickListener {
    @Override
    public void onHeaderClicked(int columnIndex) {
        String notifyText = "clicked column " + (columnIndex+1);
        Toast.makeText(getContext(), notifyText, Toast.LENGTH_SHORT).show();
    }
}

On Scroll Listening

To listen for scroll or scroll state changes you can register a OnScrollListener. The TableView provides a method called addOnScrollListener() to do so.

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
    // ...
    tableView.addOnScrollListener(new MyOnScrollListener());
}

private class MyOnScrollListener implements OnScrollListener {
    @Override
    public void onScroll(final ListView tableDataView, final int firstVisibleItem, final int visibleItemCount, final int totalItemCount) {
        // listen for scroll changes
    }
        
    @Override
    public void onScrollStateChanged(final ListView tableDateView, final ScrollState scrollState) {
        // listen for scroll state changes
    }
}

In addition this library provides an EndlessOnScrollListener which allows the loading of further data when the user scrolls to the end of the table. Therefore you can give an row threshold which defines when the data shall be reloaded. A threshold of 3 would mean, that the loading shall be triggered when the user reaches the 3rd last row. The default threshold is 5.

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
    // ...
    tableView.addOnScrollListener(new MyEndlessOnScrollListener());
}

private class MyEndlessOnScrollListener extends EndlessOnScrollListener {
    
    @Override
    public void onReloadingTriggered(final int firstRowItem, final int visibleRowCount, final int totalRowCount) {
        // show a loading view to the user
        // reload some data
        // add the loaded data to the adapter
        // hide the loading view
    }
}

Styling

Header Styling

The table view provides several possibilities to style its header. One possibility is to set a color for the header. Therefore you can adapt the XML file or add it to your code.

<de.codecrafters.tableview.TableView
    xmlns:table="http://schemas.android.com/apk/res-auto"
    android:id="@+id/tableView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    table:tableView_headerColor="@color/primary" />
tableView.setHeaderBackgroundColor(getResources().getColor(R.color.primary));

For more complex header styles you can also set a drawable as header background using the following method.

tableView.setHeaderBackground(R.drawable.linear_gradient);

In addition you can set an elevation of the table header. To achieve this you have the possibility to set the elevation in XML or alternatively set it in your code.

<de.codecrafters.tableview.TableView
    xmlns:table="http://schemas.android.com/apk/res-auto"
    android:id="@+id/tableView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    table:tableView_headerElevation="10" />
tableView.setHeaderElevation(10);

NOTE: This elevation is realized with the app-compat version of elevation. So it is also applicable on pre-lollipop devices

For SortableTableViews it is also possible to replace the default sortable indicator icons by your custom ones. To do so you need to implement the SortStateViewProvider and set it to your SortableTableView.

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
    // ...
    sortableTableView.setHeaderSortStateViewProvider(new MySortStateViewProvider());
}

private static class MySortStateViewProvider implements SortStateViewProvider {

    private static final int NO_IMAGE_RES = -1;

    @Override
    public int getSortStateViewResource(SortState state) {
        switch (state) {
            case SORTABLE:
                return R.mipmap.ic_sortable;
            case SORTED_ASC:
                return R.mipmap.ic_sorted_asc;
            case SORTED_DESC:
                return R.mipmap.ic_sorted_desc;
            default:
                return NO_IMAGE_RES;
        }
    }
}

There is also a factory class existing called SortStateViewProviders where you can get some predefined implementations of the SortStateViewProvider.

Data Row Styling

In general you can do all your styling of data content in your custom TableDataAdapter. But if you want to add a background for the whole table rows you can use the TableDataRowBackgroundProvider. There are already some implementations of the TableDataRowBackgroundProvider existing in the library. You can get them by using the Factory class TableDataRowBackgroundProviders.
This Factory contains for example an alternating-table-data-row-row provider that will color rows with even index different from rows with odd index.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // ...
    int colorEvenRows = getResources().getColor(R.color.white);
    int colorOddRows = getResources().getColor(R.color.gray);
    tableView.setDataRowBackgroundProvider(TableDataRowBackgroundProviders.alternatingRowColors(colorEvenRows, colorOddRows));
}

If the implementations of TableDataRowBackgroundProvider contained in the TableDataRowBackgroundProviders factory don't fulfil you needs you can create your own implementation of TableDataRowBackgroundProvider. Here is a small example of how to do so.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // ...
    tableView.setDataRowBackgroundProvider(new CarPriceRowColorProvider());
}
    
private static class CarPriceRowColorProvider implements TableDataRowBackgroundProviders<Car> {
    @Override
    public Drawable getRowBackground(final int rowIndex, final Car car) {
        int rowColor = getResources(R.color.white);
            
        if(car.getPrice() < 50000) {
            rowColor = getResources(R.color.light_green);
        } else if(car.getPrice() > 100000) {
            rowColor = getResources(R.color.light_red);
        }
                
        return new ColorDrawable(rowColor);
    }
}

This background provider will set the background color of each row corresponding to the price of the car that is displayed at in this row. Cheap cars (less then 50,000) get a green background, expensive cars (more then 100,000) get a red background and all other cars get a white background.

Seperator Styling

If you want to have a seperator between the data rows you can do so by specifying it in the XML like known from the ListView.

<de.codecrafters.tableview.TableView
    android:id="@+id/tableView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:divider="@color/black"
    android:dividerHeight="1dip"
    ...  /> 

As for the ListView you can specify divider as a drawable and dividerHeight as the vertical size of the divider.

Swipe to Refresh

The TableView has a build in SwipeToRefresh action. By default this is disabled, but you can easily enable it using the follwing line.

tableView.setSwipeToRefreshEnabled( true );

This enables the user to trigger the table refresh on a single swipe. To listen for this user interaction you have to set an SwipeToRefreshListener to your tableview.

carTableView.setSwipeToRefreshListener(new SwipeToRefreshListener() {
    @Override
    public void onRefresh(final RefreshIndicator refreshIndicator) {
        // your async refresh action goes here
    }
});

The callback method has the RefreshIndicator that is shown to the user passed as parameter. So if you finished your refresh action simply call RefreshIndicator.hide().

Hide Table Header

To hide the header of the TableView just call the setHeaderVisible( false ) method. You can do this also with animation calling setHeaderVisibile( false, 1000 ) where the second parameter is the duration of the animation. To make the header visible again just call setHeaderVisible( true ) or setHeaderVisible( true, 1000 ).

Hide/Show Table Header on Scroll

To hide an show the table header when the user is scrolling, just use the TableHeaderCollapseOnScrollListener.

carTableView.setOnScrollListener(new TableHeaderCollapseOnScrollListener( carTableView ));

By default the TableHeaderCollapseOnScrollListener will hide the header, when the user scrolls two rows to the bottom or shows it again when scrolling two rows to top. To change this you can call TableHeaderCollapseOnScrollListener#setRowOffset( int ) with your preferred offset. To enable animation you can call TableHeaderCollapseOnScrollListener#setAnimationDuration( int ) with your preferred animation duration.

State Persistence

The TableView as well as the SortableTableView will persist its state automatically (e.g. on orientation change). If you want to disable this behaviour you can do so using the following code snipped.

tableView.setSaveEnabled( false );

License

Copyright 2015 Ingo Schwarz

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Comments
  • Problem with table view.

    Problem with table view.

    Im using this control but when I try to show the data in the tableview, it doesn´t appear anything.

    table_products.setVisibility(View.VISIBLE); table_adapter=new cTableAdapter(getBaseContext(),res_array.get(4)); table_adapter.setData_array(res_array.get(4)); table_products.setDataAdapter(table_adapter); `public class cTableAdapter extends TableDataAdapter<Object[]> {

    private ArrayList<Object[]>data_array;
    public cTableAdapter(Context context, ArrayList<Object[]> data) {
        super(context, data);
    }
    
    public void setData_array(ArrayList<Object[]> data_array) {
        this.data_array = data_array;
    }
    
    @Override
    public View getCellView(int rowIndex, int columnIndex, ViewGroup parentView) {
       switch (columnIndex)
       {
           case 0:return renderColumn0(parentView);
           case 1:return renderColumn1(parentView,columnIndex,rowIndex);
           default:return renderColumn2(columnIndex,rowIndex);
       }
    }
    
    private View renderColumn0(ViewGroup parentView)
    {
        View viewfst=getLayoutInflater().inflate(R.layout.table_view_adapter,parentView,false);
        CheckBox cellfst=(CheckBox)viewfst.findViewById(R.id.cbx_column);
        cellfst.setChecked(false);
        return viewfst;
    }
    private View renderColumn1(ViewGroup parentView,int columnIndex,int rowIndex)
    {
       View view=getLayoutInflater().inflate(R.layout.table_view_adapter_1,parentView,false);
       TextView cell=(TextView) view.findViewById(R.id.txt_column);
       cell.setText(data_array.get(rowIndex)[columnIndex].toString());
       return view;
    }
    private View renderColumn2(int columnIndex,int rowIndex)
    {
        final TextView textView = new TextView(getContext());
        textView.setText(data_array.get(rowIndex)[columnIndex].toString());
        textView.setPadding(20, 10, 20, 10);
        return textView;
    }
    

    } ` I don´t know what is missing.

    help wanted 
    opened by renevl 19
  • add own layout inflater on getView

    add own layout inflater on getView

    i cant implement my public View getView on my own inside my adapter to inflate my own layout for the rows is there any way that i can make it? thanks

    help wanted 
    opened by agapaymarlo 19
  • How to use table view in vertical nested scroll view with horizontal scroll view

    How to use table view in vertical nested scroll view with horizontal scroll view

    Hello

    @ISchwarz23 i need to show the total of all item list in table view with different layout, it is possible with nested scroll view, can you please help how to do with nested scroll view. please give some solution

    NestedScollView LinearLayout HorizontalScrollView SortableTableView SortableTableView TextView HorizontalScrollView LinearLayout NestedScollView

    Thanks

    help wanted 
    opened by rajam1215 17
  • Unable to load rows of data

    Unable to load rows of data

    Hi,

    I am using the custom data method for rows. After initialising and calling my DataAdapter, the constructor is executed but not the getCellView overriding method. I believe this is why the rows with data are not loaded. I'm really not sure why this is happening.

    So while debugging, I notice my that the data is successfully passed to the constructor but after that nothing happens.

    Here is how I'm initialising and calling the adapters (usersList is an ArrayList of objects):

    final TableView<Users> GlobalTable = (TableView<Users>) getView().findViewById(R.id.global_tableview);

    final TableDataAdapter tableDataAdapter = new TableDataAdapter(getActivity(), usersList); GlobalTable.setDataAdapter(tableDataAdapter);

    Then my table data adapter is identical to your custom adapter example

    Thanks

    help wanted 
    opened by PSLDev94 17
  • Header Text and Sort Indicators Not Shown on API 16 or 17

    Header Text and Sort Indicators Not Shown on API 16 or 17

    Unfortunately I don't have any physical devices running these versions of Android, so I'm not able to test whether the problem is somehow related to running in the emulator. The problem isn't present API 18 (4.3) or above (which I've tested both physically and virtually).

    I removed all modifications to the color/styling, and the problem still persists. The header has the usual height and width, but it is as if there are simply no columns:

    blurred

    In the constructor of my subclass of SortableTableView, I set the header adapter as follows:

    SimpleTableHeaderAdapter header = new SimpleTableHeaderAdapter(context, /* omitted */);
    setHeaderAdapter(header);
    

    The XML for the table view is:

    </*package*/.TransactionsTableView
    	android:id="@+id/trans_table"
    	android:layout_width="match_parent"
    	android:layout_height="match_parent"
    	app:tableView_columnCount="4"
    	/>
    

    Do you know of any issues with the library on these versions of Android?

    Edit 1: It looks like this may be related to my previous bug report. The headers are only invisible when they are created while the view is initially hidden - so the sample app worked fine on APIs 16 & 17. I also copied my table into a plain activity with no fragments-and-viewpager going on, and the headers worked there as well.

    Edit 2: Here is my hacky workaround to invalidate the header when the fragment becomes visible:

    @Override
    public void setMenuVisibility(boolean menuVisible)
    {
    	super.setMenuVisibility(menuVisible);
    	if (menuVisible && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2)
    	{
    		try
    		{
    			Field f = SortableTableView.class.getDeclaredField("sortableTableHeaderView");
    			f.setAccessible(true);
    			LinearLayout header = (LinearLayout) f.get(mTableView);
    			header.invalidate();
    		}
    		catch (NoSuchFieldException e)
    		{
    			e.printStackTrace();
    		}
    		catch (IllegalAccessException e)
    		{
    			e.printStackTrace();
    		}
    	}
    }
    
    bug 
    opened by DanStout 10
  • How to set header height

    How to set header height

    Hi, Thank you for this great library.

    I'm having issues with the header because it's height is taking too much space of the screen and I noticed that in the example too.

    I searched Readme and the example for any method to control header height but I didn't find.

    Can you please tell me how to set header height?

    Best Regards Mohammad

    help wanted 
    opened by EgyptianM 9
  • Getting error while adding the dependency

    Getting error while adding the dependency

    Hi I am new to android. As you mentioned in your read me file. I added a dependency in build.gradle file. When I am trying to sync my gradle file I am getting the below error.

    "Error:(27, 13) Failed to resolve: de.codecrafters.tableview:tableview:2.1.0"

    Can you please help me understand as to how I can add dependency in my application. Is there any other step that needs to be done apart from putting an entry in the gradle file?

    question 
    opened by sdutta9 9
  • Header shriking while creating several columns

    Header shriking while creating several columns

    First, i want to thank you for this amazing lib.

    I have a problem while creating several columns, they are shrinking in size and the columns names stay like ("header here..."), i have tried to increase the setColumnWeight but with no success, i already added the horizontal scroll view like the other issues presented. Is there any way to increase the width of the columns ?

    help wanted 
    opened by gabrieltm 9
  • Header doesn't appear

    Header doesn't appear

    Hi,

    There is an issue with the library when I want to use header. If I don't put any view above the SortableTableView, the header never appears. Some examples with your sample :

    • Remove the toolbar in activity_main.xml
    • Replace RelativeLayout by a LinearLayout

    I think it's an issue because we don't need RelativeLayout everytime. The only workaround I found is using a fakeView above the TableView:

    <View
        android:id="@+id/fakeView"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="?attr/colorPrimary"/>
    
    <fr.fnac.connect.ui.component.SortableProductTableView
        android:id="@+id/comparison_table"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/fakeView"
        app:columnCount="4"
        app:headerColor="?attr/colorPrimary"
        app:headerElevation="10"/>
    

    Julien

    bug 
    opened by JulienDev 9
  • Apply sorting on date column:

    Apply sorting on date column:

    I want to apply sorting on date column but there is an issue date is also considered as a string and 1st date of all months shown then 2nd date of all month showing. How can we manage sorting for date column image

    help wanted 
    opened by sanakalam 8
  • Dynamically Changing Table Size

    Dynamically Changing Table Size

    Is it possible to change the size of the table programatically?

    Here is how I am implementing my table -

       <HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="center">
    
                <de.codecrafters.tableview.SortableTableView
                    android:id="@+id/tableView"
                    android:layout_width="900dp"
                    android:layout_height="wrap_content"
                    android:textSize="14sp"
                    custom:tableView_headerElevation="14">
                </de.codecrafters.tableview.SortableTableView>
        </HorizontalScrollView>
    

    Which is working fine, but the table can have anywhere from 2-8 columns - so 900dp looks great for 5-8 columns but looks funny for 2-4 columns.

    I've tried changing the table size like a normal element but it doesnt seem to be working.

        table.layoutParams = FrameLayout.LayoutParams(100, WRAP_CONTENT)
    

    I can tell it wants to work though, when I wrap it with

        // Log the width and the height before the change
        Log.i(TAG, table.layoutParams.width.toString() + " " + table.layoutParams.height.toString())
        
        // Change the width and keep the height the same 
        table.layoutParams = FrameLayout.LayoutParams(100, WRAP_CONTENT)
        
        // Log what it is after the change 
        Log.i(TAG, table.layoutParams.width.toString() + " " + table.layoutParams.height.toString())
    

    I get this in my Logcat

        2019-06-06 09:10:26.104 19812-19812/com.nefariis.xxxxxx I/info_logger: 2475 -2
        2019-06-06 09:10:26.104 19812-19812/com.nefariis.xxxxxx I/info_logger: 100 -2
    

    So you can see the width is going from 2475 to 100 - but its not changing on the screen.

    I've tried invalidating, post invalidating, and refreshing/redrawing the activity to no avail.

    I was hoping you have an idea of how I might accomplish this?

    Thank you and thank you again for the wonderful library.

    • Zach
    opened by Nefariis 8
  • reference Tableview is null

    reference Tableview is null

    Riepilogo.java
    TableView list = findViewById(R.id.List); String[] headers ={"Articolo","Lotto","Quantità","Utente"}; list.setHeaderAdapter(new SimpleTableHeaderAdapter(this,headers));

    activity_main.xml <de.codecrafters.tableview.TableView android:id="@+id/List" android:layout_width="match_parent" android:layout_height="match_parent" app:tableView_columnCount="4" />

    Error when i create the table E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.gestionelamiere, PID: 26419 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.gestionelamiere/com.example.gestionelamiere.Riepilogo}: java.lang.NullPointerException: Attempt to invoke virtual method 'void de.codecrafters.tableview.TableView.setHeaderAdapter(de.codecrafters.tableview.TableHeaderAdapter)' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3271) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3410) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2017) at android.os.Handler.dispatchMessage(Handler.java:107) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7397) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void de.codecrafters.tableview.TableView.setHeaderAdapter(de.codecrafters.tableview.TableHeaderAdapter)' on a null object reference at com.example.gestionelamiere.Riepilogo.onCreate(Riepilogo.java:32) at android.app.Activity.performCreate(Activity.java:7825) at android.app.Activity.performCreate(Activity.java:7814) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3246) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3410)  at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)  at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)  at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2017)  at android.os.Handler.dispatchMessage(Handler.java:107)  at android.os.Looper.loop(Looper.java:214)  at android.app.ActivityThread.main(ActivityThread.java:7397)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935) 

    opened by betto2000 0
  • Records are not showing using Kotlin

    Records are not showing using Kotlin

    Hi I implement this library using kotlin however the records are not showing only the headers.

     implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
        implementation 'com.github.ISchwarz23:SortableTableView:2.8.1'
    

    layout.xml

      <de.codecrafters.tableview.SortableTableView
                            android:layout_marginTop="5dp"
                            xmlns:table="http://schemas.android.com/apk/res-auto"
                            android:id="@+id/tableView"
                            table:tableView_columnCount="2"
                            android:layout_width="match_parent"
                            android:layout_height="match_parent"
                            />
    

    Fragment.kt

     private lateinit var tableViewSalesPerMonth: SortableTableView<Array<String>>
    onViewCreated(...){
      tableViewSalesPerMonth = binding.tableView as SortableTableView<Array<String>>
            tableViewSalesPerMonth.headerAdapter = SimpleTableHeaderAdapter(requireContext(),"Mes","Cantidad Ventas")
    
            var data = arrayOf(arrayOf("may", "33"), arrayOf("jun","32"))
            tableViewSalesPerMonth.dataAdapter = SimpleTableDataAdapter(requireContext(), data)
    
    }
    

    I will appreciate any idea to fix this problem. Thanks so much.

    opened by alcarazolabs 0
  • I want just find solution this. onclickData problem. - read one single cell value. If you can tell tips

    I want just find solution this. onclickData problem. - read one single cell value. If you can tell tips

    I new with the TableView component. Is there some one who can show me, how to read. one single Cell value. If i am understand right public void onDataClicked - just return RowIndex int value - that fine - but not columnIndex. Or is there something like getSelectedCellValue() function or... how to implement

    @Override public void onDataClicked(int rowIndex, String[] strings) {

            final String carString = "Click: " + rowIndex;
            Toast.makeText(MainActivity.this, carString, Toast.LENGTH_SHORT).show();
    

    Thanks for tips and support.

    opened by Hessu007 3
  • SortTableView scroll problem

    SortTableView scroll problem

    I'm using Tablayout, Viewpager2 and SortTableView. The SortTableView has many columns, so the length of the SortTableView exceeds the width of the screen.

    When I want to scroll on the SortTableView to see the part that is not visible (the right side of the SortTableView, sometimes the scroll causes the Tablayout to move to the next page.

    How can I scroll on the SortTableView until I see the all columns of SortTableView without move to next page?

    Thanks.

    opened by sabrinanurhidayah 0
  • inflating class de.codecrafters.tableview.TableView

    inflating class de.codecrafters.tableview.TableView

    I am facing the following problem when trying to generate the table

    android.view.InflateException: Binary XML file line # 17: Binary XML file line # 17: Error inflating class de.codecrafters.tableview.TableView Caused by: android.view.InflateException: Binary XML file line # 17: Error inflating class de.codecrafters.tableview.TableView

    E/AndroidRuntime: at android.view.View.layout(View.java:20672) at android.view.ViewGroup.layout(ViewGroup.java:6194) at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2792) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2319) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1460) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7183) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:949) at android.view.Choreographer.doCallbacks(Choreographer.java:761) at android.view.Choreographer.doFrame(Choreographer.java:696) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6669) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/swiperefreshlayout/widget/SwipeRefreshLayout; at de.codecrafters.tableview.TableView.setupTableDataView(TableView.java:562) at de.codecrafters.tableview.TableView.(TableView.java:96) at de.codecrafters.tableview.TableView.(TableView.java:81) ... 68 more Caused by: java.lang.ClassNotFoundException: Didn't find class "androidx.swiperefreshlayout.widget.SwipeRefreshLayout" on path: DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/com.consultmais.consultmais-rNuWVwD0SCMmlnyaT4DWtA==/base.apk"],nativeLibraryDirectories=[/data/app/com.consultmais.consultmais-rNuWVwD0SCMmlnyaT4DWtA==/lib/x86, /system/lib]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134) at java.lang.ClassLoader.loadClass(ClassLoader.java:379) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) ... 71 more

    opened by gustavobrunoro 1
Releases(v2.8.1)
  • v2.8.1(Dec 22, 2018)

    New Methods:

    • setGravity() in SimpleTableHeaderAdapter
    • setGravity() in SimpleTableDataAdapter

    Other:

    • update to latest version of dependencies
    Source code(tar.gz)
    Source code(zip)
  • v2.8.0(Aug 31, 2017)

    New Features:

    • listen for changes of the sorting status using SortableTableView#addSortingStatusChangeListener( SortingStateChangeListener ) and unregister using SortableTableView#removeSortingStatusChangeListener( SortingStateChangeListener )
    Source code(tar.gz)
    Source code(zip)
  • v2.7.0(Aug 26, 2017)

    New Features:

    • retrieve the current table sorting status using SortableTableView#getSortingOrder()
    • show/hide the table header using TableView#setHeaderVisible( boolean )
    • show/hide the table header animated using TableView#setHeaderVisible( boolean, int )

    New Tools:

    • show/hide the table header on scroll using the TableHeaderCollapseOnScrollListener

    Obsolescence:

    • the method SortableTableView#sort( int, boolean ) is now obsolete. use SortableTableView#sort( int, SortingOrder ) instead

    Other:

    • updated build tool version to 25.0.2
    Source code(tar.gz)
    Source code(zip)
  • v2.6.0(May 7, 2017)

  • v2.5.0(Jan 31, 2017)

  • v2.4.3(Jan 29, 2017)

  • v2.4.2(Jan 21, 2017)

    Bugs Fixed:

    • sort indicator is resetted after orientation change
    • table headers are rendered after orientation change (could not be reproduced anymore on emulator with api 16, 18, 21, 25)
    Source code(tar.gz)
    Source code(zip)
  • v2.4.1(Nov 18, 2016)

    New Features:

    • TableColumnDpWidthModel which enables fixed sizing of columns by defining the column widths in density-indipendent pixels
    • TableColumnPxWidthModel is the follwer the TableColumnWidthModel which enables fixed sizing of columns by defining the column widths in pixels

    Deprecated:

    • TableColumnWidthModel is now deprecated. Use the TableColumnPxWidthModel instead.
    Source code(tar.gz)
    Source code(zip)
  • v2.4.0(Nov 17, 2016)

  • v2.3.0(Oct 8, 2016)

  • v2.2.2(Aug 31, 2016)

    Bug Fixes:

    • Exception described in issue #49 has been fixed

    Upgrades:

    • upgrade to appcompat-v7 version 24.2.0
    • upgrade to gradle version 2.14
    • upgrade to android-maven-gradle-plugin version 1.4.1
    Source code(tar.gz)
    Source code(zip)
  • v2.2.1(Aug 7, 2016)

  • v2.2.0(Jul 19, 2016)

    New features:

    • it is now possible to add a TableDataLongClickListener to the TableView and SortableTableView

    Deprecation:

    • TableView#removeTableDataClickListener() is now deprecated -> use TableView#removeDataClickListener() instead
    • TableView#removeHeaderListener() is now deprecated -> use TableView#removeHeaderClickListener() instead
    Source code(tar.gz)
    Source code(zip)
  • v2.1.0(Jun 12, 2016)

    New features:

    • set drawables as row background (before only colors where posible)
    • SimpleTableHeaderAdapter accepts string resources

    Deprecation:

    • TableDataRowColorizer is now deprecated -> use TableDataRowBackgroundProvider
    Source code(tar.gz)
    Source code(zip)
  • v2.0.1(May 19, 2016)

  • v2.0.0(Apr 24, 2016)

    Fixed Bugs:

    • deconfliction with GridLayout xml attributes

    Api Changes:

    • added "tableView_" prefix to xml attributes (fix confliction with GridLayout attribute "columnCount")
    • renaming of setDataRowColoriser to setDataRowColorizer in TableView and SortableTableView to align naming through the whole library
    Source code(tar.gz)
    Source code(zip)
  • v1.1.1(Apr 24, 2016)

  • v1.1.0(Apr 3, 2016)

  • v1.0.1(Feb 2, 2016)

  • v1.0.0(Jan 30, 2016)

  • v0.9.6(Jan 6, 2016)

    The TableView as well as the SortableTableView provide now more adaptation possibilities for the data display area. Now the data area supports now all the customization possibilites which are supported by the TableView. This can be edited via the layout file. An example adaptation possibility is the divider adaptation like divider color or divider height.

    Source code(tar.gz)
    Source code(zip)
  • v0.9.5(Aug 16, 2015)

Owner
Ingo Schwarz
Ingo Schwarz
Android library providing bread crumbs to the support library fragments.

Hansel And Gretel Android library providing bread crumbs for compatibility fragments. Usage For a working implementation of this project see the sampl

Jake Wharton 163 Nov 25, 2022
Fragments: Advanced Reusable Interfaces on Android

LIVE #016 - Fragments: Interfaces reutilizáveis avançadas no Android (Atualizado com Jetpack) Código fonte do projeto criado na live #016, ensinando c

Kaique Ocanha 6 Oct 3, 2022
A simple launcher which displays all the apps on a RecyclerView trying to KISS

A simple launcher which displays all the apps on a RecyclerView trying to KISS

Alex Allafi 1 Jun 17, 2022
A convinience library for working with all versions of the Android Preference package from API v4 and up

UnifiedPreference UnifiedPreference is a library for working with all versions of the Android Preference package from API v4 and up. Features Easy to

Joel Pedraza 544 Nov 28, 2022
Simple and lightweight UI library for user new experience, combining floating bottom navigation and bottom sheet behaviour. Simple and beautiful.

Simple and lightweight UI library for user new experience, combining floating bottom navigation and bottom sheet behaviour. Simple and beautiful.

Rizki Maulana 118 Dec 14, 2022
Pulseq is a service for monitoring activity from all your devices.

Pulseq is inspired by technically-functional/heartbeat, which is licensed under the ISC license. The main idea of pulseq is to provide statistics on y

d1snin-dev 5 Sep 8, 2022
This library provides a simple way to add a draggable sliding up panel (popularized by Google Music and Google Maps) to your Android application. Brought to you by Umano.

Note: we are not actively responding to issues right now. If you find a bug, please submit a PR. Android Sliding Up Panel This library provides a simp

Umano: News Read To You 9.4k Dec 31, 2022
Simple and powerful library to emulate iOS's "3D Touch" preview functionality on Android.

Android 3D Touch - PeekView iOS uses 3D Touch as a way to "peek" into full content, such as emails, pictures, web searches, etc. While they have dedic

Luke Klinker 502 Dec 29, 2022
A simple library to let you sign (or draw lines) smoothly with your finger into a view and save it.

FingerSignView Introduction FingerSignView is a simple library that lets you finger, or draw lines, smoothly with your finger into a View and save it

Agnaldo Pereira 25 Nov 20, 2022
A new canvas drawing library for Android. Aims to be the Fabric.js for Android. Supports text, images, and hand/stylus drawing input. The library has a website and API docs, check it out

FabricView - A new canvas drawing library for Android. The library was born as part of a project in SD Hacks (www.sdhacks.io) on October 3rd. It is cu

Antwan Gaggi 1k Dec 13, 2022
Android Library to implement simple touch/tap/swipe gestures

SimpleFingerGestures An android library to implement simple 1 or 2 finger gestures easily Example Library The library is inside the libSFG folder Samp

Arnav Gupta 315 Dec 21, 2022
A simple library to add Emoji support to your Android Application

Emoji A library to add Emoji support to your Android app. Emojis can be picked in a PopupWindow. In order to edit and display text with Emojis this li

Niklas Baudy 1.4k Jan 4, 2023
This library offers a simple method to add a small badge icon to your ActionBar-MenuItem

Android-ActionItemBadge ActionItemBadge is a library which offers a simple and easy to use method to add a badge to your action item! Screenshots Incl

Mike Penz 1.3k Jan 1, 2023
Sentinel is a simple one screen UI which provides a standardised entry point for tools used in development and QA alongside device, application and permissions data.

Sentinel Sentinel is a simple one screen UI that provides standardised entry point for tools used in development and QA alongside device, application

Infinum 29 Dec 12, 2022
Android StackBlur is a library that can perform a blurry effect on a Bitmap based on a gradient or radius, and return the result. The library is based on the code of Mario Klingemann.

Android StackBlur Android StackBlur is a library that can perform a blurry effect on a Bitmap based on a gradient or radius, and return the result. Th

Enrique López Mañas 3.6k Dec 29, 2022
Snake View is a simple and animated linear chart for Android.

Snake View Snake library is a simple and animation line chart for Android. Latest Version How to use Configuring your project dependencies Add the lib

Txus Ballesteros 339 Dec 14, 2022
A simple, customizable and easy to use swipeable view stack for Android.

SwipeStack A simple, customizable and easy to use swipeable view stack for Android. QuickStart Include the Gradle dependency dependencies { compil

Frederik Schweiger 1.5k Dec 30, 2022
A simple and Elegant Showcase view for Android

Tuto Showcase A simple and Elegant Showcase view for Android TutoShowcase.from(this) .setContentView(R.layout.tuto_sample) .on(R.id.about) //

Florent CHAMPIGNY 509 Nov 25, 2022
Simple and fantastic wheel view in realistic effect for android.

Overview ![Size](https://img.shields.io/badge/Size-17 KB-e91e63.svg) Contact Preview Demo WheelPicke.APK Include Compile compile 'cn.aigestudio.wheelp

Aige 2.5k Jan 6, 2023