Coder Social home page Coder Social logo

ischwarz23 / sortabletableview Goto Github PK

View Code? Open in Web Editor NEW
1.1K 43.0 240.0 3.21 MB

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

License: Apache License 2.0

Java 100.00%
sortabletableview android-library tableview android android-ui material-design

sortabletableview's Introduction

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

Add it in your root build.gradle at the end of repositories:

    allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
    }

Then add the dependency:

    dependencies {
        ...
        implementation 'com.github.ISchwarz23:SortableTableView:2.8.1'
        ...
    }

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.

sortabletableview's People

Contributors

ischwarz23 avatar ktanna avatar ooelectron avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sortabletableview's Issues

Kang

Hello, thanks for your great work, I have a problem when add many headers, and each header fully wraps the content, so maybe need to scroll horizontally, can you tell me how to solve this problems, thanks!

FloatingActionButton

I find i use the this and can't build the project when i had use FloatingActionButton

the Error show:
Could not find class 'android.graphics.drawable.RippleDrawable', referenced from method android.support.v7.widget.AppCompatImageHelper.hasOverlappingRendering

java.lang.RuntimeException: Unable to start activity ComponentInfo{beans.physicalfitness/beans.physicalfitness.MainActivity}: android.view.InflateException: Binary XML file line #26: Error inflating class android.support.design.widget.FloatingActionButton

thanks

How to colorize the divider?

Hello! Does library can colorize divider or make it transperent?
android:divider and .setDividerDrawable won't work at all
Thanks!

Support for Android SDK <11.

Do you plan to release a version compatible with Android SDK lower than 11. This has locked out 20% of potential users. Alternatively, what would you advise I do if need the compatibility?

Thank you.

Joe

View recycling

I've noticed that TableDataAdapter.getCellView isn't called with a converView that you can use to recycleviews.

I think this causes causes significant performance degradation, I notice this when scrolling very fast through a long list, which results in very jerky scrolling behavior.

Is there a reason why you do not reuse the convertView in TableDataAdapter.getView if not null, and do not pass the original cellView to the TableDataAdapter.getCellView (if it exists)?

typo issue in your readme.md

hi again and sorry for making another issue :D,

in your readme.md in Colorizer part you mentioned this code:
tableView.setDataRowColoriser(TableDataRowColorisers.alternatingRows(colorEvenRows, colorOddRows));

but it should be actually TableDataRowColori"z"ers.

How to add gesture events to SortableTableView

I want to add gesture event like swipe, double table ,longPress events to SorttableTableView how could I implement this feature. I try to add onTouchEvent to this view but does not working.

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?

Cell click event in the table

Hi,
Thanks for the library. It's really helpful.

Can you please tell me how to write click event on the each table cell to get the cell value.

Thank You
-Vinay

Set column widths to wrap_content instead using weights

Is there an option to set column widths to wrap content instead using weights? It would be nice if it worked like a typical linear layout: wrap content for most of the columns and set weight to the one that should take the rest of available space.

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

tableview folder . newbie

Hi im newbie

It says

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

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

It's clear that I should copy the tableview folder and add the dependencies on build.gradle. Where should I copy the tableview folder to?

Sort

Hello!
How to add many sort algorithm?

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

Need more sorting algorithm.
Exapmle:
| header |
| new |
| pending |
| done |
| pending |
| pending |
| done |
How to sort "first new" or "first done"? Use Comparator?

sortableTableView.setColumnComparator(0, new CarProducerComparator());

