├── .gitignore
├── .gitmodules
├── README.md
├── demo
├── AndroidManifest.xml
├── assets
│ └── fonts
│ │ ├── Roboto-Bold.ttf
│ │ └── Roboto-Regular.ttf
├── libs
│ └── android-support-v4.jar
├── proguard-project.txt
├── project.properties
├── res
│ ├── drawable-hdpi
│ │ ├── ic_action_github.png
│ │ ├── ic_launcher.png
│ │ ├── la_rioja_highlighted.png
│ │ ├── la_rioja_normal.png
│ │ ├── mendoza_highlighted.png
│ │ ├── mendoza_normal.png
│ │ ├── san_juan_highlighted.png
│ │ ├── san_juan_normal.png
│ │ ├── san_luis_highlighted.png
│ │ └── san_luis_normal.png
│ ├── drawable-mdpi
│ │ ├── ic_action_github.png
│ │ ├── ic_launcher.png
│ │ ├── la_rioja_highlighted.png
│ │ ├── la_rioja_normal.png
│ │ ├── mendoza_highlighted.png
│ │ ├── mendoza_normal.png
│ │ ├── san_juan_highlighted.png
│ │ ├── san_juan_normal.png
│ │ ├── san_luis_highlighted.png
│ │ └── san_luis_normal.png
│ ├── drawable-xhdpi
│ │ ├── ic_action_github.png
│ │ ├── ic_launcher.png
│ │ ├── la_rioja_highlighted.png
│ │ ├── la_rioja_normal.png
│ │ ├── mendoza_highlighted.png
│ │ ├── mendoza_normal.png
│ │ ├── san_juan_highlighted.png
│ │ ├── san_juan_normal.png
│ │ ├── san_luis_highlighted.png
│ │ └── san_luis_normal.png
│ ├── drawable
│ │ ├── la_rioja.xml
│ │ ├── mendoza.xml
│ │ ├── san_juan.xml
│ │ ├── san_luis.xml
│ │ └── shadow_menu.xml
│ ├── layout
│ │ ├── content_frame.xml
│ │ ├── menu_frame.xml
│ │ └── my_custom_cell.xml
│ ├── menu
│ │ └── main_menu.xml
│ └── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
└── src
│ └── com
│ └── nakardo
│ └── atableview
│ └── demo
│ ├── activities
│ └── MainActivity.java
│ ├── cells
│ └── MyCustomCell.java
│ ├── fragments
│ ├── BaseListFragment.java
│ ├── MenuFragment.java
│ ├── MultipleStylesListFragment.java
│ └── SimpleListFragment.java
│ └── interfaces
│ └── TableViewConfigurationInterface.java
└── library
├── AndroidManifest.xml
├── libs
└── android-support-v4.jar
├── project.properties
├── res
├── color
│ ├── atv_default_cell_text_selector.xml
│ ├── atv_subtitle_cell_detail_text_selector.xml
│ ├── atv_subtitle_cell_text_selector.xml
│ ├── atv_value1_cell_detail_text_selector.xml
│ ├── atv_value1_cell_title_text_selector.xml
│ ├── atv_value2_cell_detail_text_selector.xml
│ └── atv_value2_cell_title_text_selector.xml
├── drawable-hdpi
│ ├── checkmark_highlighted.png
│ ├── checkmark_normal.png
│ ├── disclosure_button_normal.png
│ ├── disclosure_button_pressed.png
│ ├── disclosure_highlighted.png
│ ├── disclosure_normal.png
│ ├── group_background.png
│ └── plain_header_background.9.png
├── drawable-mdpi
│ ├── checkmark_highlighted.png
│ ├── checkmark_normal.png
│ ├── disclosure_button_normal.png
│ ├── disclosure_button_pressed.png
│ ├── disclosure_highlighted.png
│ ├── disclosure_normal.png
│ ├── group_background.png
│ └── plain_header_background.9.png
├── drawable-xhdpi
│ ├── checkmark_highlighted.png
│ ├── checkmark_normal.png
│ ├── disclosure_button_normal.png
│ ├── disclosure_button_pressed.png
│ ├── disclosure_highlighted.png
│ ├── disclosure_normal.png
│ ├── group_background.png
│ └── plain_header_background.9.png
├── drawable
│ ├── checkmark.xml
│ ├── disclosure.xml
│ └── disclosure_button.xml
├── layout
│ ├── atv_cell_default.xml
│ ├── atv_cell_subtitle.xml
│ ├── atv_cell_value1.xml
│ ├── atv_cell_value2.xml
│ ├── atv_grouped_footer.xml
│ ├── atv_grouped_header.xml
│ └── atv_plain_header_footer.xml
└── values
│ ├── colors.xml
│ ├── dimens.xml
│ ├── ids.xml
│ └── styles.xml
└── src
└── com
└── nakardo
└── atableview
├── foundation
└── NSIndexPath.java
├── internal
├── ATableViewAdapter.java
├── ATableViewCellAccessoryView.java
├── ATableViewCellClickListener.java
├── ATableViewCellContainerView.java
├── ATableViewCellDrawable.java
├── ATableViewHeaderFooterCell.java
└── ATableViewPlainFooterDrawable.java
├── protocol
├── ATableViewDataSource.java
├── ATableViewDataSourceExt.java
└── ATableViewDelegate.java
├── uikit
└── UILabel.java
├── utils
└── DrawableUtils.java
└── view
├── ATableView.java
└── ATableViewCell.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # os x
2 | .DS_Store
3 |
4 | # built application files
5 | *.apk
6 | *.ap_
7 |
8 | # files for the dex VM
9 | *.dex
10 |
11 | # Java class files
12 | *.class
13 |
14 | # generated files
15 | bin/
16 | gen/
17 |
18 | # Local configuration file (sdk path, etc)
19 | local.properties
20 |
21 | # Eclipse project files
22 | .settings
23 | .classpath
24 | .project
25 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "external/SlidingMenu"]
2 | path = external/SlidingMenu
3 | url = git@github.com:jfeinstein10/SlidingMenu.git
4 | [submodule "external/ActionBarSherlock"]
5 | path = external/ActionBarSherlock
6 | url = git@github.com:JakeWharton/ActionBarSherlock.git
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # THIS PROJECT IS NO LONGER MAINTAINED
2 | > Please refer to Android [docs](https://developer.android.com/training/material/lists-cards.html) to customize lists depending on your needs.
3 |
4 | # ATableView
5 |
6 | 
7 |
8 | ## Summary
9 |
10 | ATableView intends to imitate same object model proposed on UIKit for building tables, so it's not only limited on theming Android ListView. If you've some background on iOS development you may jump over some of the sections below, you'll find a lot of similarities with the native framework.
11 |
12 | If not, you should be good with the examples included here and the demo project.
13 |
14 | ## Updates
15 |
16 | Documentation is a little outdated, please use it only for reference and stay close to the examples included on the demo project. Feel free to submit a bug if you find any issues using it.
17 |
18 | ## How to use it
19 |
20 | ### Creating tables
21 |
22 | ```java
23 | @Override
24 | public void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.main);
27 |
28 | // ATableViewStyle.Plain & Grouped supported.
29 | ATableView tableView = new ATableView(ATableViewStyle.Grouped, this);
30 |
31 | // don't forget to set the datasource, otherwise you'll get an exception.
32 | // it must be an object extending ATableViewDataSource, or ATableViewDataSourceExt (more on this later).
33 | tableView.setDataSource(new SampleATableViewDataSource());
34 |
35 | // delegates are optional, it must extend ATableViewDelegate.
36 | tableView.setDelegate(new SampleATableViewDelegate());
37 |
38 | FrameLayout container = (FrameLayout)findViewById(android.R.id.content);
39 | container.addView(tableView);
40 | }
41 | ```
42 |
43 | ### Implementing a data source
44 |
45 | It's your responsability to implement the required methods when extending `ATableViewDataSource`. The following are supported:
46 |
47 | ```java
48 | public ATableViewCell cellForRowAtIndexPath(ATableView tableView, NSIndexPath indexPath); [Required]
49 | public int numberOfRowsInSection(ATableView tableView, int section); [Required]
50 | public int numberOfSectionsInTableView(ATableView tableView);
51 | ```
52 |
53 | More on how this methods works can be found on the iOS [UITableViewDataSource Protocol Reference](http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewDataSource_Protocol/Reference/Reference.html).
54 |
55 | #### Example
56 |
57 | ```java
58 | @Override
59 | public ATableViewCell cellForRowAtIndexPath(ATableView tableView, NSIndexPath indexPath) {
60 | final String cellIdentifier = "CellIdentifier";
61 |
62 | // ATableViewCellStyle.Default, Subtitle, Value1 & Value2 supported.
63 | ATableViewCellStyle style = ATableViewCellStyle.Default;
64 |
65 | // reuse cells. if the table has different row types it will result on performance issues.
66 | // Use ATableViewDataSourceExt on this cases.
67 | // please notice we ask the datasource for a cell instead the table as we do on ios.
68 | ATableViewCell cell = dequeueReusableCellWithIdentifier(cellIdentifier);
69 | if (cell == null) {
70 | cell = new ATableViewCell(style, cellIdentifier, MainActivity.this);
71 | // ATableViewCellSelectionStyle.Blue, Gray & None supported. It defaults to Blue.
72 | cell.setSelectionStyle(ATableViewCellSelectionStyle.Blue);
73 | }
74 |
75 | // set title.
76 | cell.getTextLabel().setText("Buenos Aires");
77 |
78 | // set detail text. careful, detail text is not present on every cell style.
79 | // null references are not as neat as in obj-c.
80 | TextView detailTextLabel = cell.getDetailTextLabel();
81 | if (detailTextLabel != null) {
82 | detailTextLabel.setText("Argentina");
83 | }
84 |
85 | return cell;
86 | }
87 |
88 | @Override
89 | public int numberOfRowsInSection(ATableView tableView, int section) {
90 | // return number of rows for this section.
91 | if (section == 1) {
92 | return 4;
93 | }
94 |
95 | return 2;
96 | }
97 |
98 | @Override
99 | public int numberOfSectionsInTableView(ATableView tableView) {
100 | // defaults to 1.
101 | return 2;
102 | }
103 | ```
104 |
105 | ### Table styles (ATableViewStyle)
106 |
107 | All [UITableViewStyle](http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/c/tdef/UITableViewStyle) styles are supported. These are:
108 |
109 | * ATableViewStyle.Plain
110 | * ATableViewStyle.Grouped
111 |
112 | ### Creating cells
113 |
114 | You can use cell styles included by default, or extend `ATableViewCell` to create your own cells.
115 |
116 | ### Cell styles (ATableViewCellStyle)
117 |
118 | All [UITableViewCellStyles](http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewCell_Class/Reference/Reference.html#//apple_ref/c/tdef/UITableViewCellStyle) styles are supported. These are:
119 |
120 | * ATableViewCellStyle.Default
121 | * ATableViewCellStyle.Subtitle
122 | * ATableViewCellStyle.Value1
123 | * ATableViewCellStyle.Value2
124 |
125 | 
126 |
127 | ### Cell selection styles (ATableViewCellSelectionStyle)
128 |
129 | All [UITableViewCellSelectionStyle](http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewCell_Class/Reference/Reference.html#//apple_ref/doc/c_ref/UITableViewCellSelectionStyle) styles are supported These are:
130 |
131 | * ATableViewCellSelectionStyle.None
132 | * ATableViewCellSelectionStyle.Blue (Default)
133 | * ATableViewCellSelectionStyle.Gray
134 |
135 | 
136 |
137 | ### Adding images to cells (imageView)
138 |
139 | imageView is shown automatically when an image is defined for it, otherwise is hidden by default on each cell.
140 |
141 | 
142 |
143 | #### Example
144 |
145 | ```java
146 | Drawable drawable = getResources().getDrawable(R.drawable.some_image);
147 | cell.getImageView().setImageDrawable(drawable);
148 | ```
149 |
150 | ### Creating custom cells
151 |
152 | Creating custom cells is as simple as extending `ATableViewCellStyle` and indicate the layout you want your cell to use.
153 |
154 | #### Example
155 |
156 | ```java
157 | public class MyCustomCell extends ATableViewCell {
158 | private UILabel mCustomLabel;
159 |
160 | protected int getLayout(ATableViewCellStyle style) {
161 | // here it goes your custom cell layout.
162 | return R.layout.my_custom_cell;
163 | }
164 |
165 | public MyCustomCell(ATableViewCellStyle style, String reuseIdentifier, Context context) {
166 | super(style, reuseIdentifier, context);
167 | mCustomLabel = (UILabel)findViewById(R.id.custom_cell_label);
168 | }
169 |
170 | public UILabel getCustomLabel() {
171 | return mCustomLabel;
172 | }
173 | }
174 | ```
175 |
176 | ### Implementing a delegate
177 |
178 | Adding a delegate to the table is optional. [UITableViewDelegate](http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html) defines many methods to describe how the table should look and behave. Only a few of them are currently supported on `ATableViewDelegate`. These are:
179 |
180 | ```java
181 | public void didSelectRowAtIndexPath(ATableView tableView, NSIndexPath indexPath);
182 | public int heightForRowAtIndexPath(ATableView tableView, NSIndexPath indexPath);
183 | ```
184 |
185 | #### Example
186 |
187 | ```java
188 | @Override
189 | public void didSelectRowAtIndexPath(ATableView tableView, NSIndexPath indexPath) {
190 | // do something when the row is selected. rows are identified by its indexPath.
191 | }
192 |
193 | @Override
194 | public int heightForRowAtIndexPath(ATableView tableView, NSIndexPath indexPath) {
195 | // return height size on dip. defaults to 44 if not implemented.
196 | return 54;
197 | }
198 | ```
199 |
200 | ### Table data source additional methods (ATableViewDataSourceExt)
201 |
202 | On the case you need to use different cell styles on the same table, you should extend `ATableViewDataSourceExt` to avoid performance issues when scrolling. This is necessary since Android ListView uses different pools for reusing cells, a pool for each cell type. `ATableViewDataSourceExt` is used to specify how many rows and pools should be created to run smoothly.
203 |
204 | You'll have additionally to implement the following methods:
205 |
206 | ```java
207 | public int numberOfRowStyles(); [Required]
208 | public int styleForRowAtIndexPath(NSIndexPath indexPath); [Required]
209 | ```
210 |
211 | #### Example
212 |
213 | ```java
214 | @Override
215 | public int numberOfRowStyles() {
216 | // number of different rows on the table.
217 | return 4;
218 | }
219 |
220 | @Override
221 | public int styleForRowAtIndexPath(NSIndexPath indexPath) {
222 | // integer identifying the style for a cell at a given indexPath.
223 | return myOwnImplementationGetStyle(indexPath);
224 | }
225 | ```
226 |
227 | ## Extra stuff
228 |
229 | ### UILabel
230 |
231 | UILabel uses internally [Roboto](http://developer.android.com/design/style/typography.html) font, which make labels look-alike in iOS and it's rendered great by Android. Roboto font is available from ICS and above, so it should be included on your project `/assets` folder in order to make it work for any version.
232 |
233 | Both **Roboto-Regular.ttf** and **Roboto-Bold.ttf** are included on the demo project. On the case you don't include these files, text will render using the default font available.
234 |
235 | ## License
236 |
237 | Copyright 2012 Diego Acosta - Contact me at diegonake@gmail.com / @nakardo
238 |
239 | Released under the [Apache 2.0.](http://www.apache.org/licenses/LICENSE-2.0.html) license.
240 |
241 | Roboto font by Google Android - Licensed under the Apache License.
242 |
243 | Awesome Android PSD images by [slaveoffear](http://slaveoffear.deviantart.com).
244 |
--------------------------------------------------------------------------------
/demo/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/demo/assets/fonts/Roboto-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/assets/fonts/Roboto-Bold.ttf
--------------------------------------------------------------------------------
/demo/assets/fonts/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/assets/fonts/Roboto-Regular.ttf
--------------------------------------------------------------------------------
/demo/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/demo/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/demo/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-14
15 | android.library.reference.1=../library
16 | android.library.reference.2=../external/SlidingMenu/library
17 |
--------------------------------------------------------------------------------
/demo/res/drawable-hdpi/ic_action_github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-hdpi/ic_action_github.png
--------------------------------------------------------------------------------
/demo/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/res/drawable-hdpi/la_rioja_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-hdpi/la_rioja_highlighted.png
--------------------------------------------------------------------------------
/demo/res/drawable-hdpi/la_rioja_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-hdpi/la_rioja_normal.png
--------------------------------------------------------------------------------
/demo/res/drawable-hdpi/mendoza_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-hdpi/mendoza_highlighted.png
--------------------------------------------------------------------------------
/demo/res/drawable-hdpi/mendoza_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-hdpi/mendoza_normal.png
--------------------------------------------------------------------------------
/demo/res/drawable-hdpi/san_juan_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-hdpi/san_juan_highlighted.png
--------------------------------------------------------------------------------
/demo/res/drawable-hdpi/san_juan_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-hdpi/san_juan_normal.png
--------------------------------------------------------------------------------
/demo/res/drawable-hdpi/san_luis_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-hdpi/san_luis_highlighted.png
--------------------------------------------------------------------------------
/demo/res/drawable-hdpi/san_luis_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-hdpi/san_luis_normal.png
--------------------------------------------------------------------------------
/demo/res/drawable-mdpi/ic_action_github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-mdpi/ic_action_github.png
--------------------------------------------------------------------------------
/demo/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/res/drawable-mdpi/la_rioja_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-mdpi/la_rioja_highlighted.png
--------------------------------------------------------------------------------
/demo/res/drawable-mdpi/la_rioja_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-mdpi/la_rioja_normal.png
--------------------------------------------------------------------------------
/demo/res/drawable-mdpi/mendoza_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-mdpi/mendoza_highlighted.png
--------------------------------------------------------------------------------
/demo/res/drawable-mdpi/mendoza_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-mdpi/mendoza_normal.png
--------------------------------------------------------------------------------
/demo/res/drawable-mdpi/san_juan_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-mdpi/san_juan_highlighted.png
--------------------------------------------------------------------------------
/demo/res/drawable-mdpi/san_juan_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-mdpi/san_juan_normal.png
--------------------------------------------------------------------------------
/demo/res/drawable-mdpi/san_luis_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-mdpi/san_luis_highlighted.png
--------------------------------------------------------------------------------
/demo/res/drawable-mdpi/san_luis_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-mdpi/san_luis_normal.png
--------------------------------------------------------------------------------
/demo/res/drawable-xhdpi/ic_action_github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-xhdpi/ic_action_github.png
--------------------------------------------------------------------------------
/demo/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/res/drawable-xhdpi/la_rioja_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-xhdpi/la_rioja_highlighted.png
--------------------------------------------------------------------------------
/demo/res/drawable-xhdpi/la_rioja_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-xhdpi/la_rioja_normal.png
--------------------------------------------------------------------------------
/demo/res/drawable-xhdpi/mendoza_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-xhdpi/mendoza_highlighted.png
--------------------------------------------------------------------------------
/demo/res/drawable-xhdpi/mendoza_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-xhdpi/mendoza_normal.png
--------------------------------------------------------------------------------
/demo/res/drawable-xhdpi/san_juan_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-xhdpi/san_juan_highlighted.png
--------------------------------------------------------------------------------
/demo/res/drawable-xhdpi/san_juan_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-xhdpi/san_juan_normal.png
--------------------------------------------------------------------------------
/demo/res/drawable-xhdpi/san_luis_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-xhdpi/san_luis_highlighted.png
--------------------------------------------------------------------------------
/demo/res/drawable-xhdpi/san_luis_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/demo/res/drawable-xhdpi/san_luis_normal.png
--------------------------------------------------------------------------------
/demo/res/drawable/la_rioja.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/demo/res/drawable/mendoza.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/demo/res/drawable/san_juan.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/demo/res/drawable/san_luis.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/demo/res/drawable/shadow_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
--------------------------------------------------------------------------------
/demo/res/layout/content_frame.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/demo/res/layout/menu_frame.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/demo/res/layout/my_custom_cell.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
15 |
16 |
21 |
22 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/demo/res/menu/main_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/demo/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #768DB0
4 |
--------------------------------------------------------------------------------
/demo/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 15dp
4 | 70dp
5 |
--------------------------------------------------------------------------------
/demo/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | ATableView Demos
4 | https://github.com/dmacosta/ATableView
5 |
--------------------------------------------------------------------------------
/demo/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
20 |
--------------------------------------------------------------------------------
/demo/src/com/nakardo/atableview/demo/activities/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.demo.activities;
2 |
3 | import android.content.Intent;
4 | import android.net.Uri;
5 | import android.os.Bundle;
6 | import android.support.v4.app.Fragment;
7 | import android.util.Log;
8 | import android.view.KeyEvent;
9 |
10 | import com.actionbarsherlock.app.SherlockFragmentActivity;
11 | import com.actionbarsherlock.view.Menu;
12 | import com.actionbarsherlock.view.MenuItem;
13 | import com.nakardo.atableview.demo.R;
14 | import com.nakardo.atableview.demo.fragments.MenuFragment;
15 | import com.nakardo.atableview.demo.fragments.MenuFragment.TableViewDemoInterface;
16 | import com.nakardo.atableview.demo.fragments.MultipleStylesListFragment;
17 | import com.nakardo.atableview.demo.interfaces.TableViewConfigurationInterface;
18 | import com.nakardo.atableview.view.ATableView.ATableViewStyle;
19 | import com.nakardo.atableview.view.ATableViewCell.ATableViewCellSeparatorStyle;
20 | import com.slidingmenu.lib.SlidingMenu;
21 |
22 | public class MainActivity extends SherlockFragmentActivity
23 | implements TableViewConfigurationInterface, TableViewDemoInterface {
24 |
25 | private TableViewConfigurationInterface mContentListener;
26 | private SlidingMenu mMenu;
27 |
28 | // example default selections.
29 | public ATableViewStyle mTableViewStyle = ATableViewStyle.Grouped;
30 | public ATableViewCellSeparatorStyle mSeparatorStyle = ATableViewCellSeparatorStyle.SingleLineEtched;
31 | public boolean mAllowsSelection = true;
32 | public boolean mAllowsMultipleSelection = false;
33 |
34 | private void setupSlidingMenu() {
35 | mMenu = new SlidingMenu(this);
36 |
37 | mMenu.setMode(SlidingMenu.LEFT);
38 | mMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
39 | mMenu.setShadowWidthRes(R.dimen.menu_shadow_width);
40 | mMenu.setShadowDrawable(R.drawable.shadow_menu);
41 | mMenu.setBehindOffsetRes(R.dimen.menu_behind_offset);
42 | mMenu.setFadeDegree(0.35f);
43 | mMenu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT);
44 |
45 | mMenu.setMenu(R.layout.menu_frame);
46 |
47 | getSupportFragmentManager().beginTransaction().replace(R.id.menu_frame,
48 | new MenuFragment()).commit();
49 | }
50 |
51 | public SlidingMenu getSlidingMenu() {
52 | return mMenu;
53 | }
54 |
55 | @Override
56 | public void onCreate(Bundle savedInstanceState) {
57 | super.onCreate(savedInstanceState);
58 | setContentView(R.layout.content_frame);
59 |
60 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
61 | setupSlidingMenu();
62 |
63 | onTableViewDemoSelected(MultipleStylesListFragment.class);
64 | }
65 |
66 | @Override
67 | public boolean onCreateOptionsMenu(Menu menu) {
68 | getSupportMenuInflater().inflate(R.menu.main_menu, menu);
69 | return true;
70 | }
71 |
72 | @Override
73 | public boolean onOptionsItemSelected(MenuItem item) {
74 | switch (item.getItemId()) {
75 | case android.R.id.home:
76 | mMenu.toggle(); return true;
77 | case R.id.goto_github:
78 | String url = getResources().getString(R.string.github_url);
79 | startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
80 | return true;
81 | }
82 |
83 | return super.onOptionsItemSelected(item);
84 | }
85 |
86 | @Override
87 | public boolean onKeyDown(int keycode, KeyEvent event ) {
88 | if (keycode == KeyEvent.KEYCODE_MENU) {
89 | mMenu.toggle(); return true;
90 | }
91 |
92 | return super.onKeyDown(keycode,event);
93 | }
94 |
95 | @Override
96 | public void onTableViewConfigurationChanged() {
97 | mContentListener.onTableViewConfigurationChanged();
98 | }
99 |
100 | @Override
101 | public void onTableViewDemoSelected(Class fragmentClass) {
102 | T fragment = null;
103 | try {
104 | fragment = fragmentClass.newInstance();
105 | } catch (InstantiationException e) {
106 | Log.e(this.getClass().toString(), e.getMessage());
107 | } catch (IllegalAccessException e) {
108 | Log.e(this.getClass().toString(), e.getMessage());
109 | }
110 | fragment.setHasOptionsMenu(true);
111 |
112 | getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, fragment).commit();
113 | mContentListener = (TableViewConfigurationInterface) fragment;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/demo/src/com/nakardo/atableview/demo/cells/MyCustomCell.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.demo.cells;
2 |
3 | import android.content.Context;
4 |
5 | import com.nakardo.atableview.demo.R;
6 | import com.nakardo.atableview.view.ATableViewCell;
7 |
8 | public class MyCustomCell extends ATableViewCell {
9 |
10 | protected int getLayout(ATableViewCellStyle style) {
11 | return R.layout.my_custom_cell;
12 | }
13 |
14 | public MyCustomCell(ATableViewCellStyle style, String reuseIdentifier, Context context) {
15 | super(style, reuseIdentifier, context);
16 | }
17 |
18 | public MyCustomCell(Context context) {
19 | super(context);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/demo/src/com/nakardo/atableview/demo/fragments/BaseListFragment.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.demo.fragments;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.FrameLayout;
9 |
10 | import com.actionbarsherlock.app.SherlockFragment;
11 | import com.nakardo.atableview.demo.activities.MainActivity;
12 | import com.nakardo.atableview.demo.interfaces.TableViewConfigurationInterface;
13 | import com.nakardo.atableview.protocol.ATableViewDataSource;
14 | import com.nakardo.atableview.protocol.ATableViewDelegate;
15 | import com.nakardo.atableview.view.ATableView;
16 | import com.slidingmenu.lib.SlidingMenu;
17 |
18 | public abstract class BaseListFragment extends SherlockFragment implements TableViewConfigurationInterface {
19 | protected MainActivity mFragmentContainer;
20 | protected ATableView mTableView;
21 |
22 | protected void createTableView() {
23 | mTableView = new ATableView(mFragmentContainer.mTableViewStyle, getActivity());
24 | mTableView.setSeparatorStyle(mFragmentContainer.mSeparatorStyle);
25 | mTableView.setAllowsSelection(mFragmentContainer.mAllowsSelection);
26 | mTableView.setAllowsMultipleSelection(mFragmentContainer.mAllowsMultipleSelection);
27 | mTableView.setDataSource(getDataSource());
28 | mTableView.setDelegate(getDelegate());
29 |
30 | ViewGroup container = (ViewGroup) getView();
31 | container.addView(mTableView);
32 | }
33 |
34 | public abstract ATableViewDataSource getDataSource();
35 |
36 | public ATableViewDelegate getDelegate() {
37 | return new ATableViewDelegate();
38 | }
39 |
40 | @Override
41 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
42 | FrameLayout view = new FrameLayout(getActivity());
43 | return view;
44 | }
45 |
46 | @Override
47 | public void onActivityCreated(Bundle savedInstanceState) {
48 | super.onActivityCreated(savedInstanceState);
49 | createTableView();
50 |
51 | // dismiss menu if it's currently showing, it reduces animation glitch while creating fragment.
52 | SlidingMenu menu = mFragmentContainer.getSlidingMenu();
53 | if (menu.isMenuShowing()) {
54 | mFragmentContainer.getSlidingMenu().toggle();
55 | }
56 | }
57 |
58 | @Override
59 | public void onAttach(Activity activity) {
60 | if (activity instanceof MainActivity) mFragmentContainer = (MainActivity) activity;
61 | else throw new RuntimeException("Fragment must be attached to an instance of MainActivity");
62 |
63 | super.onAttach(activity);
64 | }
65 |
66 | @Override
67 | public void onTableViewConfigurationChanged() {
68 | ((ViewGroup) getView()).removeView(mTableView);
69 | createTableView();
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/demo/src/com/nakardo/atableview/demo/fragments/MenuFragment.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.demo.fragments;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 | import android.os.Bundle;
8 | import android.support.v4.app.Fragment;
9 | import android.view.ViewGroup;
10 |
11 | import com.nakardo.atableview.foundation.NSIndexPath;
12 | import com.nakardo.atableview.internal.ATableViewCellAccessoryView.ATableViewCellAccessoryType;
13 | import com.nakardo.atableview.protocol.ATableViewDataSource;
14 | import com.nakardo.atableview.protocol.ATableViewDelegate;
15 | import com.nakardo.atableview.view.ATableView;
16 | import com.nakardo.atableview.view.ATableView.ATableViewStyle;
17 | import com.nakardo.atableview.view.ATableViewCell;
18 | import com.nakardo.atableview.view.ATableViewCell.ATableViewCellSeparatorStyle;
19 | import com.nakardo.atableview.view.ATableViewCell.ATableViewCellStyle;
20 |
21 | public class MenuFragment extends BaseListFragment {
22 |
23 | // section.
24 | private static final String[] mSectionsTitle = { "Demos", "Style", "Selection Style" };
25 | private static enum MenuFragmentSection { DEMOS, STYLES, SELECTION };
26 |
27 | // selections.
28 | private static enum ATableViewDemo { SIMPLE, COMPLEX };
29 | private static enum ATableViewStyleValue { GROUPED_ETCHED, GROUPED, PLAIN };
30 | private static enum ATableViewSelectionValue { NONE, SINGLE, MULTIPLE };
31 |
32 | private List> mRowsText;
33 |
34 | public interface TableViewDemoInterface {
35 | public void onTableViewDemoSelected(Class fragmentClass);
36 | }
37 |
38 | private static List> createRowsTextList() {
39 | List> rows = new ArrayList>();
40 |
41 | rows.add(Arrays.asList(new String[] { "Simple", "Complex" }));
42 | rows.add(Arrays.asList(new String[] { "Grouped (Etched)", "Grouped", "Plain" }));
43 | rows.add(Arrays.asList(new String[] { "None", "Single", "Multiple" }));
44 |
45 | return rows;
46 | }
47 |
48 | @Override
49 | protected void createTableView() {
50 | mTableView = new ATableView(ATableViewStyle.Plain, getActivity());
51 | mTableView.setDataSource(new MenuTableViewDataSource());
52 | mTableView.setDelegate(new MenuTableViewDelegate());
53 |
54 | ViewGroup container = (ViewGroup) getView();
55 | container.addView(mTableView);
56 | }
57 |
58 | @Override
59 | public ATableViewDataSource getDataSource() {
60 | return new MenuTableViewDataSource();
61 | }
62 |
63 | @Override
64 | public ATableViewDelegate getDelegate() {
65 | return new MenuTableViewDelegate();
66 | }
67 |
68 | @Override
69 | public void onActivityCreated(Bundle savedInstanceState) {
70 | mRowsText = createRowsTextList();
71 | super.onActivityCreated(savedInstanceState);
72 | }
73 |
74 | private class MenuTableViewDataSource extends ATableViewDataSource {
75 |
76 | private boolean isSelected(NSIndexPath indexPath) {
77 | boolean isSelected = false;
78 |
79 | int row = indexPath.getRow();
80 | MenuFragmentSection section = MenuFragmentSection.values()[indexPath.getSection()];
81 | switch (section) {
82 | case STYLES:
83 | ATableViewStyle tableViewStyle = mFragmentContainer.mTableViewStyle;
84 | ATableViewCellSeparatorStyle separatorStyle = mFragmentContainer.mSeparatorStyle;
85 |
86 | ATableViewStyleValue style = ATableViewStyleValue.values()[row];
87 | switch (style) {
88 | case GROUPED_ETCHED:
89 | isSelected = (tableViewStyle == ATableViewStyle.Grouped &&
90 | separatorStyle == ATableViewCellSeparatorStyle.SingleLineEtched); break;
91 | case GROUPED:
92 | isSelected = (tableViewStyle == ATableViewStyle.Grouped &&
93 | separatorStyle == ATableViewCellSeparatorStyle.SingleLine); break;
94 | default:
95 | isSelected = (tableViewStyle == ATableViewStyle.Plain); break;
96 | } break;
97 | case SELECTION:
98 | boolean allowsSelection = mFragmentContainer.mAllowsSelection;
99 | boolean allowsMultipleSelection = mFragmentContainer.mAllowsMultipleSelection;
100 |
101 | ATableViewSelectionValue selection = ATableViewSelectionValue.values()[row];
102 | switch (selection) {
103 | case NONE: isSelected = (!allowsSelection); break;
104 | case SINGLE: isSelected = (allowsSelection && !allowsMultipleSelection); break;
105 | default: isSelected = (allowsSelection && allowsMultipleSelection); break;
106 | } break;
107 | default: break;
108 | }
109 |
110 | return isSelected;
111 | }
112 |
113 | @Override
114 | public ATableViewCell cellForRowAtIndexPath(ATableView tableView, NSIndexPath indexPath) {
115 | ATableViewCell cell = null;
116 | String cellIdentifier = null;
117 |
118 | MenuFragmentSection section = MenuFragmentSection.values()[indexPath.getSection()];
119 | if (section == MenuFragmentSection.DEMOS) {
120 | cellIdentifier = "SELECTION_CELL";
121 |
122 | cell = dequeueReusableCellWithIdentifier(cellIdentifier);
123 | if (cell == null) {
124 | cell = new ATableViewCell(ATableViewCellStyle.Default, cellIdentifier, getActivity());
125 | cell.setAccessoryType(ATableViewCellAccessoryType.DisclosureIndicator);
126 | }
127 | } else {
128 | cellIdentifier = "CHECKED_CELL";
129 |
130 | cell = dequeueReusableCellWithIdentifier(cellIdentifier);
131 | if (cell == null) {
132 | cell = new ATableViewCell(ATableViewCellStyle.Default, cellIdentifier, getActivity());
133 | }
134 |
135 | // toogle selection.
136 | ATableViewCellAccessoryType accessoryType = ATableViewCellAccessoryType.None;
137 | if (isSelected(indexPath)) {
138 | accessoryType = ATableViewCellAccessoryType.Checkmark;
139 | }
140 | cell.setAccessoryType(accessoryType);
141 | }
142 |
143 | // set text.
144 | String text = mRowsText.get(indexPath.getSection()).get(indexPath.getRow());
145 | cell.getTextLabel().setText(text);
146 |
147 | return cell;
148 | }
149 |
150 | @Override
151 | public String titleForHeaderInSection(ATableView tableView, int section) {
152 | return mSectionsTitle[section];
153 | }
154 |
155 | @Override
156 | public int numberOfSectionsInTableView(ATableView tableView) {
157 | return mSectionsTitle.length;
158 | }
159 |
160 | @Override
161 | public int numberOfRowsInSection(ATableView tableView, int section) {
162 | return mRowsText.get(section).size();
163 | }
164 | }
165 |
166 | private class MenuTableViewDelegate extends ATableViewDelegate {
167 |
168 | @Override
169 | public void didSelectRowAtIndexPath(ATableView tableView, NSIndexPath indexPath) {
170 | int row = indexPath.getRow();
171 |
172 | MenuFragmentSection section = MenuFragmentSection.values()[indexPath.getSection()];
173 | switch (section) {
174 | case DEMOS:
175 | Class extends Fragment> fragmentClass = null;
176 |
177 | ATableViewDemo demo = ATableViewDemo.values()[row];
178 | switch (demo) {
179 | case SIMPLE: fragmentClass = SimpleListFragment.class; break;
180 | default: fragmentClass = MultipleStylesListFragment.class; break;
181 | }
182 |
183 | mFragmentContainer.onTableViewDemoSelected(fragmentClass);
184 | break;
185 | case STYLES:
186 | ATableViewStyle tableViewStyle = ATableViewStyle.Grouped;
187 | ATableViewCellSeparatorStyle separatorStyle = ATableViewCellSeparatorStyle.SingleLine;
188 |
189 | ATableViewStyleValue style = ATableViewStyleValue.values()[row];
190 | switch (style) {
191 | case GROUPED_ETCHED: separatorStyle = ATableViewCellSeparatorStyle.SingleLineEtched; break;
192 | case GROUPED: break;
193 | default: tableViewStyle = ATableViewStyle.Plain; break;
194 | }
195 |
196 | mFragmentContainer.mTableViewStyle = tableViewStyle;
197 | mFragmentContainer.mSeparatorStyle = separatorStyle;
198 |
199 | mTableView.reloadData(); mFragmentContainer.onTableViewConfigurationChanged();
200 | break;
201 | case SELECTION:
202 | boolean allowsSelection = true, allowsMultipleSelection = false;
203 |
204 | ATableViewSelectionValue selection = ATableViewSelectionValue.values()[row];
205 | switch (selection) {
206 | case NONE: allowsSelection = false; break;
207 | case MULTIPLE: allowsMultipleSelection = true; break;
208 | default: break;
209 | }
210 |
211 | mFragmentContainer.mAllowsSelection = allowsSelection;
212 | mFragmentContainer.mAllowsMultipleSelection = allowsMultipleSelection;
213 |
214 | mTableView.reloadData(); mFragmentContainer.onTableViewConfigurationChanged();
215 | break;
216 | default: break;
217 | }
218 | }
219 | }
220 | }
221 |
--------------------------------------------------------------------------------
/demo/src/com/nakardo/atableview/demo/fragments/MultipleStylesListFragment.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.demo.fragments;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 | import android.graphics.drawable.Drawable;
8 | import android.os.Bundle;
9 | import android.text.TextUtils.TruncateAt;
10 | import android.widget.ImageView;
11 | import android.widget.LinearLayout;
12 | import android.widget.ListView;
13 | import android.widget.TextView;
14 | import android.widget.Toast;
15 |
16 | import com.nakardo.atableview.demo.R;
17 | import com.nakardo.atableview.demo.cells.MyCustomCell;
18 | import com.nakardo.atableview.foundation.NSIndexPath;
19 | import com.nakardo.atableview.internal.ATableViewCellAccessoryView.ATableViewCellAccessoryType;
20 | import com.nakardo.atableview.protocol.ATableViewDataSource;
21 | import com.nakardo.atableview.protocol.ATableViewDataSourceExt;
22 | import com.nakardo.atableview.protocol.ATableViewDelegate;
23 | import com.nakardo.atableview.view.ATableView;
24 | import com.nakardo.atableview.view.ATableViewCell;
25 | import com.nakardo.atableview.view.ATableViewCell.ATableViewCellSelectionStyle;
26 | import com.nakardo.atableview.view.ATableViewCell.ATableViewCellStyle;
27 |
28 | public class MultipleStylesListFragment extends BaseListFragment {
29 | private List> mCapitals;
30 | private List> mProvinces;
31 | private String[] mRegions = {
32 | "Northwest", "Gran Chaco", "Mesopotamia", "Pampas", "Cuyo", "Patagonia", "Capital City", "About"
33 | };
34 | private String[] mNotes = {
35 | null, "Southwestern Santiago del Estero is sometimes considered part of the Sierras area.",
36 | null, "Southern part of La Pampa is sometimes called Dry Pampa and included in Patagonia.",
37 | "La Rioja is sometimes considered part of Cuyo region instead of the Northwest.", null,
38 | null, null
39 | };
40 |
41 | private static List> createProvincesList() {
42 | List> provinces = new ArrayList>();
43 |
44 | provinces.add(Arrays.asList(new String[] { "Jujuy", "Salta", "Tucuman", "Catamarca" }));
45 | provinces.add(Arrays.asList(new String[] { "Formosa", "Chaco", "Santiago del Estero" }));
46 | provinces.add(Arrays.asList(new String[] { "Misiones", "Entre Rios", "Corrientes" }));
47 | provinces.add(Arrays.asList(new String[] { "Cordoba", "Santa Fe", "La Pampa", "Buenos Aires" }));
48 | provinces.add(Arrays.asList(new String[] { "San Juan", "La Rioja", "Mendoza", "San Luis" }));
49 | provinces.add(Arrays.asList(new String[] { "Neuquen", "Chubut", "Santa Cruz", "Tierra del Fuego" }));
50 | provinces.add(Arrays.asList(new String[] { "Autonomous City of Buenos Aires" }));
51 | provinces.add(Arrays.asList(new String[] { "ATableView intends to imitate same object model proposed on UIKit for building tables, " +
52 | "so it's not only limited on theming Android ListView.\n\nCopyright 2012 Diego Acosta\n\n" +
53 | "Contact me at diegonake@gmail.com / @nakardo"}));
54 |
55 | return provinces;
56 | }
57 |
58 | private static List> createCapitalsList() {
59 | List> capitals = new ArrayList>();
60 |
61 | capitals.add(Arrays.asList(new String[] { "San Salvador de Jujuy", "Salta", "San Miguel de Tucuman", "S.F.V. de Catamarca" }));
62 | capitals.add(Arrays.asList(new String[] { "Formosa", "Resistencia", "Santiago del Estero" }));
63 | capitals.add(Arrays.asList(new String[] { "Posadas", "Parana", "Corrientes" }));
64 | capitals.add(Arrays.asList(new String[] { "Cordoba", "Santa Fe", "Santa Rosa", "Capital Federal" }));
65 | capitals.add(Arrays.asList(new String[] { "San Juan", "La Rioja", "Mendoza", "San Luis" }));
66 | capitals.add(Arrays.asList(new String[] { "Viedma", "Neuquen", "Rawson", "Rio Gallegos", "Ushuaia" }));
67 |
68 | return capitals;
69 | }
70 |
71 | @Override
72 | public ATableViewDataSource getDataSource() {
73 | return new MultipleStylesListDataSource();
74 | }
75 |
76 | @Override
77 | public ATableViewDelegate getDelegate() {
78 | return new MultipleStylesListDelegate();
79 | }
80 |
81 | @Override
82 | public void onActivityCreated(Bundle savedInstanceState) {
83 | mCapitals = createCapitalsList();
84 | mProvinces = createProvincesList();
85 |
86 | super.onActivityCreated(savedInstanceState);
87 | }
88 |
89 | private class MultipleStylesListDataSource extends ATableViewDataSourceExt {
90 |
91 | private Drawable getDrawableForRowAtIndexPath(NSIndexPath indexPath) {
92 | Drawable drawable = null;
93 | switch (indexPath.getRow()) {
94 | case 0: drawable = getResources().getDrawable(R.drawable.san_juan); break;
95 | case 1: drawable = getResources().getDrawable(R.drawable.la_rioja); break;
96 | case 2: drawable = getResources().getDrawable(R.drawable.mendoza); break;
97 | default:drawable = getResources().getDrawable(R.drawable.san_luis);
98 | }
99 |
100 | return drawable;
101 | }
102 |
103 | private void setupImageView(ATableViewCell cell, NSIndexPath indexPath) {
104 | ImageView imageView = cell.getImageView();
105 | if (indexPath.getSection() == 4) {
106 | int paddingLeft = (int) Math.ceil(8 * getResources().getDisplayMetrics().density);
107 | imageView.setPadding(paddingLeft, 0, 0, 0);
108 | imageView.setImageDrawable(getDrawableForRowAtIndexPath(indexPath));
109 | } else {
110 | imageView.setPadding(0, 0, 0, 0);
111 | imageView.setImageDrawable(null);
112 | }
113 | }
114 |
115 | private void setupLayout(ATableViewCell cell, NSIndexPath indexPath) {
116 | TextView textLabel = (TextView) cell.findViewById(R.id.textLabel);
117 |
118 | int maxLines = 1;
119 | TruncateAt truncateAt = TruncateAt.END;
120 | LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) textLabel.getLayoutParams();
121 | params.topMargin = params.bottomMargin = 0;
122 |
123 | // add multiline to textView apart from WRAP_CONTENT to make height dynamic.
124 | if (indexPath.getSection() == 7) {
125 | maxLines = Integer.MAX_VALUE;
126 | params.topMargin = (int) getResources().getDimension(R.dimen.atv_cell_content_margin);
127 | params.bottomMargin = (int) getResources().getDimension(R.dimen.atv_cell_content_margin);
128 | truncateAt = null;
129 | }
130 |
131 | textLabel.setLayoutParams(params);
132 | textLabel.setMaxLines(maxLines);
133 | textLabel.setEllipsize(truncateAt);
134 | }
135 |
136 | @Override
137 | public ATableViewCell cellForRowAtIndexPath(ATableView tableView, NSIndexPath indexPath) {
138 | String cellIdentifier = "CellIdentifier0";
139 | ATableViewCellStyle cellStyle = ATableViewCellStyle.Default;
140 | ATableViewCellAccessoryType accessoryType = ATableViewCellAccessoryType.None;
141 | ATableViewCellSelectionStyle selectionStyle = ATableViewCellSelectionStyle.Blue;
142 |
143 | // set proper style and identifier for cells on each section.
144 | int section = indexPath.getSection();
145 | if (section == 0) {
146 | cellIdentifier = "CellIdentifier1";
147 | cellStyle = ATableViewCellStyle.Subtitle;
148 | accessoryType = ATableViewCellAccessoryType.DisclosureIndicator;
149 | } else if (section == 1) {
150 | cellIdentifier = "CellIdentifier2";
151 | cellStyle = ATableViewCellStyle.Value1;
152 | accessoryType = ATableViewCellAccessoryType.DisclosureButton;
153 | } else if (section == 2) {
154 | cellIdentifier = "CellIdentifier3";
155 | cellStyle = ATableViewCellStyle.Value2;
156 | accessoryType = ATableViewCellAccessoryType.Checkmark;
157 | } else if (section == 5) {
158 | cellIdentifier = "CustomCellIdentifier";
159 | selectionStyle = ATableViewCellSelectionStyle.Gray;
160 | } else if (section == 7) {
161 | selectionStyle = ATableViewCellSelectionStyle.None;
162 | }
163 |
164 | // get row data.
165 | int row = indexPath.getRow();
166 | String province = mProvinces.get(section).get(row);
167 |
168 | ATableViewCell cell = null;
169 | if (section != 5) {
170 | cell = dequeueReusableCellWithIdentifier(cellIdentifier);
171 | if (cell == null) {
172 | cell = new ATableViewCell(cellStyle, cellIdentifier, getActivity());
173 | }
174 |
175 | cell.setSelectionStyle(selectionStyle);
176 | cell.setAccessoryType(accessoryType);
177 |
178 | // imageView
179 | setupImageView(cell, indexPath);
180 |
181 | // textLabel
182 | cell.getTextLabel().setText(province);
183 |
184 | // detailTextLabel
185 | TextView detailTextLabel = cell.getDetailTextLabel();
186 | if (detailTextLabel != null) {
187 | String capital = mCapitals.get(section).get(row);
188 | detailTextLabel.setText(capital);
189 | }
190 |
191 | setupLayout(cell, indexPath);
192 | } else {
193 | MyCustomCell customCell = (MyCustomCell)dequeueReusableCellWithIdentifier(cellIdentifier);
194 | if (cell == null) {
195 | customCell = new MyCustomCell(ATableViewCellStyle.Default, cellIdentifier, getActivity());
196 | customCell.setSelectionStyle(selectionStyle);
197 | customCell.setAccessoryType(accessoryType);
198 | }
199 |
200 | // customLabel
201 | customCell.getTextLabel().setText(province);
202 |
203 | cell = customCell;
204 | }
205 |
206 | return cell;
207 | }
208 |
209 | @Override
210 | public int numberOfRowsInSection(ATableView tableView, int section) {
211 | return mProvinces.get(section).size();
212 | }
213 |
214 | @Override
215 | public int numberOfSectionsInTableView(ATableView tableView) {
216 | return mRegions.length;
217 | }
218 |
219 | @Override
220 | public String titleForHeaderInSection(ATableView tableView, int section) {
221 | return mRegions[section];
222 | }
223 |
224 | @Override
225 | public String titleForFooterInSection(ATableView tableView, int section) {
226 | return mNotes[section];
227 | }
228 |
229 | @Override
230 | public int numberOfRowStyles() {
231 | return 5;
232 | }
233 |
234 | @Override
235 | public int styleForRowAtIndexPath(NSIndexPath indexPath) {
236 | int style = indexPath.getRow();
237 |
238 | switch (indexPath.getSection()) {
239 | case 3: case 4: case 6: case 7: style = 3; break; // default
240 | case 5: style = 4; break; // custom
241 | default: break;
242 | }
243 |
244 | return style;
245 | }
246 | }
247 |
248 | private class MultipleStylesListDelegate extends ATableViewDelegate {
249 |
250 | @Override
251 | public int heightForRowAtIndexPath(ATableView tableView, NSIndexPath indexPath) {
252 | if (indexPath.getSection() == 7) {
253 | return ListView.LayoutParams.WRAP_CONTENT;
254 | }
255 |
256 | return super.heightForRowAtIndexPath(tableView, indexPath);
257 | }
258 |
259 | @Override
260 | public void didSelectRowAtIndexPath(ATableView tableView, NSIndexPath indexPath) {
261 | String text ="Selected IndexPath [" + indexPath.getSection() + "," + indexPath.getRow() + "]";
262 | Toast toast = Toast.makeText(getActivity(), text, Toast.LENGTH_SHORT);
263 | toast.show();
264 | }
265 |
266 | @Override
267 | public void accessoryButtonTappedForRowWithIndexPath(ATableView tableView, NSIndexPath indexPath) {
268 | String text = "Tapped DisclosureButton at indexPath [" + indexPath.getSection() + "," + indexPath.getRow() + "]";
269 | Toast toast = Toast.makeText(getActivity(), text, Toast.LENGTH_SHORT);
270 | toast.show();
271 | mTableView.clearChoices(); mTableView.requestLayout();
272 | }
273 | }
274 | }
275 |
--------------------------------------------------------------------------------
/demo/src/com/nakardo/atableview/demo/fragments/SimpleListFragment.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.demo.fragments;
2 |
3 | import android.view.Gravity;
4 | import android.widget.Toast;
5 |
6 | import com.nakardo.atableview.foundation.NSIndexPath;
7 | import com.nakardo.atableview.protocol.ATableViewDataSource;
8 | import com.nakardo.atableview.protocol.ATableViewDelegate;
9 | import com.nakardo.atableview.view.ATableView;
10 | import com.nakardo.atableview.view.ATableViewCell;
11 | import com.nakardo.atableview.view.ATableViewCell.ATableViewCellStyle;
12 |
13 | public class SimpleListFragment extends BaseListFragment {
14 | private static final int ADD_MORE_ROWS_INCREMENT = 100;
15 | private enum SimpleListSection { ROWS, SHOW_SELECTED_ROWS, ADD_MORE };
16 |
17 | private int mRowCount = ADD_MORE_ROWS_INCREMENT;
18 |
19 | private SimpleListSection getListSection(int section) {
20 | return SimpleListSection.values()[section];
21 | }
22 |
23 | @Override
24 | public ATableViewDataSource getDataSource() {
25 | return new SimpleListDataSource();
26 | }
27 |
28 | @Override
29 | public ATableViewDelegate getDelegate() {
30 | return new SimpleListDelegate();
31 | }
32 |
33 | private class SimpleListDataSource extends ATableViewDataSource {
34 |
35 | @Override
36 | public ATableViewCell cellForRowAtIndexPath(ATableView tableView, NSIndexPath indexPath) {
37 | final String cellIdentifier = "SIMPLE_CELL";
38 |
39 | ATableViewCell cell = dequeueReusableCellWithIdentifier(cellIdentifier);
40 | if (cell == null) {
41 | cell = new ATableViewCell(ATableViewCellStyle.Default, cellIdentifier, getActivity());
42 | }
43 |
44 | String text = "Add 100 More Rows";
45 |
46 | SimpleListSection theSection = getListSection(indexPath.getSection());
47 | if (theSection == SimpleListSection.ROWS) {
48 | text = "Row " + String.valueOf(indexPath.getRow());
49 | } else if (theSection == SimpleListSection.SHOW_SELECTED_ROWS) {
50 | text = "Show Selected Rows";
51 | }
52 | cell.getTextLabel().setText(text);
53 |
54 | return cell;
55 | }
56 |
57 | @Override
58 | public int numberOfSectionsInTableView(ATableView tableView) {
59 | return SimpleListSection.values().length;
60 | }
61 |
62 | @Override
63 | public int numberOfRowsInSection(ATableView tableView, int section) {
64 | int count = mRowCount;
65 |
66 | SimpleListSection theSection = getListSection(section);
67 | if (theSection == SimpleListSection.SHOW_SELECTED_ROWS ||
68 | theSection == SimpleListSection.ADD_MORE) {
69 | count = 1;
70 | }
71 |
72 | return count;
73 | }
74 | }
75 |
76 | private class SimpleListDelegate extends ATableViewDelegate {
77 |
78 | public String getIndexPathsText(NSIndexPath[] indexPaths) {
79 | String text = "";
80 | for (NSIndexPath indexPath : indexPaths) {
81 | text += indexPath.toString() + ", ";
82 | }
83 |
84 | return text.substring(0, text.length() - 2);
85 | }
86 |
87 | @Override
88 | public void didSelectRowAtIndexPath(ATableView tableView, NSIndexPath indexPath) {
89 |
90 | SimpleListSection theSection = getListSection(indexPath.getSection());
91 | if (theSection == SimpleListSection.SHOW_SELECTED_ROWS) {
92 | String text = "Selected indexPaths " + getIndexPathsText(mTableView.getIndexPathsForSelectedRows());
93 | Toast.makeText(getActivity(), text, Toast.LENGTH_SHORT).show();
94 | } else if (theSection == SimpleListSection.ADD_MORE) {
95 | mRowCount += ADD_MORE_ROWS_INCREMENT; mTableView.reloadData();
96 | }
97 | }
98 |
99 | @Override
100 | public void willDisplayCellForRowAtIndexPath(ATableView tableView, ATableViewCell cell, NSIndexPath indexPath) {
101 | int gravity = Gravity.LEFT;
102 |
103 | SimpleListSection theSection = getListSection(indexPath.getSection());
104 | if (theSection == SimpleListSection.SHOW_SELECTED_ROWS ||
105 | theSection == SimpleListSection.ADD_MORE) {
106 | gravity = Gravity.CENTER_HORIZONTAL;
107 | }
108 |
109 | cell.getTextLabel().setGravity(gravity);
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/demo/src/com/nakardo/atableview/demo/interfaces/TableViewConfigurationInterface.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.demo.interfaces;
2 |
3 |
4 | public interface TableViewConfigurationInterface {
5 | public void onTableViewConfigurationChanged();
6 | }
7 |
--------------------------------------------------------------------------------
/library/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
9 |
--------------------------------------------------------------------------------
/library/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/library/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-8
15 | android.library=true
16 |
--------------------------------------------------------------------------------
/library/res/color/atv_default_cell_text_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/library/res/color/atv_subtitle_cell_detail_text_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/library/res/color/atv_subtitle_cell_text_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/library/res/color/atv_value1_cell_detail_text_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/library/res/color/atv_value1_cell_title_text_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/library/res/color/atv_value2_cell_detail_text_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/library/res/color/atv_value2_cell_title_text_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/library/res/drawable-hdpi/checkmark_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-hdpi/checkmark_highlighted.png
--------------------------------------------------------------------------------
/library/res/drawable-hdpi/checkmark_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-hdpi/checkmark_normal.png
--------------------------------------------------------------------------------
/library/res/drawable-hdpi/disclosure_button_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-hdpi/disclosure_button_normal.png
--------------------------------------------------------------------------------
/library/res/drawable-hdpi/disclosure_button_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-hdpi/disclosure_button_pressed.png
--------------------------------------------------------------------------------
/library/res/drawable-hdpi/disclosure_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-hdpi/disclosure_highlighted.png
--------------------------------------------------------------------------------
/library/res/drawable-hdpi/disclosure_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-hdpi/disclosure_normal.png
--------------------------------------------------------------------------------
/library/res/drawable-hdpi/group_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-hdpi/group_background.png
--------------------------------------------------------------------------------
/library/res/drawable-hdpi/plain_header_background.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-hdpi/plain_header_background.9.png
--------------------------------------------------------------------------------
/library/res/drawable-mdpi/checkmark_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-mdpi/checkmark_highlighted.png
--------------------------------------------------------------------------------
/library/res/drawable-mdpi/checkmark_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-mdpi/checkmark_normal.png
--------------------------------------------------------------------------------
/library/res/drawable-mdpi/disclosure_button_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-mdpi/disclosure_button_normal.png
--------------------------------------------------------------------------------
/library/res/drawable-mdpi/disclosure_button_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-mdpi/disclosure_button_pressed.png
--------------------------------------------------------------------------------
/library/res/drawable-mdpi/disclosure_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-mdpi/disclosure_highlighted.png
--------------------------------------------------------------------------------
/library/res/drawable-mdpi/disclosure_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-mdpi/disclosure_normal.png
--------------------------------------------------------------------------------
/library/res/drawable-mdpi/group_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-mdpi/group_background.png
--------------------------------------------------------------------------------
/library/res/drawable-mdpi/plain_header_background.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-mdpi/plain_header_background.9.png
--------------------------------------------------------------------------------
/library/res/drawable-xhdpi/checkmark_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-xhdpi/checkmark_highlighted.png
--------------------------------------------------------------------------------
/library/res/drawable-xhdpi/checkmark_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-xhdpi/checkmark_normal.png
--------------------------------------------------------------------------------
/library/res/drawable-xhdpi/disclosure_button_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-xhdpi/disclosure_button_normal.png
--------------------------------------------------------------------------------
/library/res/drawable-xhdpi/disclosure_button_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-xhdpi/disclosure_button_pressed.png
--------------------------------------------------------------------------------
/library/res/drawable-xhdpi/disclosure_highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-xhdpi/disclosure_highlighted.png
--------------------------------------------------------------------------------
/library/res/drawable-xhdpi/disclosure_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-xhdpi/disclosure_normal.png
--------------------------------------------------------------------------------
/library/res/drawable-xhdpi/group_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-xhdpi/group_background.png
--------------------------------------------------------------------------------
/library/res/drawable-xhdpi/plain_header_background.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakardo/ATableView/c745d6b057b5958f115d1485968e034ddf2270c4/library/res/drawable-xhdpi/plain_header_background.9.png
--------------------------------------------------------------------------------
/library/res/drawable/checkmark.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/library/res/drawable/disclosure.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/library/res/drawable/disclosure_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/library/res/layout/atv_cell_default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
13 |
14 |
19 |
20 |
25 |
26 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/library/res/layout/atv_cell_subtitle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
13 |
14 |
19 |
20 |
25 |
26 |
32 |
33 |
40 |
41 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/library/res/layout/atv_cell_value1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
13 |
14 |
19 |
20 |
25 |
26 |
33 |
34 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/library/res/layout/atv_cell_value2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
13 |
14 |
19 |
20 |
25 |
26 |
32 |
33 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/library/res/layout/atv_grouped_footer.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
--------------------------------------------------------------------------------
/library/res/layout/atv_grouped_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
--------------------------------------------------------------------------------
/library/res/layout/atv_plain_header_footer.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
--------------------------------------------------------------------------------
/library/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #D9D9D9
5 | #FFFFFF
6 | #9B9B9B
7 |
8 |
9 | #555555
10 |
11 |
12 | #4C566C
13 |
14 |
15 | #F5F5F5
16 | #D9D9D9
17 | #FFFFFF
18 |
19 |
20 | #058CF5
21 | #015EE6
22 |
23 |
24 | #CECECE
25 | #ABABAB
26 |
27 |
28 | #000000
29 |
30 |
31 | #000000
32 | #808080
33 |
34 |
35 | #000000
36 | #385487
37 |
38 |
39 | #526691
40 | #000000
41 |
42 | #FFFFFF
43 |
--------------------------------------------------------------------------------
/library/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 1dp
6 | 7dp
7 |
8 |
9 | 18sp
10 | 12dp
11 | 18dp
12 | 24px
13 |
14 |
15 | 8dp
16 | 20dp
17 | 10dp
18 |
19 |
20 | 20sp
21 | 16dp
22 | 6dp
23 |
24 |
25 | 18sp
26 | 10dp
27 | 6dp
28 |
29 |
30 | 10dp
31 |
32 |
33 | 44px
34 |
35 |
36 | 10dp
37 |
38 |
39 | 8dp
40 |
41 |
42 | 20sp
43 |
44 |
45 | 18sp
46 | 14sp
47 |
48 |
49 | 17sp
50 | 17sp
51 |
52 |
53 | 67dp
54 | 12sp
55 | 15sp
56 |
--------------------------------------------------------------------------------
/library/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/library/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
17 |
18 |
22 |
23 |
28 |
29 |
34 |
35 |
40 |
41 |
44 |
45 |
49 |
50 |
56 |
57 |
58 |
59 |
63 |
64 |
68 |
69 |
74 |
75 |
79 |
80 |
85 |
86 |
91 |
92 |
96 |
97 |
--------------------------------------------------------------------------------
/library/src/com/nakardo/atableview/foundation/NSIndexPath.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.foundation;
2 |
3 | public class NSIndexPath {
4 | private int mSection;
5 | private int mRow;
6 |
7 | private NSIndexPath(int row, int section) {
8 | mRow = row;
9 | mSection = section;
10 | }
11 |
12 | public static NSIndexPath indexPathForRowInSection(int row, int section) {
13 | return new NSIndexPath(row, section);
14 | }
15 |
16 | public int getSection() {
17 | return mSection;
18 | }
19 |
20 | public int getRow() {
21 | return mRow;
22 | }
23 |
24 | @Override
25 | public String toString() {
26 | return "[" + mRow + ", " + mSection + "]";
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/library/src/com/nakardo/atableview/internal/ATableViewAdapter.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.internal;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import android.content.res.Resources;
7 | import android.graphics.Rect;
8 | import android.graphics.drawable.ShapeDrawable;
9 | import android.graphics.drawable.StateListDrawable;
10 | import android.view.View;
11 | import android.view.View.MeasureSpec;
12 | import android.view.ViewGroup;
13 | import android.widget.AbsListView;
14 | import android.widget.BaseAdapter;
15 | import android.widget.ListView;
16 | import android.widget.TextView;
17 |
18 | import com.nakardo.atableview.R;
19 | import com.nakardo.atableview.foundation.NSIndexPath;
20 | import com.nakardo.atableview.internal.ATableViewCellAccessoryView.ATableViewCellAccessoryType;
21 | import com.nakardo.atableview.internal.ATableViewCellDrawable.ATableViewCellBackgroundStyle;
22 | import com.nakardo.atableview.internal.ATableViewHeaderFooterCell.ATableViewHeaderFooterCellType;
23 | import com.nakardo.atableview.protocol.ATableViewDataSource;
24 | import com.nakardo.atableview.protocol.ATableViewDataSourceExt;
25 | import com.nakardo.atableview.protocol.ATableViewDelegate;
26 | import com.nakardo.atableview.utils.DrawableUtils;
27 | import com.nakardo.atableview.view.ATableView;
28 | import com.nakardo.atableview.view.ATableView.ATableViewStyle;
29 | import com.nakardo.atableview.view.ATableViewCell;
30 | import com.nakardo.atableview.view.ATableViewCell.ATableViewCellSelectionStyle;
31 |
32 | public class ATableViewAdapter extends BaseAdapter {
33 | private List mHasHeader;
34 | private List mHasFooter;
35 | private List mHeadersHeight;
36 | private List mFootersHeight;
37 | private List mRows;
38 | private List> mRowsHeight;
39 |
40 | private ATableView mTableView;
41 |
42 | private void initialize() {
43 | mHasHeader = new ArrayList();
44 | mHasFooter = new ArrayList();
45 | mHeadersHeight = new ArrayList();
46 | mFootersHeight = new ArrayList();
47 | mRows = new ArrayList();
48 | mRowsHeight = new ArrayList>();
49 |
50 | int sections = 0;
51 |
52 | ATableViewDataSource dataSource = mTableView.getDataSource();
53 | ATableViewDelegate delegate = mTableView.getDelegate();
54 |
55 | // datasource & delegate setup.
56 | if (dataSource != null) {
57 | sections = dataSource.numberOfSectionsInTableView(mTableView);
58 | for (int s = 0; s < sections; s++) {
59 | Boolean hasHeader = false, hasFooter = false;
60 |
61 | // mark header if overridden in delegate, otherwise try to pull title instead.
62 | int headerHeight = delegate.heightForHeaderInSection(mTableView, s);
63 | if (headerHeight != ATableViewCell.LayoutParams.UNDEFINED ||
64 | dataSource.titleForHeaderInSection(mTableView, s) != null) {
65 | hasHeader = true;
66 | }
67 | mHeadersHeight.add(headerHeight);
68 | mHasHeader.add(hasHeader);
69 |
70 | // mark footer if overridden in delegate, otherwise try to pull title instead.
71 | int footerHeight = delegate.heightForFooterInSection(mTableView, s);
72 | if (footerHeight != ATableViewCell.LayoutParams.UNDEFINED ||
73 | dataSource.titleForFooterInSection(mTableView, s) != null) {
74 | hasFooter = true;
75 | }
76 | mFootersHeight.add(footerHeight);
77 | mHasFooter.add(hasFooter);
78 |
79 | // pull row count from datasource.
80 | mRows.add(dataSource.numberOfRowsInSection(mTableView, s));
81 |
82 | List sectionRowHeights = new ArrayList();
83 |
84 | // pull row heights.
85 | // closes #23, make sure to pull at least the default height for empty rows sections
86 | int r = mRows.get(s) - 1;
87 | do {
88 | NSIndexPath indexPath = NSIndexPath.indexPathForRowInSection(r, s);
89 | sectionRowHeights.add(delegate.heightForRowAtIndexPath(mTableView, indexPath));
90 | r--;
91 | } while (r >= 0);
92 | mRowsHeight.add(sectionRowHeights);
93 | }
94 | }
95 | }
96 |
97 | public ATableViewAdapter(ATableView tableView) {
98 | mTableView = tableView;
99 | initialize();
100 | }
101 |
102 | @Override
103 | public void notifyDataSetChanged() {
104 | initialize();
105 | super.notifyDataSetChanged();
106 | }
107 |
108 | public int getContentHeight() {
109 | float height = 0;
110 |
111 | // TODO we're supporting content height only for plain tables, it's more complicated for grouped style
112 | // since we would have to measure all headers & footers values.
113 | if (mTableView.getStyle() == ATableViewStyle.Plain) {
114 | float density = mTableView.getResources().getDisplayMetrics().density;
115 |
116 | // rows.
117 | for (List sectionHeights : mRowsHeight) {
118 | for (int rowHeight : sectionHeights) {
119 | height += rowHeight * density;
120 | }
121 | }
122 |
123 | // headers.
124 | for (int section = 0; section < mHeadersHeight.size(); section++) {
125 | height += hasHeader(section) ? getHeaderFooterRowHeight(section, false) : 0;
126 | }
127 |
128 | // footers.
129 | for (int section = 0; section < mFootersHeight.size(); section++) {
130 | height += hasFooter(section) ? getHeaderFooterRowHeight(section, true) : 0;
131 | }
132 |
133 | // MAGIC MAGIC MAGIC. for some reason we've to add the row count to the height.
134 | // might it be related with the ListView separators?
135 | height += getCount();
136 | }
137 |
138 | return (int) Math.floor(height);
139 | }
140 |
141 | public int getLastRowHeight() {
142 | List sectionHeights = mRowsHeight.get(mRowsHeight.size() - 1);
143 | return sectionHeights.get(sectionHeights.size() - 1);
144 | }
145 |
146 | public NSIndexPath getIndexPath(int position) {
147 | // closes #18, set offset in one by default only if we've a header in the very first
148 | // section of the table.
149 | int offset = hasHeader(0) ? 1 : 0, count = 0, limit = 0;
150 |
151 | int sections = mRows.size();
152 | for (int s = 0; s < sections; s++) {
153 | int rows = mRows.get(s);
154 |
155 | limit += rows + getHeaderFooterCountOffset(s);
156 | if (position < limit) {
157 | // offset is given by current pos, accumulated headers, footers and rows.
158 | int positionWithOffset = position - offset - count;
159 | return NSIndexPath.indexPathForRowInSection(positionWithOffset, s);
160 | }
161 | offset += getHeaderFooterCountOffset(s);
162 | count += rows;
163 | }
164 |
165 | return null;
166 | }
167 |
168 | public boolean hasHeader(int section) {
169 | if (mTableView.getStyle() == ATableViewStyle.Grouped) {
170 | return true;
171 | }
172 |
173 | return section < mHasHeader.size() && mHasHeader.get(section);
174 | }
175 |
176 | public boolean hasFooter(int section) {
177 | if (mTableView.getStyle() == ATableViewStyle.Grouped) {
178 | return true;
179 | }
180 |
181 | return section < mHasHeader.size() && mHasFooter.get(section);
182 | }
183 |
184 | public boolean isHeaderRow(int position) {
185 | int sections = mRows.size();
186 | for (int s = 0; s < sections; s++) {
187 | if (hasHeader(s) && position == 0) {
188 | return true;
189 | }
190 | position -= mRows.get(s) + getHeaderFooterCountOffset(s);
191 | }
192 |
193 | return false;
194 | }
195 |
196 | public boolean isFooterRow(int position) {
197 | int positionWithOffset = 0;
198 |
199 | int sections = mRows.size();
200 | for (int s = 0; s < sections; s++) {
201 | positionWithOffset += mRows.get(s) + getHeaderFooterCountOffset(s);
202 | if (hasFooter(s) && position - positionWithOffset == -1) {
203 | return true;
204 | }
205 | }
206 |
207 | return false;
208 | }
209 |
210 | private boolean isSingleRow(NSIndexPath indexPath) {
211 | return indexPath.getRow() == 0 && mRows.get(indexPath.getSection()) == 1;
212 | }
213 |
214 | private boolean isTopRow(NSIndexPath indexPath) {
215 | return indexPath.getRow() == 0 && mRows.get(indexPath.getSection()) > 1;
216 | }
217 |
218 | private boolean isBottomRow(NSIndexPath indexPath) {
219 | return indexPath.getRow() == mRows.get(indexPath.getSection()) - 1;
220 | }
221 |
222 | private int getMeasuredRowHeight(ATableViewCell cell, NSIndexPath indexPath, boolean cache) {
223 |
224 | // closes #12, use table width instead cell since sometimes returns zero for WRAP_CONTENT height cells.
225 | int widthMeasureSpec = MeasureSpec.makeMeasureSpec(mTableView.getWidth(), MeasureSpec.EXACTLY);
226 | int heightMeasureSpec = MeasureSpec.makeMeasureSpec(AbsListView.LayoutParams.WRAP_CONTENT, MeasureSpec.EXACTLY);
227 | cell.measure(widthMeasureSpec, heightMeasureSpec);
228 |
229 | // add measured height to cache, so we don't have to recalculate every time.
230 | int height = (int) (cell.getMeasuredHeight() / cell.getResources().getDisplayMetrics().density);
231 | if (cache) {
232 | mRowsHeight.get(indexPath.getSection()).set(indexPath.getRow(), height);
233 | }
234 |
235 | return height;
236 | }
237 |
238 | private int getRowHeight(ATableViewCell cell, NSIndexPath indexPath, ATableViewCellBackgroundStyle backgroundStyle) {
239 | Resources res = mTableView.getContext().getResources();
240 |
241 | // transform height constants into values if we've set so.
242 | // closes #7. it seems Android ~2.2 requires known row height to draw cell background drawable.
243 | int rowHeight = mRowsHeight.get(indexPath.getSection()).get(indexPath.getRow());
244 | if (rowHeight < 0) {
245 | // cached for performance, it might have some impact if user changes the text after layout.
246 | rowHeight = getMeasuredRowHeight(cell, indexPath, true);
247 | }
248 | rowHeight = (int) Math.ceil(rowHeight * res.getDisplayMetrics().density);
249 |
250 | // add extra height to rows depending on it's style.
251 | Rect padding = ATableViewCellDrawable.getContentPadding(mTableView, backgroundStyle);
252 | rowHeight += padding.top + padding.bottom;
253 |
254 | return rowHeight;
255 | }
256 |
257 | private int getHeaderFooterRowHeight(int section, boolean isFooterRow) {
258 | Resources res = mTableView.getResources();
259 |
260 | // pull height, it will default on delegate to UNDEFINED if not overridden.
261 | int rowHeight = ATableViewCell.LayoutParams.UNDEFINED;
262 | if (isFooterRow) {
263 | rowHeight = mFootersHeight.get(section);
264 | } else {
265 | rowHeight = mHeadersHeight.get(section);
266 | }
267 |
268 | // if undefined, set a valid height depending on table style, otherwise use overridden value.
269 | if (rowHeight == ATableViewCell.LayoutParams.UNDEFINED) {
270 | if (mTableView.getStyle() == ATableViewStyle.Plain) {
271 | rowHeight = (int) res.getDimension(R.dimen.atv_plain_section_header_height);
272 | } else {
273 | rowHeight = ListView.LayoutParams.WRAP_CONTENT;
274 | }
275 | }
276 |
277 | // convert row height value when an scalar was used.
278 | if (rowHeight > -1) {
279 | rowHeight = (int) Math.ceil(rowHeight * res.getDisplayMetrics().density);
280 | }
281 |
282 | return rowHeight;
283 | }
284 |
285 | private ATableViewCellBackgroundStyle getRowBackgroundStyle(NSIndexPath indexPath) {
286 | ATableViewCellBackgroundStyle backgroundStyle = ATableViewCellBackgroundStyle.Middle;
287 |
288 | if (isSingleRow(indexPath)) {
289 | backgroundStyle = ATableViewCellBackgroundStyle.Single;
290 | } else if (isTopRow(indexPath)) {
291 | backgroundStyle = ATableViewCellBackgroundStyle.Top;
292 | } else if (isBottomRow(indexPath)) {
293 | int section = indexPath.getSection();
294 | boolean nextSectionHasHeader = section < mRows.size() - 1 && !hasHeader(section + 1);
295 |
296 | // closes #19, plain tables should show separator if next section doesn't have a header.
297 | backgroundStyle = ATableViewCellBackgroundStyle.Bottom;
298 | if (mTableView.getStyle() == ATableViewStyle.Plain && nextSectionHasHeader) {
299 | backgroundStyle = ATableViewCellBackgroundStyle.PlainBottomDoubleLine;
300 | }
301 | }
302 |
303 | return backgroundStyle;
304 | }
305 |
306 | private ATableViewHeaderFooterCell getReusableHeaderFooterCell(View convertView, boolean isFooterRow) {
307 | ATableViewHeaderFooterCell cell = (ATableViewHeaderFooterCell) convertView;
308 | if (cell == null) {
309 | ATableViewHeaderFooterCellType type = ATableViewHeaderFooterCellType.Header;
310 | if (isFooterRow) {
311 | type = ATableViewHeaderFooterCellType.Footer;
312 | }
313 | cell = new ATableViewHeaderFooterCell(type, mTableView);
314 | }
315 |
316 | return cell;
317 | }
318 |
319 | private void setupHeaderFooterRowLayout(ATableViewHeaderFooterCell cell, NSIndexPath indexPath, boolean isFooterRow) {
320 | ATableViewDataSource dataSource = mTableView.getDataSource();
321 | int section = indexPath.getSection();
322 | Resources res = mTableView.getResources();
323 | TextView textLabel = cell.getTextLabel();
324 |
325 | // get text.
326 | String headerText = null;
327 | if (isFooterRow) {
328 | headerText = dataSource.titleForFooterInSection(mTableView, section);
329 | } else {
330 | headerText = dataSource.titleForHeaderInSection(mTableView, section);
331 | }
332 | textLabel.setText(headerText);
333 |
334 | // setup layout and background depending on table style.
335 | Rect padding = new Rect();
336 | if (mTableView.getStyle() == ATableViewStyle.Grouped) {
337 | boolean hasText = headerText != null && headerText.length() > 0;
338 |
339 | padding.left = padding.right = (int) res.getDimension(R.dimen.atv_grouped_section_header_footer_padding_left_right);
340 |
341 | // if we're on the very first header of the table and it has text, we've to add an extra padding
342 | // on top of the cell.
343 | padding.top = (int) res.getDimension(R.dimen.atv_grouped_section_header_padding_top);
344 | if (!isFooterRow && section == 0 && hasText) {
345 | padding.top = (int) res.getDimension(R.dimen.atv_grouped_section_header_first_row_padding_top);
346 | }
347 |
348 | // if we're on the last footer of the table, extra padding applies here as well.
349 | padding.bottom = (int) res.getDimension(R.dimen.atv_grouped_section_footer_padding_bottom);
350 | if (isFooterRow && section == mRows.size() - 1) {
351 | padding.bottom = (int) res.getDimension(R.dimen.atv_grouped_section_footer_last_row_padding_bottom);
352 | }
353 |
354 | // hide header or footer text if it's null.
355 | int visibility = headerText != null && headerText.length() > 0 ? View.VISIBLE : View.GONE;
356 | textLabel.setVisibility(visibility);
357 | } else {
358 | padding.left = (int) res.getDimension(R.dimen.atv_plain_section_header_padding_left);
359 | padding.right = (int) res.getDimension(R.dimen.atv_plain_section_header_padding_right);
360 |
361 | // set background for plain style.
362 | cell.setBackgroundResource(R.drawable.plain_header_background);
363 | }
364 | cell.setPadding(padding.left, padding.top, padding.right, padding.bottom);
365 |
366 | // setup layout height
367 | // closes #16, we've to set minHeight for grouped headers & footers as well to make it take effect.
368 | int rowHeight = getHeaderFooterRowHeight(indexPath.getSection(), isFooterRow);
369 | if (mTableView.getStyle() == ATableViewStyle.Grouped) {
370 | int minHeight = (int) res.getDimension(R.dimen.atv_grouped_section_header_footer_min_height);
371 | cell.setMinimumHeight(rowHeight < minHeight ? rowHeight : minHeight);
372 | }
373 |
374 | ListView.LayoutParams params = new ListView.LayoutParams(ListView.LayoutParams.MATCH_PARENT, rowHeight);
375 | cell.setLayoutParams(params);
376 | }
377 |
378 | private void setupRowLayout(ATableViewCell cell, NSIndexPath indexPath, int rowHeight) {
379 |
380 | // add extra padding for grouped style.
381 | if (mTableView.getStyle() == ATableViewStyle.Grouped) {
382 | int margin = (int) cell.getResources().getDimension(R.dimen.atv_cell_grouped_margins);
383 | cell.setPadding(margin, 0, margin, 0);
384 | }
385 |
386 | ListView.LayoutParams params = new ListView.LayoutParams(ListView.LayoutParams.MATCH_PARENT, rowHeight);
387 | cell.setLayoutParams(params);
388 | }
389 |
390 | private void setupRowBackgroundDrawable(ATableViewCell cell, NSIndexPath indexPath,
391 | ATableViewCellBackgroundStyle backgroundStyle, int rowHeight) {
392 |
393 | // setup background drawables.
394 | StateListDrawable drawable = new StateListDrawable();
395 |
396 | ATableViewCellSelectionStyle selectionStyle = cell.getSelectionStyle();
397 | if (selectionStyle != ATableViewCellSelectionStyle.None) {
398 | Resources res = mTableView.getContext().getResources();
399 |
400 | int startColor = res.getColor(R.color.atv_cell_selection_style_blue_start);
401 | int endColor = res.getColor(R.color.atv_cell_selection_style_blue_end);
402 |
403 | if (selectionStyle == ATableViewCellSelectionStyle.Gray) {
404 | startColor = res.getColor(R.color.atv_cell_selection_style_gray_start);
405 | endColor = res.getColor(R.color.atv_cell_selection_style_gray_end);
406 | }
407 |
408 | ShapeDrawable pressed = new ATableViewCellDrawable(mTableView, backgroundStyle, rowHeight, startColor, endColor);
409 | drawable.addState(new int[] { android.R.attr.state_selected }, pressed);
410 | drawable.addState(new int[] { android.R.attr.state_pressed }, pressed);
411 | drawable.addState(new int[] { android.R.attr.state_focused }, pressed);
412 | }
413 |
414 | int color = DrawableUtils.getRowBackgroundColor(mTableView, cell);
415 | ShapeDrawable normal = new ATableViewCellDrawable(mTableView, backgroundStyle, rowHeight, color);
416 | drawable.addState(new int[] {}, normal);
417 |
418 | // when extending
419 | ViewGroup backgroundView = (ViewGroup) cell.getBackgroundView();
420 | if (backgroundView == null) {
421 | throw new RuntimeException("Cannot find R.id.backgroundView on your cell custom layout, " +
422 | "please add it to remove this error.");
423 | }
424 | backgroundView.setBackgroundDrawable(drawable);
425 | }
426 |
427 | private void setupRowContentView(ATableViewCell cell, NSIndexPath indexPath) {
428 | ATableViewCellBackgroundStyle backgroundStyle = getRowBackgroundStyle(indexPath);
429 |
430 | // set margins accordingly to content view depending on stroke lines thickness.
431 | View contentView = cell.getContentView();
432 | Rect padding = ATableViewCellDrawable.getContentPadding(mTableView, backgroundStyle);
433 | contentView.setPadding(padding.left, padding.top, padding.right, padding.bottom);
434 | }
435 |
436 | private void setupRowAccessoryButtonDelegateCallback(ATableViewCell cell, final NSIndexPath indexPath) {
437 | ATableViewCellAccessoryType accessoryType = cell.getAccessoryType();
438 | if (accessoryType == ATableViewCellAccessoryType.DisclosureButton) {
439 | View accessoryView = cell.findViewById(R.id.accessoryView);
440 | accessoryView.setOnClickListener(new View.OnClickListener() {
441 | public void onClick(View v) {
442 | ATableViewDelegate delegate = mTableView.getDelegate();
443 | delegate.accessoryButtonTappedForRowWithIndexPath(mTableView, indexPath);
444 | }
445 | });
446 | }
447 | }
448 |
449 | private int getHeaderFooterStyleCount() {
450 | int count = 1;
451 |
452 | // closes #10. getViewTypeCount() is only called once by the adapter even when notifyDataSetChanged is invoked,
453 | // so we've to return header & footer styles even we don't have rows to display.
454 | if (mTableView.getStyle() == ATableViewStyle.Grouped) {
455 | count = 2;
456 | }
457 |
458 | return count;
459 | }
460 |
461 | private int getHeaderFooterCountOffset(int section) {
462 | return (hasHeader(section) ? 1 : 0) + (hasFooter(section) ? 1 : 0);
463 | }
464 |
465 | @Override
466 | public int getCount() {
467 | int count = 0;
468 |
469 | // count is given by number of rows in section plus its header & footer.
470 | for (int s = 0; s < mRows.size(); s++) {
471 | count += mRows.get(s) + getHeaderFooterCountOffset(s);
472 | }
473 |
474 | return count;
475 | }
476 |
477 | @Override
478 | public int getViewTypeCount() {
479 | int count = getHeaderFooterStyleCount();
480 |
481 | // count must be 1 always, either we don't have any rows, plus the additional count for header & footers.
482 | ATableViewDataSource dataSource = mTableView.getDataSource();
483 | if (dataSource instanceof ATableViewDataSourceExt) {
484 | // TODO should add custom headers & footers to view count here when supported.
485 | // getViewTypeCount() is called only once, so no effect if this value is changed on runtime by the user.
486 | count += ((ATableViewDataSourceExt) dataSource).numberOfRowStyles();
487 | } else {
488 | count += 1;
489 | }
490 |
491 | return count;
492 | }
493 |
494 | @Override
495 | public int getItemViewType(int position) {
496 | int viewType = 0;
497 |
498 | int viewTypeCount = getViewTypeCount();
499 | if (viewTypeCount > 1) {
500 | if (isHeaderRow(position) && mTableView.getStyle() == ATableViewStyle.Grouped) {
501 | viewType = viewTypeCount - 2; // additional style for groped headers.
502 | } else if (isHeaderRow(position) || isFooterRow(position)) {
503 | viewType = viewTypeCount - 1; // for plain tables, headers and footers share same style.
504 | } else {
505 | ATableViewDataSource dataSource = mTableView.getDataSource();
506 | if (dataSource instanceof ATableViewDataSourceExt) {
507 | NSIndexPath indexPath = getIndexPath(position);
508 | viewType = ((ATableViewDataSourceExt) dataSource).styleForRowAtIndexPath(indexPath);
509 | }
510 | }
511 | }
512 |
513 | return viewType;
514 | }
515 |
516 | @Override
517 | public Object getItem(int position) {
518 | return null;
519 | }
520 |
521 | @Override
522 | public long getItemId(int position) {
523 | return position;
524 | }
525 |
526 | @Override
527 | public View getView(int position, View convertView, ViewGroup parent) {
528 | boolean isHeaderRow = isHeaderRow(position);
529 | boolean isFooterRow = isFooterRow(position);
530 |
531 | NSIndexPath indexPath = getIndexPath(position);
532 | if (isHeaderRow || isFooterRow) {
533 | ATableViewHeaderFooterCell cell = getReusableHeaderFooterCell(convertView, isFooterRow);
534 |
535 | // setup.
536 | setupHeaderFooterRowLayout(cell, indexPath, isFooterRow);
537 |
538 | convertView = cell;
539 | } else {
540 | ATableViewCell cell = (ATableViewCell)convertView;
541 |
542 | ATableViewDataSource dataSource = mTableView.getDataSource();
543 | dataSource.setReusableCell(cell);
544 |
545 | cell = dataSource.cellForRowAtIndexPath(mTableView, indexPath);
546 |
547 | ATableViewCellBackgroundStyle backgroundStyle = getRowBackgroundStyle(indexPath);
548 | int rowHeight = getRowHeight(cell, indexPath, backgroundStyle);
549 |
550 | // setup.
551 | setupRowLayout(cell, indexPath, rowHeight);
552 | setupRowBackgroundDrawable(cell, indexPath, backgroundStyle, rowHeight);
553 | setupRowContentView(cell, indexPath);
554 | setupRowAccessoryButtonDelegateCallback(cell, indexPath);
555 |
556 | // notify delegate we're about drawing the cell, so it can make changes to layout before drawing.
557 | ATableViewDelegate delegate = mTableView.getDelegate();
558 | delegate.willDisplayCellForRowAtIndexPath(mTableView, cell, indexPath);
559 |
560 | convertView = cell;
561 | }
562 |
563 | return convertView;
564 | }
565 |
566 | @Override
567 | public boolean isEnabled(int position) {
568 | // TODO disable sounds for header and footer rows, should be changed when supporting clicks on those views.
569 | if (isHeaderRow(position) || isFooterRow(position)) {
570 | return false;
571 | }
572 |
573 | return super.isEnabled(position);
574 | }
575 | }
576 |
--------------------------------------------------------------------------------
/library/src/com/nakardo/atableview/internal/ATableViewCellAccessoryView.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.internal;
2 |
3 | import android.content.Context;
4 | import android.content.res.Resources;
5 | import android.view.View;
6 | import android.widget.ImageView;
7 | import android.widget.LinearLayout;
8 | import android.widget.LinearLayout.LayoutParams;
9 |
10 | import com.nakardo.atableview.R;
11 | import com.nakardo.atableview.view.ATableViewCell;
12 |
13 | // TODO this class should be generic, maybe we could change extension into a ViewGroup and place accessory within.
14 | public class ATableViewCellAccessoryView extends ImageView {
15 | public enum ATableViewCellAccessoryType { None, DisclosureIndicator, DisclosureButton, Checkmark };
16 |
17 | public ATableViewCellAccessoryView(Context context) {
18 | super(context);
19 | }
20 |
21 | public static class Builder {
22 | private ATableViewCell mTableViewCell;
23 | private ATableViewCellAccessoryType mAccessoryType;
24 |
25 | private static ImageView getAccessoryView(ATableViewCell cell, ATableViewCellAccessoryType accessoryType) {
26 | LinearLayout containerView = (LinearLayout) cell.findViewById(R.id.containerView);
27 |
28 | // check if accessoryView already exists for current cell before creating a new instance.
29 | ImageView accessoryView = (ImageView) containerView.findViewById(R.id.accessoryView);
30 | if (accessoryView == null) {
31 | Resources res = cell.getResources();
32 |
33 | // get marginRight for accessoryView, DisclosureButton has a different one.
34 | LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
35 | int marginRight = (int) res.getDimension(R.dimen.atv_cell_content_margin);
36 | if (accessoryType == ATableViewCellAccessoryType.DisclosureButton) {
37 | marginRight = (int) res.getDimension(R.dimen.atv_cell_disclosure_button_margin_right);
38 | }
39 | params.setMargins(0, 0, marginRight, 0);
40 |
41 | // setup.
42 | accessoryView = new ATableViewCellAccessoryView(cell.getContext());
43 | accessoryView.setId(R.id.accessoryView);
44 | accessoryView.setLayoutParams(params);
45 |
46 | containerView.addView(accessoryView);
47 | }
48 |
49 | return accessoryView;
50 | }
51 |
52 | private static void createAccessoryView(ATableViewCell cell, ATableViewCellAccessoryType accessoryType) {
53 | boolean isClickeable = false;
54 | int visibility = View.VISIBLE;
55 |
56 | // setup accessoryType always.
57 | int resId = android.R.color.transparent;
58 | switch (accessoryType) {
59 | case DisclosureIndicator:
60 | resId = R.drawable.disclosure;
61 | break;
62 | case DisclosureButton:
63 | resId = R.drawable.disclosure_button;
64 | isClickeable = true;
65 | break;
66 | case Checkmark:
67 | resId = R.drawable.checkmark;
68 | break;
69 | default:
70 | visibility = View.GONE;
71 | break;
72 | }
73 |
74 | // get accessoryView for given accessoryType.
75 | ImageView accessoryView = getAccessoryView(cell, accessoryType);
76 | accessoryView.setImageResource(resId);
77 | accessoryView.setClickable(isClickeable);
78 | accessoryView.setVisibility(visibility);
79 | }
80 |
81 | public Builder(ATableViewCell cell) {
82 | mTableViewCell = cell;
83 | }
84 |
85 | public Builder setAccessoryType(ATableViewCellAccessoryType accessoryType) {
86 | mAccessoryType = accessoryType;
87 | return this;
88 | }
89 |
90 | public void create() {
91 | createAccessoryView(mTableViewCell, mAccessoryType);
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/library/src/com/nakardo/atableview/internal/ATableViewCellClickListener.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.internal;
2 |
3 | import android.view.View;
4 | import android.widget.AdapterView;
5 | import android.widget.AdapterView.OnItemClickListener;
6 |
7 | import com.nakardo.atableview.protocol.ATableViewDelegate;
8 | import com.nakardo.atableview.view.ATableView;
9 | import com.nakardo.atableview.view.ATableViewCell;
10 |
11 | public class ATableViewCellClickListener implements OnItemClickListener {
12 | private ATableView mTableView;
13 |
14 | public ATableViewCellClickListener(ATableView tableView) {
15 | mTableView = tableView;
16 | }
17 |
18 | @Override
19 | public void onItemClick(AdapterView> adapter, View view, int pos, long id) {
20 |
21 | // make sure we're clicking a cell, do not send callbacks for header or footer rows.
22 | if (view instanceof ATableViewCell) {
23 |
24 | // don't throw up selection events if it's not allowed by the table configuration.
25 | ATableView tableView = (ATableView) view.getParent();
26 | if (tableView.getAllowsSelection()) {
27 | ATableViewDelegate delegate = mTableView.getDelegate();
28 | delegate.didSelectRowAtIndexPath(mTableView, mTableView.getInternalAdapter().getIndexPath(pos));
29 | }
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/library/src/com/nakardo/atableview/internal/ATableViewCellContainerView.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.internal;
2 |
3 | import com.nakardo.atableview.view.ATableViewCell;
4 | import com.nakardo.atableview.view.ATableViewCell.ATableViewCellSelectionStyle;
5 |
6 | import android.content.Context;
7 | import android.util.AttributeSet;
8 | import android.view.View;
9 | import android.view.ViewParent;
10 | import android.widget.LinearLayout;
11 |
12 | public class ATableViewCellContainerView extends LinearLayout {
13 |
14 | private static ATableViewCell getContainerCell(View view) {
15 | ViewParent parent = view.getParent();
16 | while (parent != null) {
17 | if (parent instanceof ATableViewCell) return (ATableViewCell) parent;
18 | parent = parent.getParent();
19 | }
20 |
21 | return null;
22 | }
23 |
24 | public ATableViewCellContainerView(Context context) {
25 | super(context);
26 | }
27 |
28 | public ATableViewCellContainerView(Context context, AttributeSet attrs) {
29 | super(context, attrs);
30 | }
31 |
32 | @Override
33 | public void setPressed(boolean pressed) {
34 | if (pressed) {
35 | ATableViewCell cell = getContainerCell(this);
36 | if (cell != null && cell.getSelectionStyle() == ATableViewCellSelectionStyle.None) {
37 | return;
38 | }
39 | }
40 |
41 | super.setPressed(pressed);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/library/src/com/nakardo/atableview/internal/ATableViewCellDrawable.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.internal;
2 |
3 | import android.content.res.Resources;
4 | import android.graphics.Canvas;
5 | import android.graphics.LinearGradient;
6 | import android.graphics.Matrix;
7 | import android.graphics.Paint;
8 | import android.graphics.Rect;
9 | import android.graphics.RectF;
10 | import android.graphics.Shader;
11 | import android.graphics.drawable.ShapeDrawable;
12 | import android.graphics.drawable.shapes.RoundRectShape;
13 | import android.graphics.drawable.shapes.Shape;
14 |
15 | import com.nakardo.atableview.R;
16 | import com.nakardo.atableview.utils.DrawableUtils;
17 | import com.nakardo.atableview.view.ATableView;
18 | import com.nakardo.atableview.view.ATableView.ATableViewStyle;
19 | import com.nakardo.atableview.view.ATableViewCell.ATableViewCellSeparatorStyle;
20 |
21 | public class ATableViewCellDrawable extends ShapeDrawable {
22 |
23 | // PlainBottomDoubleLine applies for bottom rows on Plain tables without a section next to it.
24 | public enum ATableViewCellBackgroundStyle {
25 | Single, Top, Middle, Bottom, PlainBottomDoubleLine
26 | };
27 |
28 | private ATableView mTableView;
29 | private ATableViewCellBackgroundStyle mCellBackgroundStyle;
30 | private int mRowHeight;
31 | private int mStrokeWidth;
32 |
33 | private Paint mSeparatorPaint;
34 | private Paint mTopEtchedPaint;
35 | private Paint mBottomEtchedPaint;
36 | private Paint mBackgroundPaint;
37 | private Paint mSelectedPaint;
38 |
39 | private int mStartColor;
40 | private int mEndColor;
41 |
42 | private static RoundRectShape getShape(ATableView tableView, ATableViewCellBackgroundStyle backgroundStyle) {
43 | ATableViewStyle tableStyle = tableView.getStyle();
44 |
45 | float[] radius = new float[] { 0, 0, 0, 0, 0, 0, 0, 0 };
46 | if (tableStyle == ATableViewStyle.Grouped) {
47 | Resources res = tableView.getResources();
48 |
49 | float radii = Math.round(res.getDimension(R.dimen.atv_grouped_stroke_radius));
50 | if (backgroundStyle == ATableViewCellBackgroundStyle.Single) {
51 | radius = new float[] { radii, radii, radii, radii, radii, radii, radii, radii };
52 | } else if (backgroundStyle == ATableViewCellBackgroundStyle.Top) {
53 | radius = new float[] { radii, radii, radii, radii, 0, 0, 0, 0 };
54 | } else if (backgroundStyle == ATableViewCellBackgroundStyle.Bottom) {
55 | radius = new float[] { 0, 0, 0, 0, radii, radii, radii, radii };
56 | }
57 | }
58 |
59 | return new RoundRectShape(radius, null, null);
60 | }
61 |
62 | private static boolean isGroupedDoubleLineEtchedRow(ATableView tableView,
63 | ATableViewCellBackgroundStyle backgroundStyle) {
64 |
65 | return tableView.getStyle() == ATableViewStyle.Grouped &&
66 | tableView.getSeparatorStyle() == ATableViewCellSeparatorStyle.SingleLineEtched &&
67 | (backgroundStyle == ATableViewCellBackgroundStyle.Bottom ||
68 | backgroundStyle == ATableViewCellBackgroundStyle.Single);
69 | }
70 |
71 | public static Rect getContentPadding(ATableView tableView, ATableViewCellBackgroundStyle backgroundStyle) {
72 | int strokeWidth = DrawableUtils.getStrokeWidth(tableView.getResources());
73 | int margins = 0, marginTop = 0, marginBottom = 0;
74 |
75 | // calculate margins to avoid content to overlap with cell stroke lines.
76 | if (tableView.getStyle() == ATableViewStyle.Grouped) {
77 | margins = marginTop = strokeWidth;
78 |
79 | // double lines for etched single / bottom rows, this is a pain in the ass.
80 | if (isGroupedDoubleLineEtchedRow(tableView, backgroundStyle)) {
81 | marginBottom = strokeWidth * 2;
82 | } else if (backgroundStyle == ATableViewCellBackgroundStyle.Single ||
83 | backgroundStyle == ATableViewCellBackgroundStyle.Bottom) {
84 | marginBottom = strokeWidth;
85 | }
86 | } else if (backgroundStyle == ATableViewCellBackgroundStyle.Middle ||
87 | backgroundStyle == ATableViewCellBackgroundStyle.Bottom) {
88 | marginTop = strokeWidth;
89 | } else if (backgroundStyle == ATableViewCellBackgroundStyle.PlainBottomDoubleLine) {
90 | marginTop = marginBottom = strokeWidth;
91 | }
92 |
93 | return new Rect(margins, marginTop, margins, marginBottom);
94 | }
95 |
96 | public ATableViewCellDrawable(ATableView tableView, ATableViewCellBackgroundStyle backgroundStyle,
97 | int rowHeight, int backgroundColor) {
98 |
99 | super(getShape(tableView, backgroundStyle));
100 | Resources res = tableView.getResources();
101 |
102 | mTableView = tableView;
103 | mCellBackgroundStyle = backgroundStyle;
104 |
105 | // Closes #11, even we should be able to pull height from canvas it doesn't work well on ~2.2.
106 | mRowHeight = rowHeight;
107 |
108 | // separator.
109 | mSeparatorPaint = new Paint(getPaint());
110 | mSeparatorPaint.setColor(DrawableUtils.getSeparatorColor(mTableView));
111 |
112 | // calculate stroke width.
113 | mStrokeWidth = DrawableUtils.getStrokeWidth(res);
114 |
115 | // etched lines, only for grouped tables, with SingleLineEtched style.
116 | if (mTableView.getStyle() == ATableViewStyle.Grouped &&
117 | mTableView.getSeparatorStyle() == ATableViewCellSeparatorStyle.SingleLineEtched) {
118 | int etchedLineColor = res.getColor(R.color.atv_cell_grouped_etched_line);
119 |
120 | mBottomEtchedPaint = new Paint(getPaint());
121 | mBottomEtchedPaint.setColor(etchedLineColor);
122 |
123 | if (backgroundStyle == ATableViewCellBackgroundStyle.Top ||
124 | backgroundStyle == ATableViewCellBackgroundStyle.Single) {
125 | etchedLineColor = res.getColor(R.color.atv_cell_grouped_top_cell_etched_line);
126 | }
127 | mTopEtchedPaint = new Paint(getPaint());
128 | mTopEtchedPaint.setColor(etchedLineColor);
129 | }
130 |
131 | // background.
132 | mBackgroundPaint = new Paint(getPaint());
133 | mBackgroundPaint.setColor(backgroundColor);
134 | }
135 |
136 | public ATableViewCellDrawable(ATableView tableView, ATableViewCellBackgroundStyle backgroundStyle,
137 | int rowHeight, int startColor, int endColor) {
138 |
139 | this(tableView, backgroundStyle, rowHeight, android.R.color.transparent);
140 |
141 | // selected.
142 | mSelectedPaint = new Paint(getPaint());
143 | mStartColor = startColor;
144 | mEndColor = endColor;
145 | }
146 |
147 | private Matrix getSeparatorPaintMatrix(Rect bounds) {
148 | Matrix matrix = new Matrix();
149 |
150 | if (isGroupedDoubleLineEtchedRow(mTableView, mCellBackgroundStyle)) {
151 | RectF rect = new RectF(0, 0, bounds.right, bounds.bottom - mStrokeWidth);
152 | matrix.setRectToRect(new RectF(0, 0, bounds.right, bounds.bottom), rect, Matrix.ScaleToFit.FILL);
153 | }
154 |
155 | return matrix;
156 | }
157 |
158 | private Matrix getTopEtchedPaintMatrix(Rect bounds) {
159 | Matrix matrix = new Matrix();
160 |
161 | RectF rect = new RectF(mStrokeWidth, mStrokeWidth, bounds.right - mStrokeWidth, bounds.bottom);
162 | if (isGroupedDoubleLineEtchedRow(mTableView, mCellBackgroundStyle)) {
163 | rect.bottom -= mStrokeWidth * 2;
164 | }
165 | matrix.setRectToRect(new RectF(0, 0, bounds.right, bounds.bottom), rect, Matrix.ScaleToFit.FILL);
166 |
167 | return matrix;
168 | }
169 |
170 | private Matrix getBackgroundPaintMatrix(Rect bounds) {
171 | Matrix matrix = new Matrix();
172 |
173 | Rect padding = getContentPadding(mTableView, mCellBackgroundStyle);
174 | int paddingTop = padding.top;
175 | if (mTableView.getStyle() == ATableViewStyle.Grouped &&
176 | mTableView.getSeparatorStyle() == ATableViewCellSeparatorStyle.SingleLineEtched) {
177 | paddingTop *= 2;
178 | }
179 | RectF rect = new RectF(padding.left, paddingTop, bounds.right - padding.right, bounds.bottom - padding.bottom);
180 | matrix.setRectToRect(new RectF(0, 0, bounds.right, bounds.bottom), rect, Matrix.ScaleToFit.FILL);
181 |
182 | return matrix;
183 | }
184 |
185 | private Matrix getSelectedPaintMatrix(Rect bounds) {
186 | Matrix matrix = new Matrix();
187 |
188 | Rect padding = getContentPadding(mTableView, mCellBackgroundStyle);
189 | RectF rect = new RectF(padding.left, padding.top, bounds.right - padding.right, bounds.bottom - padding.bottom);
190 | if (isGroupedDoubleLineEtchedRow(mTableView, mCellBackgroundStyle)) {
191 | rect.bottom += mStrokeWidth;
192 | }
193 | matrix.setRectToRect(new RectF(0, 0, bounds.right, bounds.bottom), rect, Matrix.ScaleToFit.FILL);
194 |
195 | return matrix;
196 | }
197 |
198 | @Override
199 | protected void onDraw(Shape shape, Canvas canvas, Paint paint) {
200 | canvas.save();
201 | Rect bounds = canvas.getClipBounds();
202 |
203 | // bottom etched line.
204 | if (mBottomEtchedPaint != null) shape.draw(canvas, mBottomEtchedPaint);
205 | canvas.restore(); canvas.save();
206 |
207 | // separator.
208 | canvas.concat(getSeparatorPaintMatrix(bounds));
209 | shape.draw(canvas, mSeparatorPaint);
210 | canvas.restore(); canvas.save();
211 |
212 | // top etched line.
213 | canvas.concat(getTopEtchedPaintMatrix(bounds));
214 | if (mTopEtchedPaint != null) shape.draw(canvas, mTopEtchedPaint);
215 | canvas.restore(); canvas.save();
216 |
217 | // background.
218 | canvas.concat(getBackgroundPaintMatrix(bounds));
219 | shape.draw(canvas, mBackgroundPaint);
220 | canvas.restore(); canvas.save();
221 |
222 | // selected.
223 | canvas.concat(getSelectedPaintMatrix(bounds));
224 | if (mSelectedPaint != null) {
225 |
226 | // we'll set the selected color on onDraw event since we don't know drawable height up to here.
227 | Shader shader = new LinearGradient(0, 0, 0, mRowHeight, mStartColor, mEndColor, Shader.TileMode.MIRROR);
228 | mSelectedPaint.setShader(shader);
229 |
230 | shape.draw(canvas, mSelectedPaint);
231 | }
232 | }
233 | }
234 |
--------------------------------------------------------------------------------
/library/src/com/nakardo/atableview/internal/ATableViewHeaderFooterCell.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.internal;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.widget.FrameLayout;
6 |
7 | import com.nakardo.atableview.R;
8 | import com.nakardo.atableview.uikit.UILabel;
9 | import com.nakardo.atableview.view.ATableView;
10 | import com.nakardo.atableview.view.ATableView.ATableViewStyle;
11 |
12 | public class ATableViewHeaderFooterCell extends FrameLayout {
13 | public enum ATableViewHeaderFooterCellType { Header, Footer };
14 |
15 | private UILabel mTextLabel;
16 |
17 | protected static int getLayout(ATableViewHeaderFooterCellType type, ATableView tableView) {
18 | ATableViewStyle style = tableView.getStyle();
19 | if (ATableViewStyle.Grouped == style) {
20 | if (ATableViewHeaderFooterCellType.Header == type) {
21 | return R.layout.atv_grouped_header;
22 | }
23 |
24 | return R.layout.atv_grouped_footer;
25 | }
26 |
27 | return R.layout.atv_plain_header_footer;
28 | }
29 |
30 | public ATableViewHeaderFooterCell(ATableViewHeaderFooterCellType type, ATableView tableView) {
31 | super(tableView.getContext());
32 | LayoutInflater.from(getContext()).inflate(getLayout(type, tableView), this, true);
33 |
34 | mTextLabel = (UILabel) findViewById(R.id.textLabel);
35 | }
36 |
37 | public ATableViewHeaderFooterCell(Context context) {
38 | super(context);
39 | }
40 |
41 | public UILabel getTextLabel() {
42 | return mTextLabel;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/library/src/com/nakardo/atableview/internal/ATableViewPlainFooterDrawable.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.internal;
2 |
3 | import android.content.res.Resources;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.graphics.drawable.ShapeDrawable;
7 | import android.graphics.drawable.shapes.RectShape;
8 | import android.graphics.drawable.shapes.Shape;
9 |
10 | import com.nakardo.atableview.utils.DrawableUtils;
11 | import com.nakardo.atableview.view.ATableView;
12 |
13 | public class ATableViewPlainFooterDrawable extends ShapeDrawable {
14 | private Paint mStrokePaint;
15 |
16 | private int mStrokeWidth;
17 | private float mStrokeOffset;
18 |
19 | public ATableViewPlainFooterDrawable(ATableView tableView, int rowHeight) {
20 | super(new RectShape());
21 |
22 | Resources res = tableView.getResources();
23 |
24 | mStrokeWidth = DrawableUtils.getStrokeWidth(res);
25 | mStrokeOffset = (float) Math.ceil(rowHeight * res.getDisplayMetrics().density) + mStrokeWidth;
26 |
27 | // stroke.
28 | mStrokePaint = new Paint();
29 | mStrokePaint.setStyle(Paint.Style.STROKE);
30 | mStrokePaint.setStrokeWidth(mStrokeWidth);
31 | mStrokePaint.setColor(DrawableUtils.getSeparatorColor(tableView));
32 | }
33 |
34 | @Override
35 | protected void onDraw(Shape shape, Canvas canvas, Paint paint) {
36 | float offset = mStrokeWidth / 2;
37 | while (offset < shape.getHeight()) {
38 | canvas.drawLine(0, offset, shape.getWidth(), offset, mStrokePaint);
39 | offset += mStrokeOffset;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/library/src/com/nakardo/atableview/protocol/ATableViewDataSource.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.protocol;
2 |
3 | import com.nakardo.atableview.foundation.NSIndexPath;
4 | import com.nakardo.atableview.view.ATableView;
5 | import com.nakardo.atableview.view.ATableViewCell;
6 |
7 | public abstract class ATableViewDataSource {
8 | private ATableViewCell mReusableCell;
9 |
10 | public abstract ATableViewCell cellForRowAtIndexPath(ATableView tableView, NSIndexPath indexPath);
11 | public abstract int numberOfRowsInSection(ATableView tableView, int section);
12 |
13 | public int numberOfSectionsInTableView(ATableView tableView) {
14 | return 1;
15 | }
16 |
17 | public String titleForHeaderInSection(ATableView tableView, int section) {
18 | return null;
19 | }
20 |
21 | public String titleForFooterInSection(ATableView tableView, int section) {
22 | return null;
23 | }
24 |
25 | public ATableViewCell dequeueReusableCellWithIdentifier(String cellIdentifier) {
26 | if (cellIdentifier != null && mReusableCell != null &&
27 | cellIdentifier.equals(mReusableCell.getReuseIdentifier())) {
28 | return mReusableCell;
29 | }
30 |
31 | return null;
32 | }
33 |
34 | public void setReusableCell(ATableViewCell reusableCell) {
35 | mReusableCell = reusableCell;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/library/src/com/nakardo/atableview/protocol/ATableViewDataSourceExt.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.protocol;
2 |
3 | import com.nakardo.atableview.foundation.NSIndexPath;
4 |
5 | public abstract class ATableViewDataSourceExt extends ATableViewDataSource {
6 | public abstract int numberOfRowStyles();
7 | public abstract int styleForRowAtIndexPath(NSIndexPath indexPath);
8 | }
9 |
--------------------------------------------------------------------------------
/library/src/com/nakardo/atableview/protocol/ATableViewDelegate.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.protocol;
2 |
3 | import com.nakardo.atableview.R;
4 | import com.nakardo.atableview.foundation.NSIndexPath;
5 | import com.nakardo.atableview.view.ATableView;
6 | import com.nakardo.atableview.view.ATableViewCell;
7 |
8 | public class ATableViewDelegate {
9 | public int heightForRowAtIndexPath(ATableView tableView, NSIndexPath indexPath) {
10 | return (int) tableView.getResources().getDimension(R.dimen.atv_cell_default_row_height);
11 | }
12 |
13 | public void willDisplayCellForRowAtIndexPath(ATableView tableView, ATableViewCell cell, NSIndexPath indexPath) {
14 | return;
15 | }
16 |
17 | public int heightForHeaderInSection(ATableView tableView, int section) {
18 | return ATableViewCell.LayoutParams.UNDEFINED;
19 | }
20 |
21 | public int heightForFooterInSection(ATableView tableView, int section) {
22 | return ATableViewCell.LayoutParams.UNDEFINED;
23 | }
24 |
25 | public void didSelectRowAtIndexPath(ATableView tableView, NSIndexPath indexPath) {
26 | return;
27 | }
28 |
29 | public void accessoryButtonTappedForRowWithIndexPath(ATableView tableView, NSIndexPath indexPath) {
30 | return;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/library/src/com/nakardo/atableview/uikit/UILabel.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.uikit;
2 |
3 | import java.io.InputStream;
4 |
5 | import android.content.Context;
6 | import android.content.res.AssetManager;
7 | import android.graphics.Typeface;
8 | import android.util.AttributeSet;
9 | import android.widget.TextView;
10 |
11 | public class UILabel extends TextView {
12 | private static final String BOLD_FONT_PATH = "fonts/Roboto-Bold.ttf";
13 | private static final String REGULAR_FONT_PATH = "fonts/Roboto-Regular.ttf";
14 |
15 | private static boolean assetExists(Context context, String path) {
16 | boolean exists = false;
17 | try {
18 | InputStream stream = context.getAssets().open(path); stream.close();
19 | exists = true;
20 | } catch (Exception e) {}
21 |
22 | return exists;
23 | }
24 |
25 | public UILabel(Context context) {
26 | super(context);
27 | }
28 |
29 | public UILabel(Context context, AttributeSet attrs) {
30 | super(context, attrs);
31 | }
32 |
33 | @Override
34 | public void setTypeface (Typeface tf, int style) {
35 | if (!isInEditMode()) {
36 | String customTypefacePath = REGULAR_FONT_PATH;
37 | if (style == Typeface.BOLD) {
38 | customTypefacePath = BOLD_FONT_PATH;
39 | }
40 |
41 | // load custom font if available on app bundle.
42 | if (assetExists(getContext(), customTypefacePath)) {
43 | AssetManager assets = getContext().getAssets();
44 | tf = Typeface.createFromAsset(assets, customTypefacePath);
45 | }
46 |
47 | super.setTypeface(tf, style);
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/library/src/com/nakardo/atableview/utils/DrawableUtils.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.utils;
2 |
3 | import android.content.res.Resources;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.Shader.TileMode;
7 | import android.graphics.drawable.BitmapDrawable;
8 | import android.graphics.drawable.ColorDrawable;
9 | import android.graphics.drawable.Drawable;
10 |
11 | import com.nakardo.atableview.R;
12 | import com.nakardo.atableview.view.ATableView;
13 | import com.nakardo.atableview.view.ATableView.ATableViewStyle;
14 | import com.nakardo.atableview.view.ATableViewCell;
15 |
16 | public class DrawableUtils {
17 |
18 | public static Drawable getTableBackgroundDrawable(ATableView tableView) {
19 | Drawable drawable = null;
20 |
21 | Resources res = tableView.getResources();
22 |
23 | // -1 implies no color defined.
24 | int color = tableView.getBackgroundColor();
25 | if (color == -1) {
26 | if (tableView.getStyle() == ATableViewStyle.Grouped) {
27 |
28 | // closes #20, tiled backgrounds defined on xml doesn't seems to work well on Android ~2.1.
29 | // setup gray striped background for plain style tables.
30 | Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.group_background);
31 |
32 | BitmapDrawable bitmapDrawable = new BitmapDrawable(bitmap);
33 | bitmapDrawable.setTileModeX(TileMode.REPEAT);
34 | bitmapDrawable.setTileModeY(TileMode.REPEAT);
35 |
36 | drawable = bitmapDrawable;
37 | } else {
38 | drawable = new ColorDrawable(res.getColor(R.color.atv_plain_background));
39 | }
40 | } else {
41 | drawable = new ColorDrawable(color);
42 | }
43 |
44 | return drawable;
45 | }
46 |
47 | public static int getRowBackgroundColor(ATableView tableView, ATableViewCell cell) {
48 | Resources res = tableView.getResources();
49 |
50 | // -1 implies no color defined.
51 | int color = cell.getBackgroundColor();
52 | if (color == -1) {
53 | int tableBackgroundColor = tableView.getBackgroundColor();
54 | if (tableBackgroundColor == - 1) {
55 | color = res.getColor(R.color.atv_plain_background);
56 | if (tableView.getStyle() == ATableViewStyle.Grouped) {
57 | color = res.getColor(R.color.atv_cell_grouped_background);
58 | }
59 | } else {
60 | color = tableBackgroundColor;
61 | }
62 | }
63 |
64 | return color;
65 | }
66 |
67 | public static int getStrokeWidth(Resources res) {
68 | return (int) Math.floor(res.getDimension(R.dimen.atv_stroke_width));
69 | }
70 |
71 | public static int getSeparatorColor(ATableView tableView) {
72 | Resources res = tableView.getResources();
73 |
74 | // pull color, -1 implies no custom color has being defined so we go with defaults.
75 | int color = tableView.getSeparatorColor();
76 | if (color == -1) {
77 | color = res.getColor(R.color.atv_plain_separator);
78 | if (tableView.getStyle() == ATableViewStyle.Grouped) {
79 | color = res.getColor(R.color.atv_grouped_separator);
80 | }
81 | }
82 |
83 | return color;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/library/src/com/nakardo/atableview/view/ATableView.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.view;
2 |
3 | import java.util.ArrayList;
4 |
5 | import android.content.Context;
6 | import android.util.AttributeSet;
7 | import android.util.SparseBooleanArray;
8 | import android.view.View;
9 | import android.view.ViewTreeObserver;
10 | import android.widget.AbsListView;
11 | import android.widget.FrameLayout;
12 | import android.widget.HeaderViewListAdapter;
13 | import android.widget.ListView;
14 |
15 | import com.nakardo.atableview.foundation.NSIndexPath;
16 | import com.nakardo.atableview.internal.ATableViewAdapter;
17 | import com.nakardo.atableview.internal.ATableViewCellClickListener;
18 | import com.nakardo.atableview.internal.ATableViewPlainFooterDrawable;
19 | import com.nakardo.atableview.protocol.ATableViewDataSource;
20 | import com.nakardo.atableview.protocol.ATableViewDelegate;
21 | import com.nakardo.atableview.utils.DrawableUtils;
22 | import com.nakardo.atableview.view.ATableViewCell.ATableViewCellSeparatorStyle;
23 |
24 | public class ATableView extends ListView {
25 | private static final ATableViewStyle DEFAULT_STYLE = ATableViewStyle.Plain;
26 |
27 | // UIView
28 | private int mBackgroundColor = -1;
29 |
30 | private ATableViewCellSeparatorStyle mSeparatorStyle = ATableViewCellSeparatorStyle.SingleLine;
31 | private int mSeparatorColor = -1;
32 | private ATableViewStyle mStyle = DEFAULT_STYLE;
33 | private boolean mAllowsSelection = true;
34 | private boolean mAllowsMultipleSelection = false;
35 | private ATableViewDataSource mDataSource;
36 | private ATableViewDelegate mDelegate = new ATableViewDelegate();
37 |
38 | public enum ATableViewStyle {
39 | Plain, Grouped
40 | };
41 |
42 | private void setupFooterView(int lastRowHeight) {
43 |
44 | // closes #12, add footer for plain style tables in order to make the effect of repeating
45 | // rows across table height.
46 | if (mStyle == ATableViewStyle.Plain) {
47 | final View footerView = new FrameLayout(getContext());
48 |
49 | // add listener to resize after layout has been completed.
50 | getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
51 | public void onGlobalLayout() {
52 | getViewTreeObserver().removeGlobalOnLayoutListener(this);
53 |
54 | int footerHeight = getHeight() - getInternalAdapter().getContentHeight();
55 | AbsListView.LayoutParams params = new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT,
56 | footerHeight > 0 ? footerHeight : 0);
57 | footerView.setLayoutParams(params);
58 | }
59 | });
60 |
61 | footerView.setBackgroundDrawable(new ATableViewPlainFooterDrawable(this, lastRowHeight));
62 | addFooterView(footerView);
63 | }
64 | }
65 |
66 | private void setupBackgroundDrawable() {
67 | setBackgroundDrawable(DrawableUtils.getTableBackgroundDrawable(this));
68 | }
69 |
70 | private int getSelectionMode() {
71 |
72 | // well, this is just a workaround since we've two variables in ios and only one in android
73 | // to define selection enabled and multiple selection.
74 | int choiceMode = CHOICE_MODE_SINGLE;
75 | if (mAllowsMultipleSelection) choiceMode = CHOICE_MODE_MULTIPLE;
76 |
77 | return choiceMode;
78 | }
79 |
80 | private void clearSelectedRows() {
81 | clearChoices(); requestLayout();
82 | }
83 |
84 | public ATableView(ATableViewStyle style, Context context) {
85 | super(context);
86 | mStyle = style;
87 |
88 | setSelector(android.R.color.transparent);
89 | setChoiceMode(getSelectionMode());
90 | setDivider(null);
91 | setDividerHeight(0);
92 | setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
93 | setScrollingCacheEnabled(false);
94 |
95 | setupBackgroundDrawable();
96 | }
97 |
98 | public ATableView(Context context) {
99 | super(context);
100 | }
101 |
102 | public ATableView(Context context, AttributeSet attrs) {
103 | super(context, attrs);
104 | }
105 |
106 | public ATableView(Context context, AttributeSet attrs, int defStyle) {
107 | super(context, attrs, defStyle);
108 | }
109 |
110 | public int getBackgroundColor() {
111 | return mBackgroundColor;
112 | }
113 | public void setBackgroundColor(int resId) {
114 | mBackgroundColor = resId; setupBackgroundDrawable();
115 | }
116 |
117 | public ATableViewCellSeparatorStyle getSeparatorStyle() {
118 | return mSeparatorStyle;
119 | }
120 | public void setSeparatorStyle(ATableViewCellSeparatorStyle separatorStyle) {
121 | mSeparatorStyle = separatorStyle;
122 | }
123 |
124 | public int getSeparatorColor() {
125 | return mSeparatorColor;
126 | }
127 | public void setSeparatorColor(int resId) {
128 | mSeparatorColor = resId;
129 | }
130 |
131 | public ATableViewStyle getStyle() {
132 | return mStyle;
133 | }
134 |
135 | public boolean getAllowsSelection() {
136 | return mAllowsSelection;
137 | }
138 | public void setAllowsSelection(boolean allowsSelection) {
139 | mAllowsSelection = allowsSelection;
140 |
141 | if (mAllowsSelection) setChoiceMode(getSelectionMode());
142 | else setChoiceMode(CHOICE_MODE_NONE);
143 |
144 | clearSelectedRows();
145 | }
146 |
147 | public boolean getAllowsMultipleSelection() {
148 | return mAllowsMultipleSelection;
149 | }
150 | public void setAllowsMultipleSelection(boolean allowsMultipleSelection) {
151 | mAllowsMultipleSelection = allowsMultipleSelection;
152 |
153 | if (mAllowsSelection) {
154 | setChoiceMode(getSelectionMode()); clearSelectedRows();
155 | }
156 | }
157 |
158 | public NSIndexPath getIndexPathForSelectedRow() {
159 | NSIndexPath indexPath = null;
160 |
161 | int position = getCheckedItemPosition();
162 | if (position != INVALID_POSITION) {
163 | indexPath = getInternalAdapter().getIndexPath(position);
164 | }
165 |
166 | return indexPath;
167 | }
168 |
169 | public NSIndexPath[] getIndexPathsForSelectedRows() {
170 | NSIndexPath[] indexPaths = null;
171 |
172 | SparseBooleanArray checkedList = getCheckedItemPositions();
173 | if (checkedList != null) {
174 | ArrayList indexPathList = new ArrayList();
175 |
176 | ATableViewAdapter adapter = getInternalAdapter();
177 | for (int i = 0; i < adapter.getCount(); i++) {
178 | if (checkedList.get(i)) {
179 | indexPathList.add(adapter.getIndexPath(i));
180 | }
181 | }
182 |
183 | indexPaths = indexPathList.toArray(new NSIndexPath[indexPathList.size()]);
184 | }
185 |
186 | return indexPaths;
187 | }
188 |
189 | public ATableViewDataSource getDataSource() {
190 | return mDataSource;
191 | }
192 | public void setDataSource(ATableViewDataSource dataSource) {
193 | mDataSource = dataSource;
194 | }
195 |
196 | public ATableViewDelegate getDelegate() {
197 | return mDelegate;
198 | }
199 | public void setDelegate(ATableViewDelegate delegate) {
200 | mDelegate = delegate;
201 | }
202 |
203 | public ATableViewAdapter getInternalAdapter() {
204 |
205 | // fixes bugs for tables which includes headers or footers.
206 | ATableViewAdapter adapter = null;
207 | if (getAdapter() instanceof HeaderViewListAdapter) {
208 | HeaderViewListAdapter headerAdapter = (HeaderViewListAdapter) getAdapter();
209 | adapter = (ATableViewAdapter) headerAdapter.getWrappedAdapter();
210 | } else {
211 | adapter = (ATableViewAdapter) getAdapter();
212 | }
213 |
214 | return adapter;
215 | }
216 |
217 | public void reloadData() {
218 | getInternalAdapter().notifyDataSetChanged();
219 | clearSelectedRows();
220 | }
221 |
222 | @Override
223 | protected void onAttachedToWindow() {
224 | ATableViewAdapter adapter = new ATableViewAdapter(this);
225 |
226 | // TODO we should handle the case last row is ListView.LayoutParams.WRAP_CONTENT, to get its height.
227 | // setup footer for plain tables to complete its height with empty rows.
228 | setupFooterView(adapter.getLastRowHeight());
229 |
230 | setAdapter(adapter);
231 | setOnItemClickListener(new ATableViewCellClickListener(this));
232 | super.onAttachedToWindow();
233 | }
234 | }
235 |
--------------------------------------------------------------------------------
/library/src/com/nakardo/atableview/view/ATableViewCell.java:
--------------------------------------------------------------------------------
1 | package com.nakardo.atableview.view;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.widget.Checkable;
7 | import android.widget.FrameLayout;
8 | import android.widget.ImageView;
9 | import android.widget.TextView;
10 |
11 | import com.nakardo.atableview.R;
12 | import com.nakardo.atableview.internal.ATableViewCellAccessoryView;
13 | import com.nakardo.atableview.internal.ATableViewCellAccessoryView.ATableViewCellAccessoryType;
14 |
15 | public class ATableViewCell extends FrameLayout implements Checkable {
16 | public enum ATableViewCellStyle { Default, Subtitle, Value1, Value2 };
17 | public enum ATableViewCellSelectionStyle { None, Blue, Gray };
18 | public enum ATableViewCellSeparatorStyle { None, SingleLine, SingleLineEtched };
19 |
20 | // UIView
21 | private int mBackgroundColor = -1;
22 |
23 | // internal
24 | private View mContainerView;
25 | private boolean mIsChecked;
26 |
27 | private String mReuseIdentifier;
28 | private TextView mTextLabel;
29 | private TextView mDetailTextLabel;
30 | private ImageView mImageView;
31 | private View mContentView;
32 | private View mBackgroundView;
33 | private ATableViewCellAccessoryType mAccessoryType = ATableViewCellAccessoryType.None;
34 | private ATableViewCellSelectionStyle mSelectionStyle = ATableViewCellSelectionStyle.Blue;
35 |
36 | protected int getLayout(ATableViewCellStyle style) {
37 | switch (style) {
38 | case Subtitle:
39 | return R.layout.atv_cell_subtitle;
40 | case Value1:
41 | return R.layout.atv_cell_value1;
42 | case Value2:
43 | return R.layout.atv_cell_value2;
44 | default:
45 | return R.layout.atv_cell_default;
46 | }
47 | }
48 |
49 | public ATableViewCell(ATableViewCellStyle style, String reuseIdentifier, Context context) {
50 | super(context);
51 | LayoutInflater.from(context).inflate(getLayout(style), this, true);
52 |
53 | mReuseIdentifier = reuseIdentifier;
54 | mTextLabel = (TextView)findViewById(R.id.textLabel);
55 | mDetailTextLabel = (TextView)findViewById(R.id.detailTextLabel);
56 | mImageView = (ImageView)findViewById(R.id.imageView);
57 | mContentView = findViewById(R.id.contentView);
58 | mBackgroundView = findViewById(R.id.backgroundView);
59 | mContainerView = findViewById(R.id.containerView);
60 | }
61 |
62 | public ATableViewCell(Context context) {
63 | super(context);
64 | }
65 |
66 | public View getInternalContainerView() {
67 | return mContainerView;
68 | }
69 |
70 | public int getBackgroundColor() {
71 | return mBackgroundColor;
72 | }
73 | public void setBackgroundColor(int resId) {
74 | mBackgroundColor = resId;
75 | }
76 |
77 | public String getReuseIdentifier() {
78 | return mReuseIdentifier;
79 | }
80 |
81 | public TextView getTextLabel() {
82 | return mTextLabel;
83 | }
84 |
85 | public TextView getDetailTextLabel() {
86 | return mDetailTextLabel;
87 | }
88 |
89 | public ImageView getImageView() {
90 | return mImageView;
91 | }
92 |
93 | public View getContentView() {
94 | return mContentView;
95 | }
96 |
97 | public View getBackgroundView() {
98 | return mBackgroundView;
99 | }
100 | public void setBackgroundView(View backgroundView) {
101 | mBackgroundView = backgroundView;
102 | }
103 |
104 | public ATableViewCellAccessoryType getAccessoryType() {
105 | return mAccessoryType;
106 | }
107 |
108 | public void setAccessoryType(ATableViewCellAccessoryType accessoryType) {
109 | mAccessoryType = accessoryType;
110 |
111 | // TODO build accessory view, it should support building accessories from any view.
112 | ATableViewCellAccessoryView.Builder builder = new ATableViewCellAccessoryView.Builder(this);
113 | builder.setAccessoryType(accessoryType);
114 | builder.create();
115 | }
116 |
117 | public ATableViewCellSelectionStyle getSelectionStyle() {
118 | return mSelectionStyle;
119 | }
120 | public void setSelectionStyle(ATableViewCellSelectionStyle selectionStyle) {
121 | mSelectionStyle = selectionStyle;
122 | }
123 |
124 | public class LayoutParams {
125 | public static final int UNDEFINED = -3;
126 | }
127 |
128 | @Override
129 | public void setPressed(boolean pressed) {
130 |
131 | // disable selection when it's not allowed by the table configuration.
132 | ATableView tableView = (ATableView) getParent();
133 | super.setPressed(tableView.getAllowsSelection() ? pressed : false);
134 | }
135 |
136 | @Override
137 | public void setSelected(boolean selected) {
138 |
139 | // disable selection if selectionStyle is none.
140 | super.setSelected(mSelectionStyle != ATableViewCellSelectionStyle.None ? selected : false);
141 | }
142 |
143 | @Override
144 | public boolean isChecked() {
145 | return mIsChecked;
146 | }
147 |
148 | @Override
149 | public void setChecked(boolean checked) {
150 | mIsChecked = checked; setSelected(mIsChecked);
151 | }
152 |
153 | @Override
154 | public void toggle() {
155 | mIsChecked = !mIsChecked; setSelected(mIsChecked);
156 | }
157 | }
158 |
--------------------------------------------------------------------------------