diff --git a/app/build.gradle b/app/build.gradle index a0ae9733..de95fbfb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -60,6 +60,7 @@ android { dependencies { implementation project(path: ':tableview') + implementation project(path: ':tableviewutil') implementation "androidx.annotation:annotation:$androidx_annotation_version" implementation "androidx.appcompat:appcompat:$androidx_appcompat_version" diff --git a/app/src/main/java/com/evrencoskun/tableviewsample/MainFragment.java b/app/src/main/java/com/evrencoskun/tableviewsample/MainFragment.java index 68379ffb..87344f66 100644 --- a/app/src/main/java/com/evrencoskun/tableviewsample/MainFragment.java +++ b/app/src/main/java/com/evrencoskun/tableviewsample/MainFragment.java @@ -42,12 +42,20 @@ import com.evrencoskun.tableview.TableView; import com.evrencoskun.tableview.filter.Filter; import com.evrencoskun.tableview.pagination.Pagination; -import com.evrencoskun.tableviewsample.tableview.TableViewAdapter; import com.evrencoskun.tableviewsample.tableview.TableViewListener; -import com.evrencoskun.tableviewsample.tableview.TableViewModel; +import com.evrencoskun.tableviewutil.TableViewAdapter; +import com.evrencoskun.tableviewutil.TableViewModel; +import com.evrencoskun.tableviewsample.tableview.TestData; +import com.evrencoskun.tableviewsample.tableview.model.MySamplePojo; +import com.evrencoskun.tableview.model.ColumnDefinition; + +import java.util.List; /** * A simple {@link Fragment} subclass. + * + * * Display the TableView. + * * Implements filtering, paging, selection, onClick-handling, menue-commands */ public class MainFragment extends Fragment { private Spinner moodFilter, genderFilter; @@ -115,11 +123,13 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat } private void initializeTableView() { + List> columnDefinitions = TestData.createColumnDefinitions(); + List pojos = TestData.createSampleData(); // Create TableView View model class to group view models of TableView - TableViewModel tableViewModel = new TableViewModel(); + TableViewModel tableViewModel = new TableViewModel(columnDefinitions, pojos); // Create TableView Adapter - TableViewAdapter tableViewAdapter = new TableViewAdapter(tableViewModel); + TableViewAdapter tableViewAdapter = new TableViewAdapter<>(); mTableView.setAdapter(tableViewAdapter); mTableView.setTableViewListener(new TableViewListener(mTableView)); @@ -158,7 +168,7 @@ public void filterTableForMood(@NonNull String filter) { // Sets a filter to the table, this will only filter a specific column. // In the example data, this will filter the mood column. if (mTableFilter != null) { - mTableFilter.set(TableViewModel.MOOD_COLUMN_INDEX, filter); + mTableFilter.set(TestData.COLUMN_INDEX_MOOD_HAPPY, filter); } } @@ -166,7 +176,7 @@ public void filterTableForGender(@NonNull String filter) { // Sets a filter to the table, this will only filter a specific column. // In the example data, this will filter the gender column. if (mTableFilter != null) { - mTableFilter.set(TableViewModel.GENDER_COLUMN_INDEX, filter); + mTableFilter.set(TestData.COLUMN_INDEX_GENDER_MALE, filter); } } diff --git a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/TableViewListener.java b/app/src/main/java/com/evrencoskun/tableviewsample/tableview/TableViewListener.java index 242bf0ae..fbaf1775 100644 --- a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/TableViewListener.java +++ b/app/src/main/java/com/evrencoskun/tableviewsample/tableview/TableViewListener.java @@ -25,14 +25,16 @@ package com.evrencoskun.tableviewsample.tableview; import android.content.Context; +import android.util.Log; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.evrencoskun.tableview.TableView; +import com.evrencoskun.tableview.adapter.recyclerview.holder.AbstractViewHolder; import com.evrencoskun.tableview.listener.ITableViewListener; -import com.evrencoskun.tableviewsample.tableview.holder.ColumnHeaderViewHolder; +import com.evrencoskun.tableviewutil.holder.ColumnHeaderViewHolder; import com.evrencoskun.tableviewsample.tableview.popup.ColumnHeaderLongPressPopup; import com.evrencoskun.tableviewsample.tableview.popup.RowHeaderLongPressPopup; @@ -60,10 +62,21 @@ public TableViewListener(@NonNull TableView tableView) { */ @Override public void onCellClicked(@NonNull RecyclerView.ViewHolder cellView, int column, int row) { + showToast("onCellClicked" + getMessageContext(cellView, column, row)); - // Do what you want. - showToast("Cell " + column + " " + row + " has been clicked."); + } + @NonNull + private String getMessageContext(RecyclerView.ViewHolder cellView, int column, int row) { + String data = ""; + if (cellView instanceof AbstractViewHolder) { + final Object pojo = ((AbstractViewHolder) cellView).getPojo(); + if (pojo != null) { + data = pojo.toString(); + } + } + return "(c=" + column + ",r=" + row + ") for " + data + " [" + + cellView.getClass().getSimpleName() + ".]"; } /** @@ -76,7 +89,7 @@ public void onCellClicked(@NonNull RecyclerView.ViewHolder cellView, int column, @Override public void onCellDoubleClicked(@NonNull RecyclerView.ViewHolder cellView, int column, int row) { // Do what you want. - showToast("Cell " + column + " " + row + " has been double clicked."); + showToast("onCellDoubleClicked" + getMessageContext(cellView, column, row)); } /** @@ -90,7 +103,7 @@ public void onCellDoubleClicked(@NonNull RecyclerView.ViewHolder cellView, int c public void onCellLongPressed(@NonNull RecyclerView.ViewHolder cellView, final int column, int row) { // Do What you want - showToast("Cell " + column + " " + row + " has been long pressed."); + showToast("onCellLongPressed" + getMessageContext(cellView, column, row)); } /** @@ -103,7 +116,7 @@ public void onCellLongPressed(@NonNull RecyclerView.ViewHolder cellView, final i public void onColumnHeaderClicked(@NonNull RecyclerView.ViewHolder columnHeaderView, int column) { // Do what you want. - showToast("Column header " + column + " has been clicked."); + showToast("onColumnHeaderClicked" + getMessageContext(columnHeaderView, column, -1)); } /** @@ -115,7 +128,7 @@ public void onColumnHeaderClicked(@NonNull RecyclerView.ViewHolder columnHeaderV @Override public void onColumnHeaderDoubleClicked(@NonNull RecyclerView.ViewHolder columnHeaderView, int column) { // Do what you want. - showToast("Column header " + column + " has been double clicked."); + showToast("onColumnHeaderDoubleClicked" + getMessageContext(columnHeaderView, column, -1)); } /** @@ -127,11 +140,12 @@ public void onColumnHeaderDoubleClicked(@NonNull RecyclerView.ViewHolder columnH @Override public void onColumnHeaderLongPressed(@NonNull RecyclerView.ViewHolder columnHeaderView, int column) { + showToast("onColumnHeaderLongPressed" + getMessageContext(columnHeaderView, column, -1)); if (columnHeaderView instanceof ColumnHeaderViewHolder) { // Create Long Press Popup ColumnHeaderLongPressPopup popup = new ColumnHeaderLongPressPopup( - (ColumnHeaderViewHolder) columnHeaderView, mTableView); + (ColumnHeaderViewHolder) columnHeaderView, mTableView, column); // Show popup.show(); } @@ -146,7 +160,7 @@ public void onColumnHeaderLongPressed(@NonNull RecyclerView.ViewHolder columnHea @Override public void onRowHeaderClicked(@NonNull RecyclerView.ViewHolder rowHeaderView, int row) { // Do whatever you want. - showToast("Row header " + row + " has been clicked."); + showToast("onRowHeaderClicked" + getMessageContext(rowHeaderView, -1, row)); } /** @@ -158,7 +172,7 @@ public void onRowHeaderClicked(@NonNull RecyclerView.ViewHolder rowHeaderView, i @Override public void onRowHeaderDoubleClicked(@NonNull RecyclerView.ViewHolder rowHeaderView, int row) { // Do whatever you want. - showToast("Row header " + row + " has been double clicked."); + showToast("onRowHeaderDoubleClicked" + getMessageContext(rowHeaderView, -1, row)); } /** @@ -169,15 +183,17 @@ public void onRowHeaderDoubleClicked(@NonNull RecyclerView.ViewHolder rowHeaderV */ @Override public void onRowHeaderLongPressed(@NonNull RecyclerView.ViewHolder rowHeaderView, int row) { + showToast("onRowHeaderLongPressed" + getMessageContext(rowHeaderView, -1, row)); // Create Long Press Popup - RowHeaderLongPressPopup popup = new RowHeaderLongPressPopup(rowHeaderView, mTableView); + RowHeaderLongPressPopup popup = new RowHeaderLongPressPopup(rowHeaderView, mTableView, row); // Show popup.show(); } private void showToast(String p_strMessage) { - Toast.makeText(mContext, p_strMessage, Toast.LENGTH_SHORT).show(); + Log.d(this.getClass().getSimpleName(), p_strMessage); + Toast.makeText(mContext, p_strMessage, Toast.LENGTH_LONG).show(); } } diff --git a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/TableViewModel.java b/app/src/main/java/com/evrencoskun/tableviewsample/tableview/TableViewModel.java deleted file mode 100644 index 27d3dd0b..00000000 --- a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/TableViewModel.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2021 Evren Coşkun - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package com.evrencoskun.tableviewsample.tableview; - -import androidx.annotation.DrawableRes; -import androidx.annotation.NonNull; - -import com.evrencoskun.tableviewsample.R; -import com.evrencoskun.tableviewsample.tableview.model.Cell; -import com.evrencoskun.tableviewsample.tableview.model.ColumnHeader; -import com.evrencoskun.tableviewsample.tableview.model.RowHeader; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -/** - * Created by evrencoskun on 4.02.2018. - */ - -public class TableViewModel { - - // Columns indexes - public static final int MOOD_COLUMN_INDEX = 3; - public static final int GENDER_COLUMN_INDEX = 4; - - // Constant values for icons - public static final int SAD = 1; - public static final int HAPPY = 2; - public static final int BOY = 1; - public static final int GIRL = 2; - - // Constant size for dummy data sets - private static final int COLUMN_SIZE = 500; - private static final int ROW_SIZE = 500; - - // Drawables - @DrawableRes - private final int mBoyDrawable; - @DrawableRes - private final int mGirlDrawable; - @DrawableRes - private final int mHappyDrawable; - @DrawableRes - private final int mSadDrawable; - - public TableViewModel() { - // initialize drawables - mBoyDrawable = R.drawable.ic_male; - mGirlDrawable = R.drawable.ic_female; - mHappyDrawable = R.drawable.ic_happy; - mSadDrawable = R.drawable.ic_sad; - } - - @NonNull - private List getSimpleRowHeaderList() { - List list = new ArrayList<>(); - for (int i = 0; i < ROW_SIZE; i++) { - RowHeader header = new RowHeader(String.valueOf(i), "row " + i); - list.add(header); - } - - return list; - } - - /** - * This is a dummy model list test some cases. - */ - @NonNull - private List getRandomColumnHeaderList() { - List list = new ArrayList<>(); - - for (int i = 0; i < COLUMN_SIZE; i++) { - String title = "column " + i; - int nRandom = new Random().nextInt(); - if (nRandom % 4 == 0 || nRandom % 3 == 0 || nRandom == i) { - title = "large column " + i; - } - - ColumnHeader header = new ColumnHeader(String.valueOf(i), title); - list.add(header); - } - - return list; - } - - /** - * This is a dummy model list test some cases. - */ - @NonNull - private List> getCellListForSortingTest() { - List> list = new ArrayList<>(); - for (int i = 0; i < ROW_SIZE; i++) { - List cellList = new ArrayList<>(); - for (int j = 0; j < COLUMN_SIZE; j++) { - Object text = "cell " + j + " " + i; - - final int random = new Random().nextInt(); - if (j == 0) { - text = i; - } else if (j == 1) { - text = random; - } else if (j == MOOD_COLUMN_INDEX) { - text = random % 2 == 0 ? HAPPY : SAD; - } else if (j == GENDER_COLUMN_INDEX) { - text = random % 2 == 0 ? BOY : GIRL; - } - - // Create dummy id. - String id = j + "-" + i; - - Cell cell; - if (j == 3) { - cell = new Cell(id, text); - } else if (j == 4) { - // NOTE female and male keywords for filter will have conflict since "female" - // contains "male" - cell = new Cell(id, text); - } else { - cell = new Cell(id, text); - } - cellList.add(cell); - } - list.add(cellList); - } - - return list; - } - - @DrawableRes - public int getDrawable(int value, boolean isGender) { - if (isGender) { - return value == BOY ? mBoyDrawable : mGirlDrawable; - } else { - return value == SAD ? mSadDrawable : mHappyDrawable; - } - } - - @NonNull - public List> getCellList() { - return getCellListForSortingTest(); - } - - @NonNull - public List getRowHeaderList() { - return getSimpleRowHeaderList(); - } - - @NonNull - public List getColumnHeaderList() { - return getRandomColumnHeaderList(); - } -} diff --git a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/TestData.java b/app/src/main/java/com/evrencoskun/tableviewsample/tableview/TestData.java new file mode 100644 index 00000000..471ee7b6 --- /dev/null +++ b/app/src/main/java/com/evrencoskun/tableviewsample/tableview/TestData.java @@ -0,0 +1,89 @@ +/* + * MIT License + * + * Copyright (c) 2023 K3b + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.evrencoskun.tableviewsample.tableview; + +import com.evrencoskun.tableviewsample.R; +import com.evrencoskun.tableviewsample.tableview.model.MySamplePojo; +import com.evrencoskun.tableview.model.ColumnDefinition; +import com.evrencoskun.tableviewutil.TableViewAdapter; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +/** + * This is where all Testdata for the demo app comes from. + * + * Created by k3b on 2023-03-09 + */ + +public class TestData { + // Columns indexes also used as cell-types + public static final int COLUMN_INDEX_MOOD_HAPPY = 3; + public static final int COLUMN_INDEX_GENDER_MALE = 4; + + // Constant size for dummy data sets + private static final int COLUMN_SIZE = 500; + private static final int ROW_SIZE = 500; + + public static List createSampleData() { + List sampleData = new ArrayList<>(); + for(int i = 0; i < ROW_SIZE; i++) { + sampleData.add(new MySamplePojo(String.valueOf(i))); + } + return sampleData; + } + + public static List> createColumnDefinitions() { + List> definitions = new ArrayList<>(); + definitions.addAll( + // column 0..4 userdefined + Arrays.asList( + new ColumnDefinition<>("Random 0", r -> r.mRandom), + new ColumnDefinition<>("Short 1", r -> r.mRandomShort), + new ColumnDefinition<>("Text 2", r1 -> r1.mText), + + // column 3..4 contain image + new ColumnDefinition<>("Gender 3", r -> r.mGenderMale, + parent -> TableViewAdapter.createBoolDrawableCellViewHolder(parent, R.drawable.ic_male, R.drawable.ic_female), + COLUMN_INDEX_GENDER_MALE), + new ColumnDefinition<>("Mood 4", r -> r.mMoodHappy, + parent -> TableViewAdapter.createBoolDrawableCellViewHolder(parent, R.drawable.ic_happy ,R.drawable.ic_sad), + COLUMN_INDEX_MOOD_HAPPY) + )); + + // column 5..500 contain generic text + for (int i = 5; i < COLUMN_SIZE;i++) { + final int columnNumber = i; + boolean large = new Random().nextBoolean(); + definitions.add(new ColumnDefinition<>( + (large ? "Lage Column " : "Column ") + i, + r -> r.getColumnValue(columnNumber))); + } + return definitions; + } + +} diff --git a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/model/MySamplePojo.java b/app/src/main/java/com/evrencoskun/tableviewsample/tableview/model/MySamplePojo.java new file mode 100644 index 00000000..24896d59 --- /dev/null +++ b/app/src/main/java/com/evrencoskun/tableviewsample/tableview/model/MySamplePojo.java @@ -0,0 +1,87 @@ +/* + * MIT License + * + * Copyright (c) 2023 k3b + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.evrencoskun.tableviewsample.tableview.model; + +import static java.lang.Math.abs; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.evrencoskun.tableview.model.IModelWithId; +import com.evrencoskun.tableview.sort.ISortableModel; + +import java.util.Random; + +/** + * An example Pojo that is displayed in demo app-s tableview. + */ +public class MySamplePojo implements IModelWithId { + + public final Integer mRandom; + public final Integer mRandomShort; + @NonNull + private final String mId; + @NonNull + public final String mText; + public final boolean mGenderMale; + public final boolean mMoodHappy; + + /** + * Create an item that will be displayed in the TableView. + * the "column-values" are random generated. + */ + public MySamplePojo(@NonNull String id) { + this.mId = id; + this.mText = getColumnValue(1); + mGenderMale = new Random().nextBoolean(); + mMoodHappy = new Random().nextBoolean(); + mRandom = abs(new Random().nextInt()); + mRandomShort = mRandom % 100; + } + + public String getColumnValue(int columnNumber) { + return "cell " + mId + " " + columnNumber; + } + /** + * This is necessary for sorting process. Id must be unique per data row. + * See {@link ISortableModel}. + */ + @NonNull + @Override + public String getId() { + return mId; + } + + @Override + public String toString() { + return "MySamplePojo{" + + "Id='" + mId + '\'' + + ", Random=" + mRandom + + ", RandomShort=" + mRandomShort + + ", GenderMale=" + mGenderMale + + ", MoodHappy=" + mMoodHappy + + '}'; + } +} diff --git a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/popup/ColumnHeaderLongPressPopup.java b/app/src/main/java/com/evrencoskun/tableviewsample/tableview/popup/ColumnHeaderLongPressPopup.java index e9865e97..5b93848e 100644 --- a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/popup/ColumnHeaderLongPressPopup.java +++ b/app/src/main/java/com/evrencoskun/tableviewsample/tableview/popup/ColumnHeaderLongPressPopup.java @@ -34,7 +34,7 @@ import com.evrencoskun.tableview.TableView; import com.evrencoskun.tableview.sort.SortState; import com.evrencoskun.tableviewsample.R; -import com.evrencoskun.tableviewsample.tableview.holder.ColumnHeaderViewHolder; +import com.evrencoskun.tableviewutil.holder.ColumnHeaderViewHolder; /** * Created by evrencoskun on 24.12.2017. @@ -52,11 +52,13 @@ public class ColumnHeaderLongPressPopup extends PopupMenu implements PopupMenu @NonNull private final TableView mTableView; private final int mXPosition; + private final int column; - public ColumnHeaderLongPressPopup(@NonNull ColumnHeaderViewHolder viewHolder, @NonNull TableView tableView) { + public ColumnHeaderLongPressPopup(@NonNull ColumnHeaderViewHolder viewHolder, @NonNull TableView tableView, int column) { super(viewHolder.itemView.getContext(), viewHolder.itemView); this.mTableView = tableView; this.mXPosition = viewHolder.getBindingAdapterPosition(); + this.column = column; initialize(); } @@ -107,10 +109,10 @@ public boolean onMenuItemClick(MenuItem menuItem) { mTableView.sortColumn(mXPosition, SortState.DESCENDING); break; case HIDE_ROW: - mTableView.hideRow(5); + mTableView.hideRow(3); break; case SHOW_ROW: - mTableView.showRow(5); + mTableView.showRow(3); break; case SCROLL_ROW: mTableView.scrollToRowPosition(5); diff --git a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/popup/RowHeaderLongPressPopup.java b/app/src/main/java/com/evrencoskun/tableviewsample/tableview/popup/RowHeaderLongPressPopup.java index 609c4a1e..bcba1c93 100644 --- a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/popup/RowHeaderLongPressPopup.java +++ b/app/src/main/java/com/evrencoskun/tableviewsample/tableview/popup/RowHeaderLongPressPopup.java @@ -50,12 +50,14 @@ public class RowHeaderLongPressPopup extends PopupMenu implements PopupMenu @NonNull private final TableView mTableView; private final int mRowPosition; + private final int row; - public RowHeaderLongPressPopup(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull TableView tableView) { + public RowHeaderLongPressPopup(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull TableView tableView, int row) { super(viewHolder.itemView.getContext(), viewHolder.itemView); this.mTableView = tableView; this.mRowPosition = viewHolder.getBindingAdapterPosition(); + this.row = row; initialize(); } diff --git a/changelog.md b/changelog.md new file mode 100644 index 00000000..96ef9901 --- /dev/null +++ b/changelog.md @@ -0,0 +1,109 @@ +changelog.md + +TableView is a powerful and beatifull looking Android library for displaying complex +data structures and rendering tabular data composed of rows, columns and cells. + +The current implementation at https://github.com/evrencoskun/TableView +requires a lot of copy&paste from example code to use the TableView in a clientapp. + +Product vision: reduce the amount of (copied) code to integrate TableView into a clientapp. + +* all app specific data comes from tableview independent POJOs (i.e. `List from TestData.createSampleData()`) +* all info how the POJO is displayed in the tableview comes from ColumnDefinition (i.e. `List>` from `TestData.createColumnDefinitions()`) +* no more need to implement app-specific XxxViewHolder, XxxModell for Cell, Column, RowHeader +* no more need to implement app-specific TableViewAdapter, TableViewModel +* no more need to define app specific layout for table_view_Xxx_layout.xml for Cell, Column, RowHeader +* Instead of the app-specific classes/layouts (mentioned in "no more need") there are generic, app-independant in the new modul tableviewutil. +* For legacy apps the tableview lib can be used as before. + +## Additional Requirements + +* java-8 lamda expressions to define column values and custom cell-view(-holders). See createColumnDefinitions() in TestData.java + +# Some differences between old and new style app that uses tableview + +### old style: + +build.gradle dependencies: + + implementation "com.evrencoskun.library:tableview:$tableview_version" + +Mainfragment.java + + private void initializeTableView(TableView tableView){ + // Create TableView Adapter + mTableAdapter = new MyTableAdapter(getContext()); + tableView.setAdapter(mTableAdapter); + + // Create listener + tableView.setTableViewListener(new MyTableViewListener(tableView)); + } + +Define app specific classes and resources + +* MainFragment.java +* MainActivity.java +* MainViewModel.java +* MyTableViewModel.java +* ColumnHeaderViewHolder.java +* MyTableAdapter.java +* CellModel.java +* RowHeaderViewHolder.java +* MyTableViewListener.java +* ColumnHeaderModel.java +* GenderCellViewHolder.java +* MoneyCellViewHolder.java +* RowHeaderModel.java +* CellViewHolder.java + +* ic_down.xml +* ic_up.xml +* activity_main.xml +* fragment_main.xml +* tableview_cell_layout.xml +* tableview_column_header_layout.xml +* tableview_corner_layout.xml +* tableview_gender_cell_layout.xml +* tableview_money_cell_layout.xml +* tableview_row_header_layout.xml + +### new style: + +build.gradle dependencies: + + implementation "com.evrencoskun.library:tableview:$tableview_version" + implementation "com.evrencoskun.library:tableviewutil:$tableview_version" + +Mainfragment.java + + private void initializeTableView(TableView tableView){ + List> columnDefinitions = TestData.createColumnDefinitions(); + List pojos = TestData.createSampleData(); + // Create TableView View model class to group view models of TableView + TableViewModel tableViewModel = new TableViewModel(columnDefinitions, pojos); + + // Create TableView Adapter + TableViewAdapter tableViewAdapter = new TableViewAdapter<>(columnDefinitions); + + tableView.setAdapter(tableViewAdapter); + tableView.setTableViewListener(new MyTableViewListener(tableView)); + + // Create an instance of a Filter and pass the TableView. + //mTableFilter = new Filter(tableView); + + // Load the dummy data to the TableView + tableViewAdapter.setAllItems(tableViewModel.getColumnHeaderList(), tableViewModel + .getRowHeaderList(), tableViewModel.getCellList()); + + } + +Define app specific classes and resources + +* MySamplePojo.java +* MyTableViewListener.java +* TestData.java +* MainActivity.java +* MainFragment.java + +* activity_main.xml +* fragment_main.xml diff --git a/settings.gradle b/settings.gradle index a9454f81..bc3a7820 100644 --- a/settings.gradle +++ b/settings.gradle @@ -23,3 +23,4 @@ */ include ':app', ':tableview' +include ':tableviewutil' diff --git a/tableview/src/androidTest/java/com/evrencoskun/tableview/test/data/SimpleData.java b/tableview/src/androidTest/java/com/evrencoskun/tableview/test/data/SimpleData.java index 991694a2..00c9bbb0 100644 --- a/tableview/src/androidTest/java/com/evrencoskun/tableview/test/data/SimpleData.java +++ b/tableview/src/androidTest/java/com/evrencoskun/tableview/test/data/SimpleData.java @@ -57,7 +57,7 @@ private void init(int columnSize, int rowSize) { cells = new ArrayList<>(); for (int i = 0; i < rowSize; i++) { - ArrayList cellList = new ArrayList<>(); + List cellList = new ArrayList<>(); for (int j = 0; j < columnSize; j++) { String id = j + ":" + i; cellList.add(new Cell(id, "r:" + i + "c:" + j)); diff --git a/tableview/src/main/java/com/evrencoskun/tableview/TableView.java b/tableview/src/main/java/com/evrencoskun/tableview/TableView.java index 9cdfd9fa..2dc8a119 100644 --- a/tableview/src/main/java/com/evrencoskun/tableview/TableView.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/TableView.java @@ -54,6 +54,7 @@ import com.evrencoskun.tableview.listener.scroll.HorizontalRecyclerViewListener; import com.evrencoskun.tableview.listener.scroll.VerticalRecyclerViewListener; import com.evrencoskun.tableview.preference.SavedState; +import com.evrencoskun.tableview.sort.ISortableModel; import com.evrencoskun.tableview.sort.SortState; import androidx.annotation.AttrRes; @@ -240,9 +241,9 @@ private void initialDefaultValues(@Nullable AttributeSet attrs) { public void initialize() { // Create Views - mColumnHeaderRecyclerView = createColumnHeaderRecyclerView(); - mRowHeaderRecyclerView = createRowHeaderRecyclerView(); - mCellRecyclerView = createCellRecyclerView(); + if (mColumnHeaderRecyclerView == null) mColumnHeaderRecyclerView = createColumnHeaderRecyclerView(); + if (mRowHeaderRecyclerView == null) mRowHeaderRecyclerView = createRowHeaderRecyclerView(); + if (mCellRecyclerView == null) mCellRecyclerView = createCellRecyclerView(); // Set some Id to help in identification mColumnHeaderRecyclerView.setId(R.id.ColumnHeaderRecyclerView); @@ -255,11 +256,11 @@ public void initialize() { addView(mCellRecyclerView); // Create Handlers - mSelectionHandler = new SelectionHandler(this); - mVisibilityHandler = new VisibilityHandler(this); - mScrollHandler = new ScrollHandler(this); - mPreferencesHandler = new PreferencesHandler(this); - mColumnWidthHandler = new ColumnWidthHandler(this); + if (mSelectionHandler == null) mSelectionHandler = new SelectionHandler(this); + if (mVisibilityHandler == null) mVisibilityHandler = new VisibilityHandler(this); + if (mScrollHandler == null) mScrollHandler = new ScrollHandler(this); + if (mPreferencesHandler == null) mPreferencesHandler = new PreferencesHandler(this); + if (mColumnWidthHandler == null) mColumnWidthHandler = new ColumnWidthHandler(this); initializeListeners(); } @@ -396,7 +397,7 @@ protected CellRecyclerView createCellRecyclerView() { return recyclerView; } - public void setAdapter(@Nullable AbstractTableAdapter tableAdapter) { + public void setAdapter(@Nullable AbstractTableAdapter tableAdapter) { if (tableAdapter != null) { this.mTableAdapter = tableAdapter; this.mTableAdapter.setRowHeaderWidth(mRowHeaderWidth); diff --git a/tableview/src/main/java/com/evrencoskun/tableview/adapter/AbstractTableAdapter.java b/tableview/src/main/java/com/evrencoskun/tableview/adapter/AbstractTableAdapter.java index 9f9e93c9..45ef6354 100644 --- a/tableview/src/main/java/com/evrencoskun/tableview/adapter/AbstractTableAdapter.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/adapter/AbstractTableAdapter.java @@ -25,6 +25,7 @@ package com.evrencoskun.tableview.adapter; import android.content.Context; +import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; @@ -36,6 +37,7 @@ import com.evrencoskun.tableview.adapter.recyclerview.CellRecyclerViewAdapter; import com.evrencoskun.tableview.adapter.recyclerview.ColumnHeaderRecyclerViewAdapter; import com.evrencoskun.tableview.adapter.recyclerview.RowHeaderRecyclerViewAdapter; +import com.evrencoskun.tableview.sort.ISortableModel; import java.util.ArrayList; import java.util.List; @@ -44,14 +46,15 @@ * Created by evrencoskun on 10/06/2017. */ -public abstract class AbstractTableAdapter implements ITableAdapter { +public abstract class AbstractTableAdapter implements ITableAdapter { + private final String tag = getClass().getSimpleName(); private int mRowHeaderWidth; private int mColumnHeaderHeight; private ColumnHeaderRecyclerViewAdapter mColumnHeaderRecyclerViewAdapter; private RowHeaderRecyclerViewAdapter mRowHeaderRecyclerViewAdapter; - private CellRecyclerViewAdapter mCellRecyclerViewAdapter; + private CellRecyclerViewAdapter mCellRecyclerViewAdapter; private View mCornerView; protected List mColumnHeaderItems; @@ -186,6 +189,7 @@ public int getRowHeaderItemViewType(int position) { return 0; } + /** Translates columnNumber to CellItemViewType */ @Override public int getCellItemViewType(int position) { return 0; @@ -205,7 +209,7 @@ public RowHeaderRecyclerViewAdapter getRowHeaderRecyclerViewAdapter() { return mRowHeaderRecyclerViewAdapter; } - public CellRecyclerViewAdapter getCellRecyclerViewAdapter() { + public CellRecyclerViewAdapter getCellRecyclerViewAdapter() { return mCellRecyclerViewAdapter; } @@ -223,37 +227,70 @@ public void setColumnHeaderHeight(int columnHeaderHeight) { } @Nullable - public CH getColumnHeaderItem(int position) { - if ((mColumnHeaderItems == null || mColumnHeaderItems.isEmpty()) || position < 0 || - position >= mColumnHeaderItems.size()) { + public CH getColumnHeaderItem(int columnPosition) { + int size = (mColumnHeaderItems == null) ? 0 : mColumnHeaderItems.size(); + if (columnPosition < 0 || columnPosition >= size) { + Log.i(tag,"getColumnHeaderItem(col=" + columnPosition + + ") : Illegal columnPosition allowed 0 .. " + size); return null; } - return mColumnHeaderItems.get(position); + return mColumnHeaderItems.get(columnPosition); } @Nullable - public RH getRowHeaderItem(int position) { - if ((mRowHeaderItems == null || mRowHeaderItems.isEmpty()) || position < 0 || position >= - mRowHeaderItems.size()) { + public RH getRowHeaderItem(int rowPosition) { + int size = (mRowHeaderItems == null) ? 0 : mRowHeaderItems.size(); + if (rowPosition < 0 || rowPosition >= size) { + Log.i(tag,"getRowHeaderItem(row=" + rowPosition + + ") : Illegal rowPosition allowed 0 .. " + size); + return null; } - return mRowHeaderItems.get(position); + return mRowHeaderItems.get(rowPosition); } + /** + * gets data from model column/row (and not from visibile column/row + * that may not match current filter/sorting) + * @param columnPosition + * @param rowPosition + */ + @Deprecated @Nullable public C getCellItem(int columnPosition, int rowPosition) { - if ((mCellItems == null || mCellItems.isEmpty()) || columnPosition < 0 || rowPosition >= - mCellItems.size() || mCellItems.get(rowPosition) == null || rowPosition < 0 || - columnPosition >= mCellItems.get(rowPosition).size()) { + List row = getRowFromModel(rowPosition); + if (row == null) { return null; } + int size = row.size(); + if (columnPosition < 0 || columnPosition >= size) { + Log.i(tag,"getCellItem(col=" + columnPosition + + ", row=" + rowPosition + + ") : Illegal columnPosition allowed 0 .. " + size); + return null; + } + return row.get(columnPosition); + } - return mCellItems.get(rowPosition).get(columnPosition); + /** + * gets data from model row (and not from visibile row + * that may not match current filter/sorting) + * @param rowPosition + */ + @Deprecated + private List getRowFromModel(int rowPosition) { + int size = (mCellItems == null) ? 0 : mCellItems.size(); + if (rowPosition < 0 || rowPosition >= size) { + Log.i(tag,"getCellItems(row=" + rowPosition + + ") : Illegal rowPosition allowed 0 .. " + size); + return null; + } + return mCellItems.get(rowPosition); } @Nullable public List getCellRowItems(int rowPosition) { - return (List) mCellRecyclerViewAdapter.getItem(rowPosition); + return mCellRecyclerViewAdapter.getItem(rowPosition); } public void removeRow(int rowPosition) { @@ -316,7 +353,7 @@ public void changeRowHeaderItemRange(int rowPositionStart, @Nullable List ro } public void changeCellItem(int columnPosition, int rowPosition, C cellModel) { - List cellItems = (List) mCellRecyclerViewAdapter.getItem(rowPosition); + List cellItems = mCellRecyclerViewAdapter.getItem(rowPosition); if (cellItems != null && cellItems.size() > columnPosition) { // Update cell row items. cellItems.set(columnPosition, cellModel); @@ -334,9 +371,12 @@ public void changeColumnHeaderRange(int columnPositionStart, @Nullable List columnHeaderModelList); } + /** + * This method helps to get cell item model that is located on given vertical column position. + */ @NonNull - public List getCellColumnItems(int columnPosition) { - return mCellRecyclerViewAdapter.getColumnItems(columnPosition); + public List getVerticalItemsAtColumn(int columnPosition) { + return mCellRecyclerViewAdapter.getVerticalItemsAtColumn(columnPosition); } public void removeColumn(int columnPosition) { diff --git a/tableview/src/main/java/com/evrencoskun/tableview/adapter/ITableAdapter.java b/tableview/src/main/java/com/evrencoskun/tableview/adapter/ITableAdapter.java index 70f677df..f6475eef 100644 --- a/tableview/src/main/java/com/evrencoskun/tableview/adapter/ITableAdapter.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/adapter/ITableAdapter.java @@ -32,12 +32,13 @@ import com.evrencoskun.tableview.ITableView; import com.evrencoskun.tableview.adapter.recyclerview.holder.AbstractViewHolder; +import com.evrencoskun.tableview.sort.ISortableModel; /** * Created by evrencoskun on 10/06/2017. */ -public interface ITableAdapter { +public interface ITableAdapter { int getColumnHeaderItemViewType(int position); diff --git a/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/AbstractRecyclerViewAdapter.java b/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/AbstractRecyclerViewAdapter.java index a3b38544..c7241632 100644 --- a/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/AbstractRecyclerViewAdapter.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/AbstractRecyclerViewAdapter.java @@ -73,9 +73,7 @@ public List getItems() { } public void setItems(@NonNull List itemList) { - mItemList = new ArrayList<>(itemList); - - this.notifyDataSetChanged(); + setItems(itemList, true); } public void setItems(@NonNull List itemList, boolean notifyDataSet) { diff --git a/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/CellRecyclerViewAdapter.java b/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/CellRecyclerViewAdapter.java index 8afa8ef9..7c4f4b42 100644 --- a/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/CellRecyclerViewAdapter.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/CellRecyclerViewAdapter.java @@ -46,9 +46,11 @@ /** * Created by evrencoskun on 10/06/2017. + * + * The adapter contains a List of IRow-s of Cells */ -public class CellRecyclerViewAdapter extends AbstractRecyclerViewAdapter { +public class CellRecyclerViewAdapter extends AbstractRecyclerViewAdapter> { @NonNull private final ITableView mTableView; @@ -58,7 +60,7 @@ public class CellRecyclerViewAdapter extends AbstractRecyclerViewAdapter { // This is for testing purpose private int mRecyclerViewId = 0; - public CellRecyclerViewAdapter(@NonNull Context context, @Nullable List itemList, @NonNull ITableView tableView) { + public CellRecyclerViewAdapter(@NonNull Context context, @Nullable List> itemList, @NonNull ITableView tableView) { super(context, itemList); this.mTableView = tableView; @@ -120,13 +122,13 @@ public void onBindViewHolder(@NonNull AbstractViewHolder holder, int yPosition) .recyclerView.getAdapter(); // Get the list - List rowList = (List) mItemList.get(yPosition); + List row = mItemList.get(yPosition); // Set Row position viewAdapter.setYPosition(yPosition); // Set the list to the adapter - viewAdapter.setItems(rowList); + viewAdapter.setItems(row); } @Override @@ -212,23 +214,23 @@ public void notifyCellDataSetChanged() { } /** - * This method helps to get cell item model that is located on given column position. + * This method helps to get cell item model that is located on given vertical column position. * * @param columnPosition */ @NonNull - public List getColumnItems(int columnPosition) { - List cellItems = new ArrayList<>(); + public List getVerticalItemsAtColumn(int columnPosition) { + List columnItems = new ArrayList<>(); for (int i = 0; i < mItemList.size(); i++) { - List rowList = (List) mItemList.get(i); + List row = mItemList.get(i); - if (rowList.size() > columnPosition) { - cellItems.add(rowList.get(columnPosition)); + if (row.size() > columnPosition) { + columnItems.add(row.get(columnPosition)); } } - return cellItems; + return columnItems; } @@ -252,7 +254,7 @@ public void removeColumnItems(int column) { // Create a new list which the column is already removed. List> cellItems = new ArrayList<>(); for (int i = 0; i < mItemList.size(); i++) { - List rowList = new ArrayList<>((List) mItemList.get(i)); + List rowList = new ArrayList<>(mItemList.get(i)); if (rowList.size() > column) { rowList.remove(column); @@ -262,7 +264,7 @@ public void removeColumnItems(int column) { } // Change data without notifying. Because we already did for visible recyclerViews. - setItems((List) cellItems, false); + setItems(cellItems, false); } public void addColumnItems(int column, @NonNull List cellColumnItems) { @@ -288,7 +290,7 @@ public void addColumnItems(int column, @NonNull List cellColumnItems) { // Lets change the model list silently List> cellItems = new ArrayList<>(); for (int i = 0; i < mItemList.size(); i++) { - List rowList = new ArrayList<>((List) mItemList.get(i)); + List rowList = new ArrayList<>(mItemList.get(i)); if (rowList.size() > column) { rowList.add(column, cellColumnItems.get(i)); @@ -298,6 +300,6 @@ public void addColumnItems(int column, @NonNull List cellColumnItems) { } // Change data without notifying. Because we already did for visible recyclerViews. - setItems((List) cellItems, false); + setItems(cellItems, false); } } diff --git a/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/CellRowRecyclerViewAdapter.java b/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/CellRowRecyclerViewAdapter.java index 65b0f5c5..bb47eb9d 100644 --- a/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/CellRowRecyclerViewAdapter.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/CellRowRecyclerViewAdapter.java @@ -33,12 +33,14 @@ import com.evrencoskun.tableview.adapter.ITableAdapter; import com.evrencoskun.tableview.adapter.recyclerview.holder.AbstractViewHolder; import com.evrencoskun.tableview.adapter.recyclerview.holder.AbstractViewHolder.SelectionState; +import com.evrencoskun.tableview.model.Cell; +import com.evrencoskun.tableview.sort.ISortableModel; /** * Created by evrencoskun on 10/06/2017. */ -public class CellRowRecyclerViewAdapter extends AbstractRecyclerViewAdapter { +public class CellRowRecyclerViewAdapter extends AbstractRecyclerViewAdapter { private int mYPosition; private final ITableAdapter mTableAdapter; @@ -73,7 +75,7 @@ public void setYPosition(int rowPosition) { @Override public int getItemViewType(int position) { - return mTableAdapter.getCellItemViewType(position); + return ((Cell) getItem(position)).getColumnType(); } @Override diff --git a/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/ColumnHeaderRecyclerViewAdapter.java b/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/ColumnHeaderRecyclerViewAdapter.java index d444debe..838c484b 100644 --- a/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/ColumnHeaderRecyclerViewAdapter.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/ColumnHeaderRecyclerViewAdapter.java @@ -50,8 +50,10 @@ public class ColumnHeaderRecyclerViewAdapter extends AbstractRecyclerViewAda private final ITableView mTableView; private ColumnSortHelper mColumnSortHelper; - public ColumnHeaderRecyclerViewAdapter(@NonNull Context context, @Nullable List itemList, @NonNull ITableAdapter - tableAdapter) { + public ColumnHeaderRecyclerViewAdapter( + @NonNull Context context, + @Nullable List itemList, + @NonNull ITableAdapter tableAdapter) { super(context, itemList); this.mTableAdapter = tableAdapter; this.mTableView = tableAdapter.getTableView(); diff --git a/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/holder/AbstractViewHolder.java b/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/holder/AbstractViewHolder.java index 7b202e40..4740019c 100644 --- a/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/holder/AbstractViewHolder.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/adapter/recyclerview/holder/AbstractViewHolder.java @@ -28,6 +28,7 @@ import androidx.annotation.ColorInt; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; /** @@ -35,6 +36,10 @@ */ public abstract class AbstractViewHolder extends RecyclerView.ViewHolder { + protected int mColumnPosition; + protected int mRowPosition; + @Nullable private Object mPojo; + public enum SelectionState {SELECTED, UNSELECTED, SHADOWED} // Default value @@ -74,4 +79,13 @@ public boolean onFailedToRecycleView() { return false; } + public void setCell(@Nullable Object content, int columnPosition, int rowPosition, @Nullable Object pojo) { + mColumnPosition = columnPosition; + mRowPosition = rowPosition; + this.mPojo = pojo; + } + public Object getPojo() { + return mPojo; + } + } diff --git a/tableview/src/main/java/com/evrencoskun/tableview/handler/ColumnSortHandler.java b/tableview/src/main/java/com/evrencoskun/tableview/handler/ColumnSortHandler.java index 35cfa243..bedfb7be 100644 --- a/tableview/src/main/java/com/evrencoskun/tableview/handler/ColumnSortHandler.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/handler/ColumnSortHandler.java @@ -52,7 +52,7 @@ public class ColumnSortHandler { - private final CellRecyclerViewAdapter> mCellRecyclerViewAdapter; + private final CellRecyclerViewAdapter mCellRecyclerViewAdapter; private final RowHeaderRecyclerViewAdapter mRowHeaderRecyclerViewAdapter; private final ColumnHeaderRecyclerViewAdapter mColumnHeaderRecyclerViewAdapter; @@ -68,7 +68,7 @@ public void setEnableAnimation(boolean mEnableAnimation) { } public ColumnSortHandler(@NonNull ITableView tableView) { - this.mCellRecyclerViewAdapter = (CellRecyclerViewAdapter>) tableView.getCellRecyclerView() + this.mCellRecyclerViewAdapter = (CellRecyclerViewAdapter) tableView.getCellRecyclerView() .getAdapter(); this.mRowHeaderRecyclerViewAdapter = (RowHeaderRecyclerViewAdapter) tableView diff --git a/tableview/src/main/java/com/evrencoskun/tableview/handler/FilterHandler.java b/tableview/src/main/java/com/evrencoskun/tableview/handler/FilterHandler.java index b331ed5e..82771ac8 100644 --- a/tableview/src/main/java/com/evrencoskun/tableview/handler/FilterHandler.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/handler/FilterHandler.java @@ -41,7 +41,7 @@ public class FilterHandler { - private final CellRecyclerViewAdapter> mCellRecyclerViewAdapter; + private final CellRecyclerViewAdapter mCellRecyclerViewAdapter; private final RowHeaderRecyclerViewAdapter mRowHeaderRecyclerViewAdapter; private List> originalCellDataStore; private List originalRowDataStore; @@ -50,7 +50,7 @@ public class FilterHandler { public FilterHandler(@NonNull ITableView tableView) { tableView.getAdapter().addAdapterDataSetChangedListener(adapterDataSetChangedListener); - this.mCellRecyclerViewAdapter = (CellRecyclerViewAdapter>) tableView + this.mCellRecyclerViewAdapter = (CellRecyclerViewAdapter) tableView .getCellRecyclerView().getAdapter(); this.mRowHeaderRecyclerViewAdapter = (RowHeaderRecyclerViewAdapter) tableView diff --git a/tableview/src/main/java/com/evrencoskun/tableview/handler/VisibilityHandler.java b/tableview/src/main/java/com/evrencoskun/tableview/handler/VisibilityHandler.java index 61a7908a..49a46a4a 100644 --- a/tableview/src/main/java/com/evrencoskun/tableview/handler/VisibilityHandler.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/handler/VisibilityHandler.java @@ -32,6 +32,7 @@ import com.evrencoskun.tableview.ITableView; import com.evrencoskun.tableview.adapter.AbstractTableAdapter; + import java.util.List; /** @@ -44,7 +45,10 @@ public class VisibilityHandler { @NonNull private final ITableView mTableView; @NonNull + /** Remember all existing rows that are currently hidden */ private SparseArray mHideRowList = new SparseArray<>(); + + /** Remember all existing columns that are currently hidden */ @NonNull private SparseArray mHideColumnList = new SparseArray<>(); @@ -127,7 +131,7 @@ private void showColumn(int column, boolean removeFromList) { if (hiddenColumn != null) { // add column model to the adapter mTableView.getAdapter().addColumn(column, hiddenColumn.getColumnHeaderModel(), - hiddenColumn.getCellModelList()); + (List) hiddenColumn.getCellModelList()); } else { Log.e(LOG_TAG, "This column is already visible."); } @@ -236,7 +240,6 @@ public Object getColumnHeaderModel() { public List getCellModelList() { return mCellModelList; } - } @NonNull @@ -252,9 +255,9 @@ private Row getRowValueFromPosition(int row) { private Column getColumnValueFromPosition(int column) { AbstractTableAdapter adapter = mTableView.getAdapter(); Object columnHeaderModel = adapter.getColumnHeaderItem(column); - List cellModelList = adapter.getCellColumnItems(column); + List verticalItemsAtColumn = adapter.getVerticalItemsAtColumn(column); - return new Column(column, columnHeaderModel, cellModelList); + return new Column(column, columnHeaderModel, verticalItemsAtColumn); } @NonNull diff --git a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/model/Cell.java b/tableview/src/main/java/com/evrencoskun/tableview/model/Cell.java similarity index 63% rename from app/src/main/java/com/evrencoskun/tableviewsample/tableview/model/Cell.java rename to tableview/src/main/java/com/evrencoskun/tableview/model/Cell.java index 258c560a..3abaef61 100644 --- a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/model/Cell.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/model/Cell.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package com.evrencoskun.tableviewsample.tableview.model; +package com.evrencoskun.tableview.model; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -34,48 +34,54 @@ * Created by evrencoskun on 11/06/2017. */ -public class Cell implements ISortableModel, IFilterableModel { +public class Cell implements ISortableModel, IFilterableModel { @NonNull - private final String mId; - @Nullable - private final Object mData; - @NonNull - private final String mFilterKeyword; + private final POJO mData; + private final ColumnDefinition columnDefinition; - public Cell(@NonNull String id, @Nullable Object data) { - this.mId = id; + /** + * @param data the row where the cell data belongs to. + * @param columnDefinition defines mapping from pojo to content and optional viewHolderId for non standard viewholders + */ + public Cell(@NonNull POJO data, ColumnDefinition columnDefinition) { this.mData = data; - this.mFilterKeyword = String.valueOf(data); + this.columnDefinition = columnDefinition; } /** - * This is necessary for sorting process. - * See ISortableModel + * This is necessary for sorting process. Id must be unique per data row. + * See {@link ISortableModel}. */ @NonNull @Override public String getId() { - return mId; + return mData.getId(); } /** * This is necessary for sorting process. - * See ISortableModel + * See {@link ISortableModel}. */ @Nullable @Override public Object getContent() { - return mData; + return columnDefinition.getPojoToCellValueProvider().get(mData); } + public int getColumnType() { + return columnDefinition.getColumnType(); + } @Nullable - public Object getData() { + public POJO getData() { return mData; } + /** + * See {@link IFilterableModel}. + */ @NonNull @Override public String getFilterableKeyword() { - return mFilterKeyword; + return getContent().toString(); } } diff --git a/tableview/src/main/java/com/evrencoskun/tableview/model/ColumnDefinition.java b/tableview/src/main/java/com/evrencoskun/tableview/model/ColumnDefinition.java new file mode 100644 index 00000000..a3eabe1b --- /dev/null +++ b/tableview/src/main/java/com/evrencoskun/tableview/model/ColumnDefinition.java @@ -0,0 +1,100 @@ +/* + * MIT License + * + * Copyright (c) 2023 K3b + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.evrencoskun.tableview.model; + +import android.util.SparseArray; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.evrencoskun.tableview.model.IColumnValueProvider; +import com.evrencoskun.tableview.model.IViewHolderFactory; + +/** + * All informations needed to define a Table + * @param + */ +public class ColumnDefinition { + public static final int COLUMN_TYPE_GENERIC = 9999; + @NonNull private final String columnHeaderText; + @NonNull private final IColumnValueProvider pojoToCellValueProvider; + @Nullable private final IViewHolderFactory viewHolderFactory; + + private final int columnType; + + private static SparseArray typId2ViewHolderFactory = new SparseArray<>(); + + /** + * Constructor + * @param columnHeaderText text to be displayed as column header + * @param pojoToCellValueProvider translates POJO to cell column Text + * @param viewHolderFactory creates view with viewholder for this column. null means default viewholder + * @param columnType id of the used viewHolderFactory (must be unique for each viewholder-type). COLUMN_TYPE_GENERIC means default viewholder + */ + public ColumnDefinition( + @NonNull String columnHeaderText, + @NonNull IColumnValueProvider pojoToCellValueProvider, + @Nullable IViewHolderFactory viewHolderFactory, + int columnType) { + this.columnHeaderText = columnHeaderText; + this.pojoToCellValueProvider = pojoToCellValueProvider; + this.viewHolderFactory = viewHolderFactory; + this.columnType = columnType; + if (columnType != COLUMN_TYPE_GENERIC) { + typId2ViewHolderFactory.append(columnType, viewHolderFactory); + } + } + + public ColumnDefinition( + @NonNull String columnHeaderText, + @NonNull IColumnValueProvider pojoToCellValueProvider) { + this(columnHeaderText,pojoToCellValueProvider,null, COLUMN_TYPE_GENERIC); + } + + /** text to be displayed as column header */ + @NonNull public String getColumnHeaderText() { + return columnHeaderText; + } + + /** translates POJO to cell column Text */ + @NonNull public IColumnValueProvider getPojoToCellValueProvider() { + return pojoToCellValueProvider; + } + + /** creates view with viewholder for this column. null means default viewholder */ + @Nullable public IViewHolderFactory getViewHolderFactory() { + return viewHolderFactory; + } + + @Override + public String toString() { + return "ColumnDefinition{" + + "columnHeaderText='" + columnHeaderText + '\'' + + '}'; + } + public int getColumnType() { + return columnType; + } +} diff --git a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/holder/MoodCellViewHolder.java b/tableview/src/main/java/com/evrencoskun/tableview/model/IColumnValueProvider.java similarity index 54% rename from app/src/main/java/com/evrencoskun/tableviewsample/tableview/holder/MoodCellViewHolder.java rename to tableview/src/main/java/com/evrencoskun/tableview/model/IColumnValueProvider.java index f48197da..d1ed5451 100644 --- a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/holder/MoodCellViewHolder.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/model/IColumnValueProvider.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2021 Evren Coşkun + * Copyright (c) 2023 K3b * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,34 +22,13 @@ * SOFTWARE. */ -package com.evrencoskun.tableviewsample.tableview.holder; - -import android.view.View; -import android.widget.ImageView; - -import androidx.annotation.NonNull; - -import com.evrencoskun.tableview.adapter.recyclerview.holder.AbstractViewHolder; -import com.evrencoskun.tableviewsample.R; -import com.evrencoskun.tableviewsample.tableview.TableViewModel; +package com.evrencoskun.tableview.model; /** - * Created by evrencoskun on 4.02.2018. + * Lamda support to translate POJO to column value object in a table cell. + * + * Example: pojo -> pojo.getName() */ - -public class MoodCellViewHolder extends AbstractViewHolder { - @NonNull - public final ImageView cell_image; - - public MoodCellViewHolder(@NonNull View itemView) { - super(itemView); - cell_image = itemView.findViewById(R.id.cell_image); - } - - public void setData(Object data) { - int mood = (int) data; - int moodDrawable = mood == TableViewModel.HAPPY ? R.drawable.ic_happy : R.drawable.ic_sad; - - cell_image.setImageResource(moodDrawable); - } -} \ No newline at end of file +public interface IColumnValueProvider { + Object get(POJO row); +} diff --git a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/model/ColumnHeader.java b/tableview/src/main/java/com/evrencoskun/tableview/model/IModelWithId.java similarity index 78% rename from app/src/main/java/com/evrencoskun/tableviewsample/tableview/model/ColumnHeader.java rename to tableview/src/main/java/com/evrencoskun/tableview/model/IModelWithId.java index 5fa19923..7b61ddb4 100644 --- a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/model/ColumnHeader.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/model/IModelWithId.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2021 Evren Coşkun + * Copyright (c) 2023 k3b * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,17 +22,15 @@ * SOFTWARE. */ -package com.evrencoskun.tableviewsample.tableview.model; +package com.evrencoskun.tableview.model; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -/** - * Created by evrencoskun on 11/06/2017. - */ - -public class ColumnHeader extends Cell { - public ColumnHeader(@NonNull String id, @Nullable String data) { - super(id, data); - } +/** All POJO-items in TableView must implement this */ +public interface IModelWithId { + /** + * to make sorting work, Id must be unique per data row. + */ + @NonNull + String getId(); } diff --git a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/holder/GenderCellViewHolder.java b/tableview/src/main/java/com/evrencoskun/tableview/model/IViewHolderFactory.java similarity index 61% rename from app/src/main/java/com/evrencoskun/tableviewsample/tableview/holder/GenderCellViewHolder.java rename to tableview/src/main/java/com/evrencoskun/tableview/model/IViewHolderFactory.java index d56d4246..ea1137b8 100644 --- a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/holder/GenderCellViewHolder.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/model/IViewHolderFactory.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2021 Evren Coşkun + * Copyright (c) 2023 K3b * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,30 +22,15 @@ * SOFTWARE. */ -package com.evrencoskun.tableviewsample.tableview.holder; +package com.evrencoskun.tableview.model; -import android.view.View; +import android.view.ViewGroup; -import androidx.annotation.NonNull; - -import com.evrencoskun.tableviewsample.R; -import com.evrencoskun.tableviewsample.tableview.TableViewModel; +import com.evrencoskun.tableview.adapter.recyclerview.holder.AbstractViewHolder; /** - * Created by evrencoskun on 4.02.2018. + * Lamda Support to create a factory that creates a view with viewholder. */ - -public class GenderCellViewHolder extends MoodCellViewHolder { - - public GenderCellViewHolder(@NonNull View itemView) { - super(itemView); - } - - @Override - public void setData(Object data) { - int gender = (int) data; - int genderDrawable = gender == TableViewModel.BOY ? R.drawable.ic_male : R.drawable.ic_female; - - cell_image.setImageResource(genderDrawable); - } +public interface IViewHolderFactory { + AbstractViewHolder createViewHolder(ViewGroup parent); } diff --git a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/model/RowHeader.java b/tableview/src/main/java/com/evrencoskun/tableview/model/RowHeader.java similarity index 82% rename from app/src/main/java/com/evrencoskun/tableviewsample/tableview/model/RowHeader.java rename to tableview/src/main/java/com/evrencoskun/tableview/model/RowHeader.java index 1180fdb4..91a1988b 100644 --- a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/model/RowHeader.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/model/RowHeader.java @@ -22,17 +22,21 @@ * SOFTWARE. */ -package com.evrencoskun.tableviewsample.tableview.model; +package com.evrencoskun.tableview.model; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; /** * Created by evrencoskun on 11/06/2017. */ -public class RowHeader extends Cell { - public RowHeader(@NonNull String id, @Nullable String data) { - super(id, data); +public class RowHeader extends Cell { + public RowHeader(@NonNull POJO data) { + super(data, null); + } + + @Override + public Object getContent() { + return getId(); } } diff --git a/tableview/src/main/java/com/evrencoskun/tableview/pagination/Pagination.java b/tableview/src/main/java/com/evrencoskun/tableview/pagination/Pagination.java index 343a92ce..44e8cc43 100644 --- a/tableview/src/main/java/com/evrencoskun/tableview/pagination/Pagination.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/pagination/Pagination.java @@ -57,7 +57,7 @@ public class Pagination implements IPagination { @Nullable private RowHeaderRecyclerViewAdapter mRowHeaderRecyclerViewAdapter; @Nullable - private CellRecyclerViewAdapter> mCellRecyclerViewAdapter; + private CellRecyclerViewAdapter mCellRecyclerViewAdapter; @Nullable private OnTableViewPageTurnedListener onTableViewPageTurnedListener; diff --git a/tableview/src/main/java/com/evrencoskun/tableview/sort/ISortableModel.java b/tableview/src/main/java/com/evrencoskun/tableview/sort/ISortableModel.java index 2b62ab07..0c106fbb 100644 --- a/tableview/src/main/java/com/evrencoskun/tableview/sort/ISortableModel.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/sort/ISortableModel.java @@ -24,16 +24,15 @@ package com.evrencoskun.tableview.sort; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.evrencoskun.tableview.model.IModelWithId; + /** * Created by evrencoskun on 24.11.2017. */ -public interface ISortableModel { - @NonNull - String getId(); +public interface ISortableModel extends IModelWithId { @Nullable Object getContent(); diff --git a/tableview/src/main/java/com/evrencoskun/tableview/sort/RowHeaderForCellSortComparator.java b/tableview/src/main/java/com/evrencoskun/tableview/sort/RowHeaderForCellSortComparator.java index aa8495fa..4a6d8685 100644 --- a/tableview/src/main/java/com/evrencoskun/tableview/sort/RowHeaderForCellSortComparator.java +++ b/tableview/src/main/java/com/evrencoskun/tableview/sort/RowHeaderForCellSortComparator.java @@ -53,9 +53,11 @@ public RowHeaderForCellSortComparator(@NonNull List referenceLis } @Override - public int compare(List o, List t1) { - Object o1 = mReferenceList.get(this.mColumnList.indexOf(o)).getContent(); - Object o2 = mReferenceList.get(this.mColumnList.indexOf(t1)).getContent(); + public int compare(List l1, List l2) { + int colL1 = this.mColumnList.indexOf(l1); + int colL2 = this.mColumnList.indexOf(l2); + Object o1 = mReferenceList.get(colL1).getContent(); + Object o2 = mReferenceList.get(colL2).getContent(); if (mSortState == SortState.DESCENDING) { return mRowHeaderSortComparator.compareContent(o2, o1); } else { diff --git a/tableviewutil/.gitignore b/tableviewutil/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/tableviewutil/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/tableviewutil/build.gradle b/tableviewutil/build.gradle new file mode 100644 index 00000000..b4c8da4a --- /dev/null +++ b/tableviewutil/build.gradle @@ -0,0 +1,40 @@ +plugins { + id 'com.android.library' +} + +android { + namespace 'com.evrencoskun.tableviewutil' + compileSdkVersion compile_sdk_version + + defaultConfig { + minSdkVersion min_sdk_version + targetSdkVersion target_sdk_version + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility = java_version + targetCompatibility = java_version + } +} + +dependencies { + implementation project(path: ':tableview') + + implementation "androidx.appcompat:appcompat:$androidx_appcompat_version" + implementation "androidx.recyclerview:recyclerview:$androidx_recyclerview_version" + testImplementation "junit:junit:$junit_version" + androidTestImplementation "androidx.test.ext:junit:$androidx_test_ext_version" + androidTestImplementation "androidx.test:rules:$androidx_test_version" + androidTestImplementation "androidx.test:runner:$androidx_test_version" + androidTestImplementation "androidx.test.espresso:espresso-core:$androidx_test_espresso_version" + androidTestImplementation "androidx.test.espresso:espresso-contrib:$androidx_test_espresso_version" +} \ No newline at end of file diff --git a/tableviewutil/consumer-rules.pro b/tableviewutil/consumer-rules.pro new file mode 100644 index 00000000..e69de29b diff --git a/tableviewutil/proguard-rules.pro b/tableviewutil/proguard-rules.pro new file mode 100644 index 00000000..481bb434 --- /dev/null +++ b/tableviewutil/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/tableviewutil/src/main/AndroidManifest.xml b/tableviewutil/src/main/AndroidManifest.xml new file mode 100644 index 00000000..1cf554fa --- /dev/null +++ b/tableviewutil/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/TableViewAdapter.java b/tableviewutil/src/main/java/com/evrencoskun/tableviewutil/TableViewAdapter.java similarity index 59% rename from app/src/main/java/com/evrencoskun/tableviewsample/tableview/TableViewAdapter.java rename to tableviewutil/src/main/java/com/evrencoskun/tableviewutil/TableViewAdapter.java index 3954929b..8a6c4189 100644 --- a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/TableViewAdapter.java +++ b/tableviewutil/src/main/java/com/evrencoskun/tableviewutil/TableViewAdapter.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2021 Evren Coşkun + * Copyright (c) 2021 Evren Coşkun, 2023 k3b * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,50 +22,82 @@ * SOFTWARE. */ -package com.evrencoskun.tableviewsample.tableview; +package com.evrencoskun.tableviewutil; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.evrencoskun.tableview.adapter.AbstractTableAdapter; import com.evrencoskun.tableview.adapter.recyclerview.holder.AbstractViewHolder; +import com.evrencoskun.tableview.model.ColumnDefinition; +import com.evrencoskun.tableview.model.IModelWithId; +import com.evrencoskun.tableview.model.IViewHolderFactory; import com.evrencoskun.tableview.sort.SortState; -import com.evrencoskun.tableviewsample.R; -import com.evrencoskun.tableviewsample.tableview.holder.CellViewHolder; -import com.evrencoskun.tableviewsample.tableview.holder.ColumnHeaderViewHolder; -import com.evrencoskun.tableviewsample.tableview.holder.GenderCellViewHolder; -import com.evrencoskun.tableviewsample.tableview.holder.MoodCellViewHolder; -import com.evrencoskun.tableviewsample.tableview.holder.RowHeaderViewHolder; -import com.evrencoskun.tableviewsample.tableview.model.Cell; -import com.evrencoskun.tableviewsample.tableview.model.ColumnHeader; -import com.evrencoskun.tableviewsample.tableview.model.RowHeader; +import com.evrencoskun.tableviewutil.holder.BoolDrawableCellViewHolder; +import com.evrencoskun.tableviewutil.holder.ColumnHeaderViewHolder; +import com.evrencoskun.tableviewutil.holder.GenericTextCellViewHolder; +import com.evrencoskun.tableviewutil.holder.RowHeaderViewHolder; +import com.evrencoskun.tableview.model.Cell; +import com.evrencoskun.tableview.model.RowHeader; /** - * Created by evrencoskun on 11/06/2017. - *

- * This is a sample of custom TableView Adapter. + * Generic adapter that translates a POJO to TableView-Cells. + * + * Defaultimplementation translates all columns to TextView fields. */ +public class TableViewAdapter + extends AbstractTableAdapter, RowHeader, Cell> { -public class TableViewAdapter extends AbstractTableAdapter { + public TableViewAdapter() { + super(); + } - // Cell View Types by Column Position - private static final int MOOD_CELL_TYPE = 1; - private static final int GENDER_CELL_TYPE = 2; - // add new one if it necessary.. + /** + * This is where you create your custom Column Header ViewHolder. This method is called when + * Column Header RecyclerView of the TableView needs a new RecyclerView.ViewHolder of the given + * type to represent an item. + * + * @param viewholderTypeId : This value comes from "getColumnHeaderItemViewType" method to support + * different type of viewHolder as a Column Header item. + * @see #getColumnHeaderItemViewType(int); + */ + @NonNull + @Override + public AbstractViewHolder onCreateColumnHeaderViewHolder(@NonNull ViewGroup parent, int viewholderTypeId) { + View layout = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.table_view_column_header_layout, parent, false); - private static final String LOG_TAG = TableViewAdapter.class.getSimpleName(); + // Create a ColumnHeader ViewHolder + return new ColumnHeaderViewHolder(layout, getTableView()); - @NonNull - private final TableViewModel mTableViewModel; + } - public TableViewAdapter(@NonNull TableViewModel tableViewModel) { - super(); - this.mTableViewModel = tableViewModel; + /** + * That is where you set Column Header data to your custom Column Header ViewHolder. + * This method is Called by ColumnHeader RecyclerView of the TableView to display the data at + * the specified position. This method gives you everything you need about a column header + * item. + * + * @param holder : This is one of your column header ViewHolders that was created + * on ```onCreateColumnHeaderViewHolder``` method. In this example + * we have created "ColumnHeaderViewHolder" holder. + * @param columnHeader : This is the column header located on this X position. In this + * example, the header is ColumnDefinition.getColumnHeaderText(). + * @param columnPosition : This is the X (Column) position of the column header item. + * @see #onCreateColumnHeaderViewHolder(ViewGroup, int) ; + */ + @Override + public void onBindColumnHeaderViewHolder(@NonNull AbstractViewHolder holder, + @Nullable ColumnDefinition columnHeader, + int columnPosition) { + //!!! TODO + holder.setCell(columnHeader, columnPosition,-1, getColumnDefinition(columnPosition)); } /** @@ -73,120 +105,105 @@ public TableViewAdapter(@NonNull TableViewModel tableViewModel) { * RecyclerView of the TableView needs a new RecyclerView.ViewHolder of the given type to * represent an item. * - * @param viewType : This value comes from "getCellItemViewType" method to support different + * @param viewholderTypeId : This value comes from "getCellItemViewType" method to support different * type of viewHolder as a Cell item. * @see #getCellItemViewType(int); */ @NonNull @Override - public AbstractViewHolder onCreateCellViewHolder(@NonNull ViewGroup parent, int viewType) { - //TODO check - Log.e(LOG_TAG, " onCreateCellViewHolder has been called"); - LayoutInflater inflater = LayoutInflater.from(parent.getContext()); - View layout; - - switch (viewType) { - case MOOD_CELL_TYPE: - // Get image cell layout which has ImageView on the base instead of TextView. - layout = inflater.inflate(R.layout.table_view_image_cell_layout, parent, false); - - return new MoodCellViewHolder(layout); - case GENDER_CELL_TYPE: - // Get image cell layout which has ImageView instead of TextView. - layout = inflater.inflate(R.layout.table_view_image_cell_layout, parent, false); - - return new GenderCellViewHolder(layout); - default: - // For cells that display a text - layout = inflater.inflate(R.layout.table_view_cell_layout, parent, false); - - // Create a Cell ViewHolder - return new CellViewHolder(layout); - } + public AbstractViewHolder onCreateCellViewHolder(@NonNull ViewGroup parent, int viewholderTypeId) { + return getViewHolderFactoryById(viewholderTypeId, TableViewAdapter::createGenericTextCellViewHolder).createViewHolder(parent); } /** - * That is where you set Cell View Model data to your custom Cell ViewHolder. This method is - * Called by Cell RecyclerView of the TableView to display the data at the specified position. - * This method gives you everything you need about a cell item. + * Translates columnNumber to CellItemViewType (viewholderTypeId). * - * @param holder : This is one of your cell ViewHolders that was created on - * ```onCreateCellViewHolder``` method. In this example we have created - * "CellViewHolder" holder. - * @param cellItemModel : This is the cell view model located on this X and Y position. In this - * example, the model class is "Cell". - * @param columnPosition : This is the X (Column) position of the cell item. - * @param rowPosition : This is the Y (Row) position of the cell item. - * @see #onCreateCellViewHolder(ViewGroup, int) ; + * @return columnNumber or COLUMN_TYPE_GENERIC if there is no special CellItemViewType */ @Override - public void onBindCellViewHolder(@NonNull AbstractViewHolder holder, @Nullable Cell cellItemModel, int - columnPosition, int rowPosition) { + public int getCellItemViewType(int columnNumber) { + return getViewHolderTypeId(columnNumber,ColumnDefinition.COLUMN_TYPE_GENERIC); + } - switch (holder.getItemViewType()) { - case MOOD_CELL_TYPE: - MoodCellViewHolder moodViewHolder = (MoodCellViewHolder) holder; + private IViewHolderFactory getViewHolderFactoryById(int viewholderTypeId, @Nullable IViewHolderFactory notFoundValue) { + ColumnDefinition definition = getColumnDefinition(viewholderTypeId); + if (definition != null) { + IViewHolderFactory factory = definition.getViewHolderFactory(); + if (factory != null) { + return factory; + } + } + return notFoundValue; + } - moodViewHolder.cell_image.setImageResource(mTableViewModel.getDrawable((int) cellItemModel - .getData(), false)); - break; - case GENDER_CELL_TYPE: - GenderCellViewHolder genderViewHolder = (GenderCellViewHolder) holder; + private int getViewHolderTypeId(int column, @Nullable int notFoundValue) { + ColumnDefinition definition = getColumnDefinition(column); + if (definition != null) { + int id = definition.getColumnType(); + if (id != ColumnDefinition.COLUMN_TYPE_GENERIC) { + return id; + } + } + return notFoundValue; + } - genderViewHolder.cell_image.setImageResource(mTableViewModel.getDrawable((int) - cellItemModel.getData(), true)); - break; - default: - // Get the holder to update cell item text - CellViewHolder viewHolder = (CellViewHolder) holder; - viewHolder.setCell(cellItemModel); - break; + private ColumnDefinition getColumnDefinition(int column) { + if (mColumnHeaderItems != null && column >= 0 && column < mColumnHeaderItems.size()) { + return mColumnHeaderItems.get(column); } + return null; } /** - * This is where you create your custom Column Header ViewHolder. This method is called when - * Column Header RecyclerView of the TableView needs a new RecyclerView.ViewHolder of the given - * type to represent an item. + * For cells that display a text * - * @param viewType : This value comes from "getColumnHeaderItemViewType" method to support - * different type of viewHolder as a Column Header item. - * @see #getColumnHeaderItemViewType(int); + * @param parent where view and viewholder will be attached to + * @return viewholder for view attached to R.layout.table_view_cell_layout */ @NonNull - @Override - public AbstractViewHolder onCreateColumnHeaderViewHolder(@NonNull ViewGroup parent, int viewType) { - // TODO: check - //Log.e(LOG_TAG, " onCreateColumnHeaderViewHolder has been called"); - // Get Column Header xml Layout - View layout = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.table_view_column_header_layout, parent, false); + public static GenericTextCellViewHolder createGenericTextCellViewHolder(@NonNull ViewGroup parent) { + LayoutInflater inflater = LayoutInflater.from(parent.getContext()); - // Create a ColumnHeader ViewHolder - return new ColumnHeaderViewHolder(layout, getTableView()); + // For cells that display a text + View layout = inflater.inflate(R.layout.table_view_cell_layout, parent, false); + + // Create a Cell ViewHolder + return new GenericTextCellViewHolder(layout); } + // Get image cell layout which has ImageView on the base instead of TextView. + /** - * That is where you set Column Header View Model data to your custom Column Header ViewHolder. - * This method is Called by ColumnHeader RecyclerView of the TableView to display the data at - * the specified position. This method gives you everything you need about a column header - * item. + * For cells that display one of two images based on a boolean value + * @param parent where view and viewholder will be attached to + * @param idDrawableTrue icon id for the image that represents true. + * @param idDrawableFalse icon id for the image that represents false. + * @return viewholder for view attached to R.layout.table_view_image_cell_layout + */ + @NonNull public static AbstractViewHolder createBoolDrawableCellViewHolder(@NonNull ViewGroup parent, @DrawableRes int idDrawableTrue, @DrawableRes int idDrawableFalse) { + LayoutInflater inflater = LayoutInflater.from(parent.getContext()); + View layout = inflater.inflate(R.layout.table_view_image_cell_layout, parent, false); + return new BoolDrawableCellViewHolder(layout, idDrawableTrue, idDrawableFalse); + } + + /** + * That is where you set Cell View Model data to your custom Cell ViewHolder. This method is + * Called by Cell RecyclerView of the TableView to display the data at the specified position. + * This method gives you everything you need about a cell item. * - * @param holder : This is one of your column header ViewHolders that was created - * on ```onCreateColumnHeaderViewHolder``` method. In this example - * we have created "ColumnHeaderViewHolder" holder. - * @param columnHeaderItemModel : This is the column header view model located on this X - * position. In this example, the model class is "ColumnHeader". - * @param columnPosition : This is the X (Column) position of the column header item. - * @see #onCreateColumnHeaderViewHolder(ViewGroup, int) ; + * @param holder : This is one of your cell ViewHolders that was created on + * ```onCreateCellViewHolder``` method. In this example we have created + * "GenericTextCellViewHolder" holder. + * @param cellItemModel : This is the cell view model located on this X and Y position. In this + * example, the model class is "Cell". + * @param columnPosition : This is the X (Column) position of the cell item. + * @param rowPosition : This is the Y (Row) position of the cell item. + * @see #onCreateCellViewHolder(ViewGroup, int) ; */ @Override - public void onBindColumnHeaderViewHolder(@NonNull AbstractViewHolder holder, @Nullable ColumnHeader - columnHeaderItemModel, int columnPosition) { - - // Get the holder to update cell item text - ColumnHeaderViewHolder columnHeaderViewHolder = (ColumnHeaderViewHolder) holder; - columnHeaderViewHolder.setColumnHeader(columnHeaderItemModel); + public void onBindCellViewHolder(@NonNull AbstractViewHolder holder, @Nullable Cell cellItemModel, int + columnPosition, int rowPosition) { + holder.setCell(cellItemModel != null ? cellItemModel.getContent() : null, columnPosition, rowPosition, cellItemModel.getData()); } /** @@ -194,13 +211,13 @@ public void onBindColumnHeaderViewHolder(@NonNull AbstractViewHolder holder, @Nu * Row Header RecyclerView of the TableView needs a new RecyclerView.ViewHolder of the given * type to represent an item. * - * @param viewType : This value comes from "getRowHeaderItemViewType" method to support + * @param viewholderTypeId : This value comes from "getRowHeaderItemViewType" method to support * different type of viewHolder as a row Header item. * @see #getRowHeaderItemViewType(int); */ @NonNull @Override - public AbstractViewHolder onCreateRowHeaderViewHolder(@NonNull ViewGroup parent, int viewType) { + public AbstractViewHolder onCreateRowHeaderViewHolder(@NonNull ViewGroup parent, int viewholderTypeId) { // Get Row Header xml Layout View layout = LayoutInflater.from(parent.getContext()) .inflate(R.layout.table_view_row_header_layout, parent, false); @@ -209,7 +226,6 @@ public AbstractViewHolder onCreateRowHeaderViewHolder(@NonNull ViewGroup parent, return new RowHeaderViewHolder(layout); } - /** * That is where you set Row Header View Model data to your custom Row Header ViewHolder. This * method is Called by RowHeader RecyclerView of the TableView to display the data at the @@ -229,7 +245,7 @@ public void onBindRowHeaderViewHolder(@NonNull AbstractViewHolder holder, @Nulla // Get the holder to update row header item text RowHeaderViewHolder rowHeaderViewHolder = (RowHeaderViewHolder) holder; - rowHeaderViewHolder.row_header_textview.setText(String.valueOf(rowHeaderItemModel.getData())); + rowHeaderViewHolder.setCell(rowHeaderItemModel.getId(),-1, rowPosition, rowHeaderItemModel.getData()); } @NonNull @@ -257,8 +273,8 @@ public int getColumnHeaderItemViewType(int position) { // The unique ID for this type of column header item // If you have different items for Cell View by X (Column) position, // then you should fill this method to be able create different - // type of CellViewHolder on "onCreateCellViewHolder" - return 0; + // type of GenericTextCellViewHolder on "onCreateCellViewHolder" + return ColumnDefinition.COLUMN_TYPE_GENERIC; } @Override @@ -267,24 +283,6 @@ public int getRowHeaderItemViewType(int position) { // If you have different items for Row Header View by Y (Row) position, // then you should fill this method to be able create different // type of RowHeaderViewHolder on "onCreateRowHeaderViewHolder" - return 0; - } - - @Override - public int getCellItemViewType(int column) { - - // The unique ID for this type of cell item - // If you have different items for Cell View by X (Column) position, - // then you should fill this method to be able create different - // type of CellViewHolder on "onCreateCellViewHolder" - switch (column) { - case TableViewModel.MOOD_COLUMN_INDEX: - return MOOD_CELL_TYPE; - case TableViewModel.GENDER_COLUMN_INDEX: - return GENDER_CELL_TYPE; - default: - // Default view type - return 0; - } + return ColumnDefinition.COLUMN_TYPE_GENERIC; } } diff --git a/tableviewutil/src/main/java/com/evrencoskun/tableviewutil/TableViewModel.java b/tableviewutil/src/main/java/com/evrencoskun/tableviewutil/TableViewModel.java new file mode 100644 index 00000000..c4cd1077 --- /dev/null +++ b/tableviewutil/src/main/java/com/evrencoskun/tableviewutil/TableViewModel.java @@ -0,0 +1,86 @@ +/* + * MIT License + * + * Copyright (c) 2021 Evren Coşkun, 2023 k3b + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.evrencoskun.tableviewutil; + +import androidx.annotation.NonNull; + +import com.evrencoskun.tableview.model.Cell; +import com.evrencoskun.tableview.model.ColumnDefinition; +import com.evrencoskun.tableview.model.IColumnValueProvider; +import com.evrencoskun.tableview.model.IModelWithId; +import com.evrencoskun.tableview.model.RowHeader; + +import java.util.ArrayList; +import java.util.List; + +/** + * Generic TableViewModel that defines RowHeader, ColumnHeader and Cells of the Table. + */ +public class TableViewModel { + private final List> columnDefinitions; + protected final List pojos; + + public TableViewModel(List> columnDefinitions, List pojos) { + this.columnDefinitions = columnDefinitions; + this.pojos = pojos; + } + + @NonNull + public List>> getCellList() { + List>> list = new ArrayList<>(); + int numberOfColumns = columnDefinitions.size(); + for (POJO pojo : pojos) { + List> cellList = new ArrayList<>(); + for (int colId = 0; colId < numberOfColumns; colId++) { + ColumnDefinition columnDefinition = columnDefinitions.get(colId); + Cell cell = new Cell(pojo, columnDefinition); + cellList.add(cell); + } + list.add(cellList); + } + + return list; + } + + @NonNull + public List> getColumnHeaderList() { + return columnDefinitions; + } + + + @NonNull + public List getRowHeaderList() { + List list = new ArrayList<>(); + for (POJO pojo : pojos) { + RowHeader header = new RowHeader(pojo); + list.add(header); + } + + return list; + } + + public List> getColumnDefinitions() { + return columnDefinitions; + } +} diff --git a/tableviewutil/src/main/java/com/evrencoskun/tableviewutil/holder/BoolDrawableCellViewHolder.java b/tableviewutil/src/main/java/com/evrencoskun/tableviewutil/holder/BoolDrawableCellViewHolder.java new file mode 100644 index 00000000..67b7b023 --- /dev/null +++ b/tableviewutil/src/main/java/com/evrencoskun/tableviewutil/holder/BoolDrawableCellViewHolder.java @@ -0,0 +1,84 @@ +/* + * MIT License + * + * Copyright (c) 2021 Evren Coşkun + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.evrencoskun.tableviewutil.holder; + +import android.util.Log; +import android.view.View; +import android.widget.ImageView; + +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.evrencoskun.tableview.adapter.recyclerview.holder.AbstractViewHolder; +import com.evrencoskun.tableviewutil.R; + +/** + * Created by evrencoskun on 4.02.2018. + */ + +public class BoolDrawableCellViewHolder extends AbstractViewHolder { + @NonNull + private final ImageView cell_image; + @DrawableRes private final int mIdDrawableTrue; + @DrawableRes private final int mIdDrawableFalse; + + public BoolDrawableCellViewHolder(@NonNull View itemView, @DrawableRes int idDrawableTrue, @DrawableRes int idDrawableFalse) { + super(itemView); + cell_image = itemView.findViewById(R.id.cell_image); + mIdDrawableTrue = idDrawableTrue; + mIdDrawableFalse = idDrawableFalse; + } + + public void setCell(@Nullable Object content, int columnPosition, int rowPosition, Object pojo) { + super.setCell(content, columnPosition, rowPosition, pojo); + if (content == null) { + setData(null); + } else if (!(content instanceof Boolean)) { + //!!! TODO bug ??? wrong column content + Log.w(this.getClass().getSimpleName(), "setCell('" + content + + "', " + columnPosition + ", " + + rowPosition + ", " + + pojo + + ")"); + setData(null); + } else { + setData((Boolean) content); + } + } + + /** + * @deprecated use {@link #setCell(Object, int, int, Object)} instead + */ + public void setData(Boolean data) { + if (data != null) { + int moodDrawable = data ? mIdDrawableTrue : mIdDrawableFalse; + + cell_image.setImageResource(moodDrawable); + } else { + cell_image.setImageBitmap(null); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/holder/ColumnHeaderViewHolder.java b/tableviewutil/src/main/java/com/evrencoskun/tableviewutil/holder/ColumnHeaderViewHolder.java similarity index 87% rename from app/src/main/java/com/evrencoskun/tableviewsample/tableview/holder/ColumnHeaderViewHolder.java rename to tableviewutil/src/main/java/com/evrencoskun/tableviewutil/holder/ColumnHeaderViewHolder.java index 40d4dd71..759d8057 100644 --- a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/holder/ColumnHeaderViewHolder.java +++ b/tableviewutil/src/main/java/com/evrencoskun/tableviewutil/holder/ColumnHeaderViewHolder.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package com.evrencoskun.tableviewsample.tableview.holder; +package com.evrencoskun.tableviewutil.holder; import android.util.Log; import android.view.View; @@ -35,9 +35,9 @@ import com.evrencoskun.tableview.ITableView; import com.evrencoskun.tableview.adapter.recyclerview.holder.AbstractSorterViewHolder; +import com.evrencoskun.tableview.model.ColumnDefinition; import com.evrencoskun.tableview.sort.SortState; -import com.evrencoskun.tableviewsample.R; -import com.evrencoskun.tableviewsample.tableview.model.ColumnHeader; +import com.evrencoskun.tableviewutil.R; /** * Created by evrencoskun on 23/10/2017. @@ -68,10 +68,18 @@ public ColumnHeaderViewHolder(@NonNull View itemView, @Nullable ITableView table } /** - * This method is calling from onBindColumnHeaderHolder on TableViewAdapter + * This method is called from onBindColumnHeaderHolder on TableViewAdapter */ - public void setColumnHeader(@Nullable ColumnHeader columnHeader) { - column_header_textview.setText(String.valueOf(columnHeader.getData())); + public void setCell(@Nullable Object content, int columnPosition, int rowPosition, Object pojo) { + super.setCell(content, columnPosition, rowPosition, pojo); + setColumnHeader((ColumnDefinition) pojo); + } + + /** + * @deprecated use {@link #setCell(Object, int, int, Object)} instead + */ + public void setColumnHeader(@Nullable ColumnDefinition columnHeader) { + column_header_textview.setText(columnHeader != null ? columnHeader.getColumnHeaderText() : null); // If your TableView should have auto resize for cells & columns. // Then you should consider the below lines. Otherwise, you can remove them. diff --git a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/holder/CellViewHolder.java b/tableviewutil/src/main/java/com/evrencoskun/tableviewutil/holder/GenericTextCellViewHolder.java similarity index 81% rename from app/src/main/java/com/evrencoskun/tableviewsample/tableview/holder/CellViewHolder.java rename to tableviewutil/src/main/java/com/evrencoskun/tableviewutil/holder/GenericTextCellViewHolder.java index e13ee332..eece81a7 100644 --- a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/holder/CellViewHolder.java +++ b/tableviewutil/src/main/java/com/evrencoskun/tableviewutil/holder/GenericTextCellViewHolder.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package com.evrencoskun.tableviewsample.tableview.holder; +package com.evrencoskun.tableviewutil.holder; import android.view.View; import android.widget.LinearLayout; @@ -32,27 +32,27 @@ import androidx.annotation.Nullable; import com.evrencoskun.tableview.adapter.recyclerview.holder.AbstractViewHolder; -import com.evrencoskun.tableviewsample.R; -import com.evrencoskun.tableviewsample.tableview.model.Cell; +import com.evrencoskun.tableviewutil.R; /** * Created by evrencoskun on 23/10/2017. */ -public class CellViewHolder extends AbstractViewHolder { +public class GenericTextCellViewHolder extends AbstractViewHolder { @NonNull private final TextView cell_textview; @NonNull private final LinearLayout cell_container; - public CellViewHolder(@NonNull View itemView) { + public GenericTextCellViewHolder(@NonNull View itemView) { super(itemView); cell_textview = itemView.findViewById(R.id.cell_data); cell_container = itemView.findViewById(R.id.cell_container); } - public void setCell(@Nullable Cell cell) { - cell_textview.setText(String.valueOf(cell.getData())); + public void setCell(@Nullable Object content, int columnPosition, int rowPosition, Object pojo) { + super.setCell(content, columnPosition, rowPosition, pojo); + cell_textview.setText(content == null ? "" : content.toString()); // If your TableView should have auto resize for cells & columns. // Then you should consider the below lines. Otherwise, you can ignore them. diff --git a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/holder/RowHeaderViewHolder.java b/tableviewutil/src/main/java/com/evrencoskun/tableviewutil/holder/RowHeaderViewHolder.java similarity index 79% rename from app/src/main/java/com/evrencoskun/tableviewsample/tableview/holder/RowHeaderViewHolder.java rename to tableviewutil/src/main/java/com/evrencoskun/tableviewutil/holder/RowHeaderViewHolder.java index ce74dad9..4f796f4c 100644 --- a/app/src/main/java/com/evrencoskun/tableviewsample/tableview/holder/RowHeaderViewHolder.java +++ b/tableviewutil/src/main/java/com/evrencoskun/tableviewutil/holder/RowHeaderViewHolder.java @@ -22,15 +22,16 @@ * SOFTWARE. */ -package com.evrencoskun.tableviewsample.tableview.holder; +package com.evrencoskun.tableviewutil.holder; import android.view.View; import android.widget.TextView; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import com.evrencoskun.tableviewutil.R; import com.evrencoskun.tableview.adapter.recyclerview.holder.AbstractViewHolder; -import com.evrencoskun.tableviewsample.R; /** * Created by evrencoskun on 23/10/2017. @@ -38,10 +39,15 @@ public class RowHeaderViewHolder extends AbstractViewHolder { @NonNull - public final TextView row_header_textview; + private final TextView row_header_textview; public RowHeaderViewHolder(@NonNull View itemView) { super(itemView); row_header_textview = itemView.findViewById(R.id.row_header_textview); } + + public void setCell(@Nullable Object content, int columnPosition, int rowPosition, @Nullable Object pojo) { + super.setCell(content,columnPosition,rowPosition,pojo); + row_header_textview.setText(String.valueOf(content)); + } } diff --git a/app/src/main/res/drawable/ic_down.xml b/tableviewutil/src/main/res/drawable/ic_down.xml similarity index 100% rename from app/src/main/res/drawable/ic_down.xml rename to tableviewutil/src/main/res/drawable/ic_down.xml diff --git a/app/src/main/res/drawable/ic_next.xml b/tableviewutil/src/main/res/drawable/ic_next.xml similarity index 100% rename from app/src/main/res/drawable/ic_next.xml rename to tableviewutil/src/main/res/drawable/ic_next.xml diff --git a/app/src/main/res/drawable/ic_previous.xml b/tableviewutil/src/main/res/drawable/ic_previous.xml similarity index 100% rename from app/src/main/res/drawable/ic_previous.xml rename to tableviewutil/src/main/res/drawable/ic_previous.xml diff --git a/app/src/main/res/drawable/ic_up.xml b/tableviewutil/src/main/res/drawable/ic_up.xml similarity index 100% rename from app/src/main/res/drawable/ic_up.xml rename to tableviewutil/src/main/res/drawable/ic_up.xml diff --git a/app/src/main/res/layout/table_view_cell_layout.xml b/tableviewutil/src/main/res/layout/table_view_cell_layout.xml similarity index 100% rename from app/src/main/res/layout/table_view_cell_layout.xml rename to tableviewutil/src/main/res/layout/table_view_cell_layout.xml diff --git a/app/src/main/res/layout/table_view_column_header_layout.xml b/tableviewutil/src/main/res/layout/table_view_column_header_layout.xml similarity index 100% rename from app/src/main/res/layout/table_view_column_header_layout.xml rename to tableviewutil/src/main/res/layout/table_view_column_header_layout.xml diff --git a/app/src/main/res/layout/table_view_corner_layout.xml b/tableviewutil/src/main/res/layout/table_view_corner_layout.xml similarity index 100% rename from app/src/main/res/layout/table_view_corner_layout.xml rename to tableviewutil/src/main/res/layout/table_view_corner_layout.xml diff --git a/app/src/main/res/layout/table_view_image_cell_layout.xml b/tableviewutil/src/main/res/layout/table_view_image_cell_layout.xml similarity index 90% rename from app/src/main/res/layout/table_view_image_cell_layout.xml rename to tableviewutil/src/main/res/layout/table_view_image_cell_layout.xml index 84ec3644..8e26c4ce 100644 --- a/app/src/main/res/layout/table_view_image_cell_layout.xml +++ b/tableviewutil/src/main/res/layout/table_view_image_cell_layout.xml @@ -33,10 +33,8 @@ + android:layout_width="@dimen/cell_image_size" + android:layout_height="@dimen/cell_image_size" /> diff --git a/app/src/main/res/layout/table_view_row_header_layout.xml b/tableviewutil/src/main/res/layout/table_view_row_header_layout.xml similarity index 100% rename from app/src/main/res/layout/table_view_row_header_layout.xml rename to tableviewutil/src/main/res/layout/table_view_row_header_layout.xml diff --git a/app/src/main/res/values/colors.xml b/tableviewutil/src/main/res/values/colors.xml similarity index 100% rename from app/src/main/res/values/colors.xml rename to tableviewutil/src/main/res/values/colors.xml diff --git a/app/src/main/res/values/dimens.xml b/tableviewutil/src/main/res/values/dimens.xml similarity index 96% rename from app/src/main/res/values/dimens.xml rename to tableviewutil/src/main/res/values/dimens.xml index ae89c5e8..f016182d 100644 --- a/app/src/main/res/values/dimens.xml +++ b/tableviewutil/src/main/res/values/dimens.xml @@ -30,4 +30,5 @@ 55dp 40dp + 32dp diff --git a/tableviewutil/src/test/java/com/evrencoskun/tableviewutil/ExampleUnitTest.java b/tableviewutil/src/test/java/com/evrencoskun/tableviewutil/ExampleUnitTest.java new file mode 100644 index 00000000..584655ca --- /dev/null +++ b/tableviewutil/src/test/java/com/evrencoskun/tableviewutil/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.evrencoskun.tableviewutil; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file