No! Comparator sort "-1, 0, 1".
And need more sorting button, or popup menu.
Sorry my bad english. =(

Using the Eclipse ADT?

Hello, I would like to use this library in Eclipse ADT but without success.
Xml layout can not inflate the component:

     <de.codecrafters.tableviewexample.SortableCarTableView
         android: id = "@ + id / tableView"
         android: layout_width = "match_parent"
         android: layout_height = "match_parent"
         android: layout_below = "@ id / toolbar"
         custom: tableView_columnCount = "4"
         custom: tableView_headerElevation = "10"
         custom: tableView_headerColor = "@ color / primary" />

giving an error that does not exist.

How to do this?

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

Provide my own view for sortable_header.xml

Hello,

I'd like to be able to provide my own view for for the SortableTableHeaderView. Instead of the the little widget, I'd like to overlay the header when it's sorted. Unfortunately there isn't a way to override or inject anything in SortableTable to do this.

Do you think it'd be a good idea to allow SortableTableView to inject a custom content provider to inflate the headerContainerLayout in SortableTableHeaderView.renderHeaderViews()? I think we can also change the LinearLayout to a ViewGroup.

I'm thinking something like:

final ViewGroup headerContainerLayout = (ViewGroup) mHeaderContentProvider(adapter, this);

Then providing the appropriate setters on SortableTable and SortableTableHeaderView.

The the default provider would just inflate the current R.layout.sortable_header.

Set selected row backgroundColor

I'm trying to find an easy way to set (change) the background color of selected a row when its clicked on and keep the background color after sorting rows.
Do it as ListView
<ListView
....
android:choiceMode="singleChoice"
android:listSelector="#4d90fe"/>

Table grows when sorting within HorizontalScrollView

Hello Ingo,

I really enjoy using your SortableTableView for my app, it's a really great library. Unfortunately, there is one problem that I have with it: When I use a SortableTableView inside a HorizontalScrollView, then each time I tab a table header to sort the table, the table grows a bit wider. To recreate this you can use your sample project in your repository and just put the View into a HorizontalScrollView. The resulting main_activity.xml looks as follows:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                xmlns:custom="http://schemas.android.com/apk/res-auto"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context="de.codecrafters.tableviewexample.MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/primary"
        custom:title="@string/title_activity_main"
        custom:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

    <android.widget.HorizontalScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <de.codecrafters.tableviewexample.SortableCarTableView
            android:id="@+id/tableView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@id/toolbar"
            custom:columnCount="4"
            custom:headerElevation="10"
            custom:headerColor="@color/primary" />

    </android.widget.HorizontalScrollView>

</RelativeLayout>

Is this a bug or is this intended behavior? If it is the latter, can you please tell me how I can prevent the table from growing?

Best Regards,
Luparion

Remove the TableView's internal ScrollView

This is not needed and can easily be implemented if needed. The problem due to this can be explained like this.

When I have tableView at the lower end of my LinearLayout layout (or any) where only 1 row can be visible. Then the tableView's internal scrollview starts scrolling that one row but I want to scroll all the screen up to see more than one rows. This is only possible when tableView expand itself beyond the screen in a parent scrollView which holds all the screen.

Here is my tableView layout in a LinearLayout with many siblings that are all in a ScrollView vertical.
<com.dgheating.mobileapp.Data.SortableProductTable xmlns:android="http://schemas.android.com/apk/res/android" xmlns:table="http://schemas.android.com/apk/res-auto" android:id="@+id/tableViewProducts" android:layout_width="match_parent" android:layout_height="wrap_content" android:divider="@color/dividerDarkGrey" android:dividerHeight="1dip" table:columnCount="5" table:headerColor="@color/colorPrimary" />

untitled

See in the screen shot I can't scroll the screen up because tableView is not expanding based on its content.

Adding Header Text.

Hi ,

Im trying to add text to the header but failing.
How can it be done?

What i have tried,

TableView<String[]> tableView = (TableView<String[]>) getView().findViewById(R.id.view12);
tableView.setHeaderBackground(R.color.accent);
SimpleTableHeaderAdapter simpleTableHeaderAdapter = new SimpleTableHeaderAdapter(container,false, R.string.id, R.string.alarm, R.string.Add);
tableView.setHeaderAdapter(simpleTableHeaderAdapter);

isn't there a way to make it scrollable horizontally?

thanks for your great library,

I have a problem. in my situation I have tables with 10-50 columns, I really need to have a horizontal scroll for it and also making more width for each column. is there anyway to do that?

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 ?

Maven Artifact of this library?

Hello Ingo,

can you please create a Maven Artifact of your library and deploy it to Maven Central? We want to use your library at work, however we use Maven as our build system and will not switch to Gradle in the near future.

Best Regards,
Luparion

Only shows 1 row when used in a listview.

Hi there,

I am trying to implement this TableView in a ListView. The problem is, it only shows 1 row and you have to scroll the tableview itself to see other rows. Is it a bug or am I doing something wrong? Here is what I do:

This is my JSON data:

{"Rows":[{"Column":["Karşıyaka-Bornova","Bornova-Karşıyaka"]},{"Column":["9:30","10:00"]},{"Column":["10:30","11:00"]}]}

Code:

LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);

JSONObject table = new JSONObject(s10Data);
int columns = table.getJSONArray("Rows").getJSONObject(0).getJSONArray("Column").length();
int rows = table.getJSONArray("Rows").length();
List<String[]> tableList = new ArrayList<>();
TableView<String[]> tableView = new TableView(activity);
tableView.setColumnCount(columns);


for (int j = 0; j < rows; j++) {
    String[] rowItems = new String[columns];
         for (int k = 0; k < columns; k++) {
               rowItems[k] = table.getJSONArray("Rows").getJSONObject(j).getJSONArray("Column").getString(k);
                }
                tableList.add(rowItems);
           }

SimpleTableDataAdapter adapter10 = new SimpleTableDataAdapter(activity,tableList);
tableView.setDataAdapter(adapter10);
tableView.setLayoutParams(params2);
holder.innerLinearLayout.addView(tableView);

And this is what happens:

Picture

This is how it supposed to appear. (Have no idea why there is grey space on it)

Picture

Edit:
After implementing a headeradapter, it now shows header and 1 other row. Still need a solution here.

Sorting indicator not "activated" for default sorted column

Hello Ingo, Thank you for such a great contribution!

Can you please let me know how to "activate" the sorting indicator for the default sorted column? My goal is to clearly communicate to the user which column is sorted and in which direction. Once the user clicks on a particular column, the indicator is clearly activating but not before clicking.
thanks again!

Divider for data and header row elements

Hello! Can you add methods like this?
setDataRowElementDividerHeight()
setDataRowElementDividerColor()
setHeaderRowElementDividerHeight()
setHeaderRowElementDividerColor()

Scroll-able along with other items, outside it's container

Hello,
Thank you for the swift reply to my question. I've opened it as a new issue as you advised.
I tried the syntax as you requested. It works well, though a small bit still bugs me. So I enclosed it in a scrollview but it still scrolls inside itself.

The structure of my layout file
`
ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">

<LinearLayout>  header views like instructions, etc </LinearLayout>

    <de.codecrafters.tableview.TableView
        xmlns:table="http://schemas.android.com/apk/res-auto"
        android:id="@+id/instTableView"
        android:orientation="vertical"
        android:layout_marginTop="10dip"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:divider="@color/list_divider"
        android:dividerHeight="1dip"
        android:textSize="10sp"
        android:layout_marginBottom="50dp"
        android:background="@drawable/flat_border_set"
        android:gravity="center_horizontal"/>
//Long list of item views {table rows}

<LinearLayout> - footer views eg share buttons etc </LinearLayout>

</ScrollView`

As it is, when I scroll down the rows scroll within the table container. This becomes a challenge for smaller screens.

So, I'd like to have the whole page to scroll so that if a user scrolls down, the table view scrolls along with everything else. Am I doing it wrong?

Joe

I/de.codecrafters.tableview.SortableTableView: Unable to sort column with index -1. Reason: no comparator set for this column.

The example application from the google play store does not exhibit this issue. However, following the instructions from the readme.md file, any time the orientation of the screen changes, the warning (from the title) appears in the debug log. I'm using 2.2.1 on android 6.0

This is the view

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

This is the code in a fragment

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View v = inflater.inflate(R.layout.fragment_history, container, false);
        SortableTableView<String[]> tableView = (SortableTableView<String[]>) v.findViewById(R.id.tableView);

        String[] header = {"Scan", "Hardware ID", "Timestamp", "blood"};
        tableView.setHeaderAdapter(new SimpleTableHeaderAdapter(getActivity(), header));


        tableView.setColumnCount(4);

        String[][] data = {{"no", "data", "yet", ":("}};
        tableView.setDataAdapter(new SimpleTableDataAdapter(getActivity(), data));
        tableView.setColumnComparator(0, (String[] lhs, String[] rhs)->Integer.parseInt(lhs[0]) - Integer.parseInt(rhs[0]));
        tableView.setColumnComparator(1, (String[] lhs, String[] rhs)->lhs[1].compareTo(rhs[1]));
        tableView.setColumnComparator(2, (String[] lhs, String[] rhs)->lhs[2].compareTo(rhs[2]));
        tableView.setColumnComparator(3, (String[] lhs, String[] rhs)->Integer.parseInt(lhs[3]) - Integer.parseInt(rhs[3]));
        return v;
    }

Interestingly enough, the first instance of this fragment getting created won't display that error/warning onto the log.

notifyDataSetChanged(); not working

Today I have tried using your library to show some data but after updating it I cannot refresh the data in the adapter, because the method adapter.notifyDataSetChanged(); doesn't seem to work? Did I make a mistake somewhere, should I post my code here or is this a known issue?

Scrollbar not present

Hi,

Thanks for this library!

On my Nexus 6 running Android 5.1.1 and my Nexus 7 (2103) running 6.01, I'm not seeing a scrollbar in my tableview.

Do I need to do something different or is this a bug?

ScrollView for several SortableTableViews

Hello, i was trying to put several tables inside a ScrollView, for example:

<ScrollView ... <RelativeLayout ... <HorizontalScrollView ... <SortableTableView ...

I want to create several SortableTableViews, however when i scroll vertically through the screen, the vertical scrolling inside the SortableTableViews doesn't work anymore (if it has like 50 rows of data and i'm setting the height to show only 4 at once). Do you know if this is fixable?

Thanks.

Findviewbyid return null

Hello,

When i try to get sortabletableview it return me Null, i'm using it in fragment.

materiauTableView = (SortableMateriauTableView) view.findViewById(R.id.tableView);

<com.diadecmobile.view.fragment.projectFragment.materiauxFragment.SortableMateriauTableView
        android:id="@+id/tableView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        custom:columnCount="8"
        custom:headerElevation="10"
        custom:headerColor="@color/theme_primary" />

Crash on orientation change / restore instance state

There's some kind of bug introduced with the 0.9.6 version. When changing the orientation of the device, an unhandled exception is throw from the restore instance state code. It can be replicated using the demo app. Version 0.9.5 works correctly.

FATAL EXCEPTION: main
  Process: de.codecrafters.tableviewexample, PID: 20881
  java.lang.RuntimeException: Unable to start activity ComponentInfo{de.codecrafters.tableviewexample/de.codecrafters.tableviewexample.MainActivity}: java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class android.widget.AbsListView$SavedState instead. This usually happens when two views of different type have the same id in the same hierarchy. This view's id is id/tableView. Make sure other views do not use the same id.
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
      at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4053)
      at android.app.ActivityThread.access$900(ActivityThread.java:156)
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1357)
      at android.os.Handler.dispatchMessage(Handler.java:102)
      at android.os.Looper.loop(Looper.java:211)
      at android.app.ActivityThread.main(ActivityThread.java:5373)
      at java.lang.reflect.Method.invoke(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:372)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
   Caused by: java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class android.widget.AbsListView$SavedState instead. This usually happens when two views of different type have the same id in the same hierarchy. This view's id is id/tableView. Make sure other views do not use the same id.
      at android.view.View.onRestoreInstanceState(View.java:13847)
      at android.view.View.dispatchRestoreInstanceState(View.java:13823)
      at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2888)
      at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2894)
      at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2894)
      at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2894)
      at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2894)
      at android.view.View.restoreHierarchyState(View.java:13801)
      at com.android.internal.policy.impl.PhoneWindow.restoreHierarchyState(PhoneWindow.java:2012)
      at android.app.Activity.onRestoreInstanceState(Activity.java:1023)
      at android.app.Activity.performRestoreInstanceState(Activity.java:978)
      at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1162)
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2352)
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442) 
      at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4053) 
      at android.app.ActivityThread.access$900(ActivityThread.java:156) 
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1357) 
      at android.os.Handler.dispatchMessage(Handler.java:102) 
      at android.os.Looper.loop(Looper.java:211) 
      at android.app.ActivityThread.main(ActivityThread.java:5373) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:372) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815) 

Usage of this library in your App

Hi all,

As this library is now nearly one year old, I'm very interested in which apps this library is used. Especially if this app is available in the app store.
I just want this information to use it in my references. So if you have used this lib in your app which is already published please write the app name (or maybe a link to the app store) as an answer to this issue. I'm very intereseted to see how you have used my library :)

Best regards,
Ingo

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.