├── .gitignore
├── LICENSE
├── README.md
├── build.gradle
├── direct-select-example-advanced
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── ramotion
│ │ └── directselect
│ │ └── examples
│ │ └── advanced
│ │ ├── AdvancedExampleActivity.java
│ │ ├── AdvancedExampleCountryAdapter.java
│ │ ├── AdvancedExampleCountryPOJO.java
│ │ └── AdvancedExampleCountryPickerBox.java
│ └── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable
│ ├── ds_bg_list_selector.xml
│ ├── ds_bg_picker_box.xml
│ ├── ds_countries_ar.png
│ ├── ds_countries_au.png
│ ├── ds_countries_br.png
│ ├── ds_countries_ca.png
│ ├── ds_countries_cn.png
│ ├── ds_countries_dz.png
│ ├── ds_countries_in.png
│ ├── ds_countries_kz.png
│ ├── ds_countries_ru.png
│ ├── ds_countries_us.png
│ ├── ds_picker_box_arrows.png
│ └── ic_launcher_background.xml
│ ├── layout
│ ├── advanced_example_activity.xml
│ ├── advanced_example_country_cell.xml
│ ├── advanced_example_country_list_item.xml
│ └── advanced_example_country_picker_box.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ └── values
│ ├── arrays.xml
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
├── direct-select-example-basic
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── ramotion
│ │ └── directselect
│ │ └── examples
│ │ └── basic
│ │ └── BasicExampleActivity.java
│ └── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable
│ ├── ds_basic_example_custom_picker_box_bg.xml
│ └── ic_launcher_background.xml
│ ├── layout
│ └── ds_basic_example_activity.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ └── values
│ ├── arrays.xml
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
├── direct-select
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── ramotion
│ │ └── directselect
│ │ ├── AnimationListenerAdapter.java
│ │ ├── CustomListView.java
│ │ ├── DSAbstractPickerBox.java
│ │ ├── DSDefaultAdapter.java
│ │ ├── DSDefaultPickerBox.java
│ │ └── DSListView.java
│ └── res
│ ├── layout
│ ├── ds_default_cell.xml
│ ├── ds_default_list_item.xml
│ ├── ds_default_picker_box.xml
│ └── ds_list_view.xml
│ └── values
│ └── attr.xml
├── direct_select_preview.gif
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── header.png
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Java compiled classes #
2 | *.class
3 |
4 | # Package Files #
5 | *.apk
6 | *.ap_
7 |
8 | # IDEA Project files #
9 | *.iws
10 | *.iml
11 | *.ipr
12 | .idea/
13 |
14 | # Build directory #
15 | /build/
16 | /target/
17 | */target/
18 | */build/
19 |
20 | # Generated files #
21 | bin/
22 | gen/
23 |
24 | # Local props file #
25 | local.properties
26 |
27 | # Gradle cache #
28 | .gradle
29 |
30 | # OSX files #
31 | .DS_Store
32 |
33 | # NDK #
34 | obj/
35 |
36 | # files for the dex VM #
37 | *.dex
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Ramotion
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
DIRECT SELECT [JAVA]
7 |
8 | Selection widget with an ethereal, full-screen modal popup displaying the available choices
9 |
10 |
11 | ___
12 |
13 |
14 | We specialize in the designing and coding of custom UI for Mobile Apps and Websites.
15 |
16 |
17 |
18 | Stay tuned for the latest updates:
19 |
20 |
21 |
22 | Inspired by [Virgil Pana](https://dribbble.com/virgilpana) [shot](https://dribbble.com/shots/3876250-DirectSelect-Dropdown-ux)
23 |
24 | ## Requirements
25 | - Android 4.0 IceCreamSandwich (API lvl 14) or greater
26 | - Your favorite IDE
27 | ## Installation
28 | Just download the package from [here](http://central.maven.org/maven2/com/ramotion/directselect/direct-select/0.1.1/direct-select-0.1.1.aar) and add it to your project classpath, or use it as dependency in your build tool:
29 | - Gradle:
30 | ```groovy
31 | 'com.ramotion.directselect:direct-select:0.1.1'
32 | ```
33 | - SBT:
34 | ```scala
35 | libraryDependencies += "com.ramotion.directselect" % "direct-select" % "0.1.1"
36 | ```
37 | - Maven:
38 | ```xml
39 |
40 | com.ramotion.directselect
41 | direct-select
42 | 0.1.1
43 |
44 | ```
45 | ## Basic usage
46 | Basic usage assumes a simple configuration through xml layout without writing program code, but this doesn't provide the possibility to create cells with custom content layout for your lists and pickers.
47 | So, all you need is two elements in your layout:
48 | ```xml
49 |
50 |
56 |
57 |
71 |
72 |
79 |
80 |
81 | ```
82 | `DSListView` represents a list with options for the picker that shows up when the user touches a `DSDefaultPickerBox` element and hides when the user removes his finger from the screen. `DSListView` has a couple of custom attributes, some of them are required, some not, here is a list:
83 | - **`data_array`** is a required reference to your selector options represented as array of strings in application resources.
84 | - **`picker_box_view`** is a required reference to implemented picker box element, you can use default implementation provided by the library `DSDefaultPickerBox` or you can implement your own as shown in the advanced usage example in this repository.
85 | - **`selector_background`** is a drawable or color responsible for a highlighting of selector position when `DSListView` is shown on the screen. Using the same background as in your PickerBox element you can achieve a pretty nice and clean effect.
86 | - **`scale_animations`** is a boolean that turns on/off scale animations of the selected item. Try it.
87 | - **`scale_animations_factor`** is a float value that defines max scale ratio for scaling animation
88 | - **`scale_animations_pivot_center`** is a boolean that moves pivot point of scale animations to center of your element instead of default left aligned position.
89 | - **`selected_index`** is an integer that represents initially selected option.
90 |
91 | ## Advanced usage
92 | Here everything is more complicated. Let's start from creating layout files.
93 | 1. First of all we need to implement our custom cell layout, in separate xml file, eg `advanced_example_country_cell.xml`:
94 | ```xml
95 |
100 |
101 |
111 |
112 |
119 |
120 |
121 | ```
122 | 2. Now we need to create a layout for our cell in the list view, `advanced_example_country_list_item.xml`- it just wraps our newly created cell with `FrameLayout` for correct element animations and positioning inside the list view.
123 | ```xml
124 |
131 |
132 |
136 |
137 |
138 | ```
139 | 3. Third step - creation of our custom picker box layout, a new file named `advanced_example_country_picker_box.xml` that contains our custom cell layout, and inserts an additional custom elements that must appear only in picker box, like the direction arrows in our example.
140 | ```xml
141 |
147 |
148 |
152 |
153 |
166 |
167 |
168 | ```
169 | 4. Finally, we need to write some code. First of all - we need to prepare a dataset, our cell contains two items - a title and image, so we can't use the default `data_array` attribute from the basic example. Our structure can be represented by plain old java object with two appropriate fields.
170 | ```java
171 | public class AdvancedExampleCountryPOJO {
172 | private String title;
173 | private int icon;
174 |
175 | public AdvancedExampleCountryPOJO(String title, int icon) {
176 | this.title = title;
177 | this.icon = icon;
178 | }
179 |
180 | public static List getExampleDataset() {
181 | return Arrays.asList(
182 | new AdvancedExampleCountryPOJO("Russian Federation", R.drawable.ds_countries_ru),
183 | new AdvancedExampleCountryPOJO("Canada", R.drawable.ds_countries_ca),
184 | new AdvancedExampleCountryPOJO("United States of America", R.drawable.ds_countries_us),
185 | new AdvancedExampleCountryPOJO("China", R.drawable.ds_countries_cn),
186 | new AdvancedExampleCountryPOJO("Brazil", R.drawable.ds_countries_br),
187 | new AdvancedExampleCountryPOJO("Australia", R.drawable.ds_countries_au),
188 | new AdvancedExampleCountryPOJO("India", R.drawable.ds_countries_in),
189 | new AdvancedExampleCountryPOJO("Argentina", R.drawable.ds_countries_ar),
190 | new AdvancedExampleCountryPOJO("Kazakhstan", R.drawable.ds_countries_kz),
191 | new AdvancedExampleCountryPOJO("Algeria", R.drawable.ds_countries_dz)
192 | );
193 | }
194 |
195 | // getters, setters, equal, hashcode, etc.
196 | }
197 | ```
198 | 5. Now, to more complex things - we need to somehow provide our dataset to `DSListView`, for this purpose in Android we have a `android.widget.ArrayAdapter` class, so we need a custom implementation to map data from our POJO to the actual cell described earlier:
199 | ```java
200 | public class AdvancedExampleCountryAdapter extends ArrayAdapter {
201 | private List items;
202 | private Context context;
203 |
204 | public AdvancedExampleCountryAdapter(@NonNull Context context, int resource, @NonNull List objects) {
205 | super(context, resource, objects);
206 | this.items = objects;
207 | this.context = context;
208 | }
209 |
210 | @Override
211 | public long getItemId(int position) {
212 | return position;
213 | }
214 |
215 | @Override
216 | public boolean hasStableIds() {
217 | return true;
218 | }
219 |
220 | @Override
221 | public int getCount() {
222 | return items.size();
223 | }
224 |
225 | @NonNull
226 | @Override
227 | public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
228 | AdvancedExampleCountryAdapter.ViewHolder holder;
229 |
230 | if (null == convertView) {
231 | LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
232 | assert vi != null;
233 | convertView = vi.inflate(R.layout.advanced_example_country_list_item, parent, false);
234 | holder = new AdvancedExampleCountryAdapter.ViewHolder();
235 | holder.text = convertView.findViewById(R.id.custom_cell_text);
236 | holder.icon = convertView.findViewById(R.id.custom_cell_image);
237 | convertView.setTag(holder);
238 | } else {
239 | holder = (AdvancedExampleCountryAdapter.ViewHolder) convertView.getTag();
240 | }
241 | if (null != holder) {
242 | holder.text.setText(items.get(position).getTitle());
243 | holder.icon.setImageResource(items.get(position).getIcon());
244 | }
245 | return convertView;
246 | }
247 |
248 | private class ViewHolder {
249 | TextView text;
250 | ImageView icon;
251 | }
252 | }
253 |
254 | ```
255 | 6. Almost done, but before we put it all together, there is one more thing. We almost forgot about our custom picker box to map the selected cell from the list view to the actual displayed picker. So, we need to implement simple view that inflates our layout for the picker box described earlier. To guarantee correctness, work must extend the `DSAbstractPickerBox` class and implement some abstract methods:
256 | ```java
257 | public class AdvancedExampleCountryPickerBox extends DSAbstractPickerBox {
258 | private TextView text;
259 | private ImageView icon;
260 | private View cellRoot;
261 |
262 | public AdvancedExampleCountryPickerBox(@NonNull Context context) {
263 | this(context, null);
264 | }
265 |
266 | public AdvancedExampleCountryPickerBox(@NonNull Context context,
267 | @Nullable AttributeSet attrs) {
268 | this(context, attrs, 0);
269 | }
270 |
271 | public AdvancedExampleCountryPickerBox(@NonNull Context context,
272 | @Nullable AttributeSet attrs, int defStyleAttr) {
273 | super(context, attrs, defStyleAttr);
274 | init(context);
275 | }
276 |
277 | private void init(@NonNull Context context) {
278 | LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
279 | assert mInflater != null;
280 | mInflater.inflate(R.layout.advanced_example_country_picker_box, this, true);
281 | }
282 |
283 | @Override
284 | protected void onFinishInflate() {
285 | super.onFinishInflate();
286 | this.text = findViewById(R.id.custom_cell_text);
287 | this.icon = findViewById(R.id.custom_cell_image);
288 | this.cellRoot = findViewById(R.id.custom_cell_root);
289 | }
290 |
291 | @Override
292 | public void onSelect(AdvancedExampleCountryPOJO selectedItem, int selectedIndex) {
293 | this.text.setText(selectedItem.getTitle());
294 | this.icon.setImageResource(selectedItem.getIcon());
295 | }
296 |
297 | @Override
298 | public View getCellRoot() {
299 | return this.cellRoot;
300 | }
301 | }
302 | ```
303 | 7. Finally - put all parts together in the main activity layout and write some code in `MainActivity`:
304 | ```java
305 | public class AdvancedExampleActivity extends AppCompatActivity {
306 |
307 | @SuppressLint("ClickableViewAccessibility")
308 | @Override
309 | protected void onCreate(Bundle savedInstanceState) {
310 | super.onCreate(savedInstanceState);
311 | setContentView(R.layout.advanced_example_activity);
312 |
313 | // Prepare dataset
314 | List exampleDataSet = AdvancedExampleCountryPOJO.getExampleDataset();
315 |
316 | // Create adapter with our dataset
317 | ArrayAdapter adapter = new AdvancedExampleCountryAdapter(
318 | this, R.layout.advanced_example_country_list_item, exampleDataSet);
319 |
320 | // Set adapter to our DSListView
321 | DSListView pickerView = findViewById(R.id.ds_county_list);
322 | pickerView.setAdapter(adapter);
323 |
324 | }
325 | }
326 | ```
327 | That's all. There are still some unmentioned features, like the possibility to change the size and position of the list view and the possibility to change default cell text appearance through `cell-font-size` settings or through applying your custom style.
328 | Full examples with some comments and explanations can be found in this repository. Feel free to report bugs and ask questions.
329 |
330 |
331 |
332 | ## 📄 License
333 |
334 | Direct Select Android is released under the MIT license.
335 | See [LICENSE](./LICENSE) for details.
336 |
337 | This library is a part of a selection of our best UI open-source projects
338 |
339 | If you use the open-source library in your project, please make sure to credit and backlink to www.ramotion.com
340 |
341 | ## 📱 Get the Showroom App for Android to give it a try
342 | Try this UI component and more like this in our Android app. Contact us if interested.
343 |
344 |
345 |
346 |
347 |
348 |
349 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 |
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:3.3.1'
9 | classpath 'com.bmuschko:gradle-nexus-plugin:2.3.1'
10 | }
11 | }
12 |
13 | allprojects {
14 | repositories {
15 | google()
16 | jcenter()
17 | }
18 | }
19 |
20 | task clean(type: Delete) {
21 | delete rootProject.buildDir
22 | }
23 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 28
5 | defaultConfig {
6 | applicationId "com.ramotion.directselect.examples.advenced"
7 | minSdkVersion 14
8 | targetSdkVersion 28
9 | versionCode 2
10 | versionName "1.0.1"
11 |
12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | buildToolsVersion '28.0.3'
21 | }
22 |
23 | dependencies {
24 | implementation fileTree(include: ['*.jar'], dir: 'libs')
25 | implementation project(':direct-select')
26 | implementation 'androidx.appcompat:appcompat:1.0.2'
27 | }
28 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/java/com/ramotion/directselect/examples/advanced/AdvancedExampleActivity.java:
--------------------------------------------------------------------------------
1 | package com.ramotion.directselect.examples.advanced;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.os.Bundle;
5 | import android.view.Window;
6 | import android.view.WindowManager;
7 | import android.widget.ArrayAdapter;
8 |
9 | import com.ramotion.directselect.DSListView;
10 |
11 | import java.util.List;
12 |
13 | import androidx.appcompat.app.ActionBar;
14 | import androidx.appcompat.app.AppCompatActivity;
15 |
16 | public class AdvancedExampleActivity extends AppCompatActivity {
17 |
18 | @SuppressLint("ClickableViewAccessibility")
19 | @Override
20 | protected void onCreate(Bundle savedInstanceState) {
21 | super.onCreate(savedInstanceState);
22 |
23 | // Make activity fullscreen
24 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
25 | requestWindowFeature(Window.FEATURE_NO_TITLE);
26 | ActionBar supportActionBar = getSupportActionBar();
27 | if (null != supportActionBar)
28 | supportActionBar.hide();
29 |
30 | setContentView(R.layout.advanced_example_activity);
31 |
32 | // Prepare dataset
33 | List exampleDataSet = AdvancedExampleCountryPOJO.getExampleDataset();
34 |
35 | // Create adapter with our dataset
36 | ArrayAdapter adapter = new AdvancedExampleCountryAdapter(
37 | this, R.layout.advanced_example_country_list_item, exampleDataSet);
38 |
39 | // Set adapter to our DSListView
40 | DSListView pickerView = findViewById(R.id.ds_county_list);
41 | pickerView.setAdapter(adapter);
42 |
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/java/com/ramotion/directselect/examples/advanced/AdvancedExampleCountryAdapter.java:
--------------------------------------------------------------------------------
1 | package com.ramotion.directselect.examples.advanced;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.ArrayAdapter;
8 | import android.widget.ImageView;
9 | import android.widget.TextView;
10 |
11 |
12 | import java.util.List;
13 |
14 | import androidx.annotation.NonNull;
15 | import androidx.annotation.Nullable;
16 |
17 | public class AdvancedExampleCountryAdapter extends ArrayAdapter {
18 | private List items;
19 | private Context context;
20 |
21 | public AdvancedExampleCountryAdapter(@NonNull Context context, int resource, @NonNull List objects) {
22 | super(context, resource, objects);
23 | this.items = objects;
24 | this.context = context;
25 | }
26 |
27 | @Override
28 | public long getItemId(int position) {
29 | return position;
30 | }
31 |
32 | @Override
33 | public boolean hasStableIds() {
34 | return true;
35 | }
36 |
37 | @Override
38 | public int getCount() {
39 | return items.size();
40 | }
41 |
42 | @NonNull
43 | @Override
44 | public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
45 | AdvancedExampleCountryAdapter.ViewHolder holder;
46 |
47 | if (null == convertView) {
48 | LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
49 | assert vi != null;
50 | convertView = vi.inflate(R.layout.advanced_example_country_list_item, parent, false);
51 | holder = new AdvancedExampleCountryAdapter.ViewHolder();
52 | holder.text = convertView.findViewById(R.id.custom_cell_text);
53 | holder.icon = convertView.findViewById(R.id.custom_cell_image);
54 | convertView.setTag(holder);
55 | } else {
56 | holder = (AdvancedExampleCountryAdapter.ViewHolder) convertView.getTag();
57 | }
58 |
59 | if (null != holder) {
60 | holder.text.setText(items.get(position).getTitle());
61 | holder.icon.setImageResource(items.get(position).getIcon());
62 | }
63 | return convertView;
64 | }
65 |
66 | private class ViewHolder {
67 | TextView text;
68 | ImageView icon;
69 | }
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/java/com/ramotion/directselect/examples/advanced/AdvancedExampleCountryPOJO.java:
--------------------------------------------------------------------------------
1 | package com.ramotion.directselect.examples.advanced;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 |
6 | public class AdvancedExampleCountryPOJO {
7 |
8 | private String title;
9 | private int icon;
10 |
11 | public AdvancedExampleCountryPOJO(String title, int icon) {
12 | this.title = title;
13 | this.icon = icon;
14 | }
15 |
16 | public String getTitle() {
17 | return title;
18 | }
19 |
20 | public void setTitle(String title) {
21 | this.title = title;
22 | }
23 |
24 | public int getIcon() {
25 | return icon;
26 | }
27 |
28 | public void setIcon(int icon) {
29 | this.icon = icon;
30 | }
31 |
32 | public static List getExampleDataset() {
33 | return Arrays.asList(
34 | new AdvancedExampleCountryPOJO("Russian Federation", R.drawable.ds_countries_ru),
35 | new AdvancedExampleCountryPOJO("Canada", R.drawable.ds_countries_ca),
36 | new AdvancedExampleCountryPOJO("United States of America", R.drawable.ds_countries_us),
37 | new AdvancedExampleCountryPOJO("China", R.drawable.ds_countries_cn),
38 | new AdvancedExampleCountryPOJO("Brazil", R.drawable.ds_countries_br),
39 | new AdvancedExampleCountryPOJO("Australia", R.drawable.ds_countries_au),
40 | new AdvancedExampleCountryPOJO("India", R.drawable.ds_countries_in),
41 | new AdvancedExampleCountryPOJO("Argentina", R.drawable.ds_countries_ar),
42 | new AdvancedExampleCountryPOJO("Kazakhstan", R.drawable.ds_countries_kz),
43 | new AdvancedExampleCountryPOJO("Algeria", R.drawable.ds_countries_dz)
44 | );
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/java/com/ramotion/directselect/examples/advanced/AdvancedExampleCountryPickerBox.java:
--------------------------------------------------------------------------------
1 | package com.ramotion.directselect.examples.advanced;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.widget.ImageView;
8 | import android.widget.TextView;
9 |
10 | import com.ramotion.directselect.DSAbstractPickerBox;
11 |
12 | import androidx.annotation.NonNull;
13 | import androidx.annotation.Nullable;
14 |
15 | public class AdvancedExampleCountryPickerBox extends DSAbstractPickerBox {
16 |
17 | private TextView text;
18 | private ImageView icon;
19 | private View cellRoot;
20 |
21 | public AdvancedExampleCountryPickerBox(@NonNull Context context) {
22 | this(context, null);
23 | }
24 |
25 | public AdvancedExampleCountryPickerBox(@NonNull Context context, @Nullable AttributeSet attrs) {
26 | this(context, attrs, 0);
27 | }
28 |
29 | public AdvancedExampleCountryPickerBox(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
30 | super(context, attrs, defStyleAttr);
31 | init(context);
32 | }
33 |
34 | private void init(@NonNull Context context) {
35 | LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
36 | assert mInflater != null;
37 | mInflater.inflate(R.layout.advanced_example_country_picker_box, this, true);
38 | }
39 |
40 | @Override
41 | protected void onFinishInflate() {
42 | super.onFinishInflate();
43 | this.text = findViewById(R.id.custom_cell_text);
44 | this.icon = findViewById(R.id.custom_cell_image);
45 | this.cellRoot = findViewById(R.id.custom_cell_root);
46 | }
47 |
48 | @Override
49 | public void onSelect(AdvancedExampleCountryPOJO selectedItem, int selectedIndex) {
50 | this.text.setText(selectedItem.getTitle());
51 | this.icon.setImageResource(selectedItem.getIcon());
52 | }
53 |
54 | @Override
55 | public View getCellRoot() {
56 | return this.cellRoot;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/drawable/ds_bg_list_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/drawable/ds_bg_picker_box.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
7 |
8 |
9 |
10 |
11 |
12 | -
15 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/drawable/ds_countries_ar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/drawable/ds_countries_ar.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/drawable/ds_countries_au.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/drawable/ds_countries_au.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/drawable/ds_countries_br.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/drawable/ds_countries_br.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/drawable/ds_countries_ca.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/drawable/ds_countries_ca.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/drawable/ds_countries_cn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/drawable/ds_countries_cn.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/drawable/ds_countries_dz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/drawable/ds_countries_dz.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/drawable/ds_countries_in.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/drawable/ds_countries_in.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/drawable/ds_countries_kz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/drawable/ds_countries_kz.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/drawable/ds_countries_ru.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/drawable/ds_countries_ru.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/drawable/ds_countries_us.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/drawable/ds_countries_us.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/drawable/ds_picker_box_arrows.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/drawable/ds_picker_box_arrows.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/layout/advanced_example_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
21 |
22 |
35 |
36 |
40 |
41 |
45 |
46 |
51 |
52 |
57 |
58 |
62 |
63 |
68 |
69 |
74 |
75 |
79 |
80 |
85 |
86 |
93 |
94 |
98 |
99 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/layout/advanced_example_country_cell.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
19 |
20 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/layout/advanced_example_country_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/layout/advanced_example_country_picker_box.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
14 |
15 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-advanced/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - Soccer
5 | - American Football
6 | - Basketball
7 | - Cricket
8 | - Table Tennis
9 | - Tennis
10 | - Hockey
11 | - Volleyball
12 | - Baseball
13 | - Rugby
14 | - Golf
15 |
16 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #ffffff
4 | #eeeeee
5 | #797979
6 | #6d74ff
7 |
8 | #dedede
9 | #9f9f9f
10 | #ffffff
11 | #ffffff
12 | #232323
13 |
14 |
15 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | DS Advanced Example
3 | picker box arrows icon
4 | cell image
5 | Direct Select for Android
6 | New iOS and Android control for you and your company. Please make sure to use it properly, if you have any questions, please create an issue on our GitHub account.
7 | Here a fully customized picker with custom background and cell layout:
8 | Here a picker with default cell but custom background:
9 | by Ramotion inc.
10 |
11 |
--------------------------------------------------------------------------------
/direct-select-example-advanced/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
17 |
18 |
23 |
24 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/direct-select-example-basic/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/direct-select-example-basic/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 28
5 | defaultConfig {
6 | applicationId "com.ramotion.directselect.examples.basic"
7 | minSdkVersion 14
8 | targetSdkVersion 28
9 | versionCode 2
10 | versionName "1.0.1"
11 |
12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | buildToolsVersion '28.0.3'
21 | }
22 |
23 | dependencies {
24 | implementation fileTree(include: ['*.jar'], dir: 'libs')
25 | implementation project(':direct-select')
26 | implementation 'androidx.appcompat:appcompat:1.0.2'
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/direct-select-example-basic/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/java/com/ramotion/directselect/examples/basic/BasicExampleActivity.java:
--------------------------------------------------------------------------------
1 | package com.ramotion.directselect.examples.basic;
2 |
3 | import android.os.Bundle;
4 |
5 | import androidx.appcompat.app.AppCompatActivity;
6 |
7 | public class BasicExampleActivity extends AppCompatActivity {
8 |
9 | @Override
10 | protected void onCreate(Bundle savedInstanceState) {
11 | super.onCreate(savedInstanceState);
12 | setContentView(R.layout.ds_basic_example_activity);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/drawable/ds_basic_example_custom_picker_box_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 |
10 | -
13 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/layout/ds_basic_example_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
23 |
24 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-basic/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-basic/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-basic/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-basic/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-basic/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-basic/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-basic/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-basic/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-basic/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct-select-example-basic/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - January
5 | - February
6 | - March
7 | - April
8 | - May
9 | - June
10 | - July
11 | - August
12 | - September
13 | - October
14 | - November
15 | - December
16 |
17 |
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 | #67f45959
8 | #49067397
9 | #ffffff
10 |
11 |
12 |
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | DS Basic Example
3 |
4 |
--------------------------------------------------------------------------------
/direct-select-example-basic/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/direct-select/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/direct-select/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'signing'
3 | apply plugin: 'com.bmuschko.nexus'
4 |
5 | group = 'com.ramotion.directselect'
6 | version = '0.1.1'
7 |
8 | android {
9 | compileSdkVersion 28
10 | buildToolsVersion '28.0.3'
11 |
12 | defaultConfig {
13 | minSdkVersion 14
14 | targetSdkVersion 28
15 | versionCode 2
16 | versionName version
17 |
18 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
19 | }
20 |
21 | buildTypes {
22 | release {
23 | minifyEnabled false
24 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
25 | }
26 | }
27 | }
28 |
29 | dependencies {
30 | implementation fileTree(dir: 'libs', include: ['*.jar'])
31 | implementation 'androidx.appcompat:appcompat:1.0.2'
32 | }
33 |
34 | modifyPom {
35 | project {
36 | name 'DirectSelect for Android'
37 | description 'DirectSelect is a selection widget with an ethereal, full-screen modal popup displaying the available choices when the widget is interact with. http://ramotion.com'
38 | url 'https://github.com/Ramotion/direct-select-android'
39 | inceptionYear '2018'
40 |
41 | scm {
42 | url 'https://github.com/Ramotion/direct-select-android'
43 | connection 'scm:git@github.com:Ramotion/direct-select-android.git'
44 | developerConnection 'scm:git@github.com:Ramotion/direct-select-android.git'
45 | }
46 |
47 | licenses {
48 | license {
49 | name 'The MIT License (MIT)'
50 | url 'https://opensource.org/licenses/mit-license.php'
51 | distribution 'repo'
52 | }
53 | }
54 |
55 | developers {
56 | developer {
57 | id 'oleg-vasiliev'
58 | name 'Oleg Vasiliev'
59 | email 'oleg-vasiliev@hotmail.com'
60 | }
61 |
62 | developer {
63 | id 'golovin47'
64 | name 'Ivan Golovin'
65 | email 'golovinivans@gmail.com'
66 | }
67 | }
68 | }
69 | }
70 |
71 | extraArchive {
72 | sources = false
73 | tests = false
74 | javadoc = false
75 | }
76 |
77 | nexus {
78 | sign = true
79 | repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
80 | snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots/'
81 | }
--------------------------------------------------------------------------------
/direct-select/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/direct-select/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/direct-select/src/main/java/com/ramotion/directselect/AnimationListenerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.ramotion.directselect;
2 |
3 | import android.view.animation.Animation;
4 |
5 | abstract class AnimationListenerAdapter implements Animation.AnimationListener {
6 |
7 | @Override
8 | public void onAnimationStart(Animation animation) {
9 |
10 | }
11 |
12 | @Override
13 | public void onAnimationEnd(Animation animation) {
14 |
15 | }
16 |
17 | @Override
18 | public void onAnimationRepeat(Animation animation) {
19 |
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/direct-select/src/main/java/com/ramotion/directselect/CustomListView.java:
--------------------------------------------------------------------------------
1 | package com.ramotion.directselect;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.MotionEvent;
6 | import android.widget.ListView;
7 |
8 | /**
9 | * Custom List View that reacts only to specific motion events
10 | */
11 | class CustomListView extends ListView {
12 |
13 | public CustomListView(Context context) {
14 | super(context);
15 | }
16 |
17 | public CustomListView(Context context, AttributeSet attrs) {
18 | super(context, attrs);
19 | }
20 |
21 | public CustomListView(Context context, AttributeSet attrs, int defStyleAttr) {
22 | super(context, attrs, defStyleAttr);
23 | }
24 |
25 | @Override
26 | public boolean onTouchEvent(MotionEvent ev) {
27 | return ev.getSource() == DSListView.MOTION_EVENT_SOURCE && super.onTouchEvent(ev);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/direct-select/src/main/java/com/ramotion/directselect/DSAbstractPickerBox.java:
--------------------------------------------------------------------------------
1 | package com.ramotion.directselect;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.View;
6 | import android.widget.FrameLayout;
7 |
8 | import androidx.annotation.NonNull;
9 | import androidx.annotation.Nullable;
10 |
11 | /**
12 | * Represents a Picker Box for Direct Select with specified data type
13 | *
14 | * @param data type for direct select and picker box elements
15 | */
16 | public abstract class DSAbstractPickerBox extends FrameLayout {
17 |
18 | public DSAbstractPickerBox(@NonNull Context context) {
19 | super(context);
20 | }
21 |
22 | public DSAbstractPickerBox(@NonNull Context context, @Nullable AttributeSet attrs) {
23 | super(context, attrs);
24 | }
25 |
26 | public DSAbstractPickerBox(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
27 | super(context, attrs, defStyleAttr);
28 | }
29 |
30 | /**
31 | * This method will be invoked when directselect select's a item
32 | *
33 | * @param selectedItem data object of selected item
34 | * @param selectedIndex index of selected item
35 | */
36 | public abstract void onSelect(T selectedItem, int selectedIndex);
37 |
38 | /**
39 | * This method must return a root view of your custom cell in most cases.
40 | * This view and all his children views will be used for scroll/show animations if they are enabled
41 | */
42 | public abstract View getCellRoot();
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/direct-select/src/main/java/com/ramotion/directselect/DSDefaultAdapter.java:
--------------------------------------------------------------------------------
1 | package com.ramotion.directselect;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.ArrayAdapter;
8 | import android.widget.TextView;
9 |
10 | import java.util.ArrayList;
11 |
12 | import androidx.annotation.NonNull;
13 |
14 | /**
15 | * Default implementation of ArrayAdapter for DSListView
16 | * Used by default for strings with default cell layout through simple and clean xml configuration
17 | */
18 | public class DSDefaultAdapter extends ArrayAdapter {
19 |
20 | private ArrayList items;
21 | private Context context;
22 |
23 | // Things to provide proper cell configuration comparing to configuration of picker box element
24 | // Any custom implementation doesn't need this three vars
25 | private int cellHeight;
26 | private int cellTextSize;
27 | private DSDefaultPickerBox dsPickerBoxDefault;
28 |
29 | DSDefaultAdapter(Context context, int textViewResourceId, ArrayList stringItems, Integer cellHeight, Integer cellTextSize) {
30 | super(context, textViewResourceId, stringItems);
31 | this.items = stringItems;
32 | this.context = context;
33 | this.cellHeight = cellHeight;
34 | this.cellTextSize = cellTextSize;
35 | }
36 |
37 | void setDsPickerBoxDefault(DSDefaultPickerBox dsPickerBoxDefault) {
38 | this.dsPickerBoxDefault = dsPickerBoxDefault;
39 | }
40 |
41 | void setCellHeight(Integer cellHeight) {
42 | this.cellHeight = cellHeight;
43 | }
44 |
45 | void setCellTextSize(Integer cellTextSize) {
46 | this.cellTextSize = cellTextSize;
47 | }
48 |
49 | @Override
50 | public long getItemId(int position) {
51 | return position;
52 | }
53 |
54 | @Override
55 | public boolean hasStableIds() {
56 | return true;
57 | }
58 |
59 | @Override
60 | public int getCount() {
61 | return items.size();
62 | }
63 |
64 | @NonNull
65 | @Override
66 | public View getView(int position, View convertView, @NonNull ViewGroup parent) {
67 | DSDefaultAdapter.ViewHolder holder;
68 |
69 | if (null == convertView) {
70 | LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
71 | assert vi != null;
72 | convertView = vi.inflate(R.layout.ds_default_list_item, parent, false);
73 | holder = new DSDefaultAdapter.ViewHolder();
74 | holder.text = convertView.findViewById(R.id.ds_default_cell_text);
75 | convertView.setTag(holder);
76 | } else {
77 | holder = (ViewHolder) convertView.getTag();
78 | }
79 |
80 | if (null != holder) {
81 | holder.text.setText(items.get(position));
82 |
83 | if (cellHeight > 0)
84 | convertView.setMinimumHeight(cellHeight);
85 |
86 | if (cellTextSize > 0)
87 | holder.text.setTextSize(cellTextSize);
88 |
89 | if (null != this.dsPickerBoxDefault)
90 | convertView.setPadding(dsPickerBoxDefault.getPaddingLeft(), dsPickerBoxDefault.getPaddingTop(),
91 | dsPickerBoxDefault.getPaddingRight(), dsPickerBoxDefault.getPaddingBottom());
92 | }
93 | return convertView;
94 | }
95 |
96 | private class ViewHolder {
97 | TextView text;
98 | }
99 |
100 | }
101 |
--------------------------------------------------------------------------------
/direct-select/src/main/java/com/ramotion/directselect/DSDefaultPickerBox.java:
--------------------------------------------------------------------------------
1 | package com.ramotion.directselect;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.TextView;
9 |
10 | import androidx.annotation.NonNull;
11 | import androidx.annotation.Nullable;
12 |
13 | /**
14 | * Default implementation of Picker Box element for Strings to work "from the box"
15 | * with default cell layout
16 | */
17 | public class DSDefaultPickerBox extends DSAbstractPickerBox {
18 |
19 | private TextView textView;
20 | private ViewGroup cellRoot;
21 |
22 | public DSDefaultPickerBox(@NonNull Context context) {
23 | this(context, null);
24 |
25 | }
26 |
27 | public DSDefaultPickerBox(@NonNull Context context, @Nullable AttributeSet attrs) {
28 | this(context, attrs, 0);
29 | }
30 |
31 | public DSDefaultPickerBox(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
32 | super(context, attrs, defStyleAttr);
33 | init(context);
34 | }
35 |
36 | private void init(@NonNull Context context) {
37 | LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
38 | assert mInflater != null;
39 | mInflater.inflate(R.layout.ds_default_picker_box, this, true);
40 | this.setClipChildren(false);
41 | this.setClipToPadding(false);
42 | }
43 |
44 | void setCellTextSize(int cellTextSize) {
45 | if (cellTextSize > 0)
46 | this.textView.setTextSize(cellTextSize);
47 | }
48 |
49 | @Override
50 | protected void onFinishInflate() {
51 | super.onFinishInflate();
52 | this.textView = findViewById(R.id.ds_default_cell_text);
53 | this.cellRoot = findViewById(R.id.ds_default_cell_root);
54 | this.cellRoot.setMinimumHeight(this.getHeight());
55 | }
56 |
57 | @Override
58 | public void onSelect(String value, int index) {
59 | this.textView.setText(value);
60 | }
61 |
62 | @Override
63 | public View getCellRoot() {
64 | return this.cellRoot;
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/direct-select/src/main/java/com/ramotion/directselect/DSListView.java:
--------------------------------------------------------------------------------
1 | package com.ramotion.directselect;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.content.res.TypedArray;
6 | import android.graphics.Color;
7 | import android.os.Build;
8 | import android.os.Handler;
9 | import android.util.AttributeSet;
10 | import android.view.LayoutInflater;
11 | import android.view.MotionEvent;
12 | import android.view.View;
13 | import android.view.ViewGroup;
14 | import android.view.animation.AccelerateInterpolator;
15 | import android.view.animation.AlphaAnimation;
16 | import android.view.animation.Animation;
17 | import android.view.animation.DecelerateInterpolator;
18 | import android.view.animation.ScaleAnimation;
19 | import android.widget.AbsListView;
20 | import android.widget.ArrayAdapter;
21 | import android.widget.FrameLayout;
22 | import android.widget.ListView;
23 | import android.widget.RelativeLayout;
24 | import android.widget.Space;
25 |
26 | import java.util.ArrayList;
27 | import java.util.Arrays;
28 |
29 | import androidx.annotation.ColorInt;
30 | import androidx.annotation.DrawableRes;
31 |
32 | /**
33 | * Represents a popup view with list of available options to choose from and selector view
34 | * at fixed position from top to indicate a selected option. Contains mail logic, animations, handlers, etc.
35 | */
36 | @SuppressWarnings({"unused", "UnusedReturnValue", "unchecked"})
37 | public class DSListView extends RelativeLayout implements AbsListView.OnScrollListener {
38 | static int MOTION_EVENT_SOURCE = 42;
39 |
40 | private ArrayAdapter adapter = null;
41 | private ArrayList dataFromAttributes = null;
42 |
43 | private Context context;
44 |
45 | // Inner parts
46 | private ListView listView = null;
47 | private View selectorView = null;
48 |
49 | // State variables
50 | private boolean selectorAnimationsEnabled = true;
51 | private boolean pickerInitialized;
52 | private boolean readyToHide;
53 | private boolean animationInProgress;
54 | private boolean scrollInProgress;
55 | private boolean listViewIsShown;
56 |
57 | // Settings and selector position
58 | private int firstVisibleItem = 0;
59 | private int selectedItem = 0;
60 | private int cellsBeforeSelector = 0;
61 | private int cellHeight = 100;
62 | private float scaleFactorDelta = 0.3f;
63 | private int selectorTopMargin = 0;
64 | private int subScrollDuration = 100;
65 | private int topMarginCompensation = 0;
66 | private boolean selectorAnimationCenterPivot = false;
67 |
68 | // Attached picker box view to display selected value and trigger show/hide animations of DSListView
69 | private DSAbstractPickerBox pickerBox;
70 | private int pickerBoxResId;
71 | private int cellTextSize;
72 |
73 | // Selector view background settings
74 | private int selectorBgColor = Color.parseColor("#116b2b66");
75 | private int selectorBgDrawable;
76 |
77 | public DSListView(Context context) {
78 | this(context, null);
79 | }
80 |
81 | public DSListView(Context context, AttributeSet attrs) {
82 | this(context, attrs, 0);
83 | }
84 |
85 | public DSListView(Context context, AttributeSet attrs, int defStyle) {
86 | super(context, attrs, defStyle);
87 | TypedArray styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.DSListView);
88 | final int count = styledAttrs.getIndexCount();
89 | for (int i = 0; i < count; ++i) {
90 | int attr = styledAttrs.getIndex(i);
91 | if (attr == R.styleable.DSListView_cell_font_size) {
92 | this.cellTextSize = styledAttrs.getDimensionPixelSize(attr, 0);
93 | } else if (attr == R.styleable.DSListView_data_array) {
94 | String[] arr = getResources().getStringArray(styledAttrs.getResourceId(attr, 0));
95 | this.dataFromAttributes = new ArrayList<>(Arrays.asList(arr));
96 | } else if (attr == R.styleable.DSListView_scale_animations) {
97 | this.selectorAnimationsEnabled = styledAttrs.getBoolean(attr, true);
98 | } else if (attr == R.styleable.DSListView_selected_index) {
99 | this.selectedItem = styledAttrs.getInt(attr, 0);
100 | } else if (attr == R.styleable.DSListView_picker_box_view) {
101 | this.pickerBoxResId = styledAttrs.getResourceId(attr, 0);
102 | } else if (attr == R.styleable.DSListView_scale_animations_factor) {
103 | this.scaleFactorDelta = styledAttrs.getFloat(attr, 1.3f) - 1f;
104 | } else if (attr == R.styleable.DSListView_scale_animations_pivot_center) {
105 | this.selectorAnimationCenterPivot = styledAttrs.getBoolean(attr, false);
106 | } else if (attr == R.styleable.DSListView_selector_background) {
107 | try {
108 | this.selectorBgColor = styledAttrs.getColor(attr, Color.parseColor("#116b2b66"));
109 | } catch (Exception e) {
110 | this.selectorBgDrawable = styledAttrs.getResourceId(attr, 0);
111 | }
112 | }
113 | }
114 | styledAttrs.recycle();
115 | initPicker(context);
116 | }
117 |
118 | private void initPicker(Context context) {
119 | this.context = context;
120 |
121 | LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
122 |
123 | assert inflater != null;
124 | inflater.inflate(R.layout.ds_list_view, this, true);
125 |
126 | listView = findViewById(R.id.list_view);
127 | selectorView = findViewById(R.id.selector_view);
128 |
129 | if (selectorBgDrawable > 0)
130 | selectorView.setBackgroundResource(selectorBgDrawable);
131 | else
132 | selectorView.setBackgroundColor(selectorBgColor);
133 |
134 | // If string data array provided from xml - use it with default string array adapter
135 | if (null != dataFromAttributes)
136 | setAdapter((ArrayAdapter) new DSDefaultAdapter(context, R.layout.ds_default_list_item,
137 | dataFromAttributes, cellHeight, cellTextSize));
138 |
139 | }
140 |
141 | @Override
142 | public void onWindowFocusChanged(boolean hasWindowFocus) {
143 | super.onWindowFocusChanged(hasWindowFocus);
144 |
145 | // Init listView here, because we need to do some calculations when listView already has height
146 | if (pickerInitialized || null == adapter)
147 | return;
148 |
149 | int[] selectboxLocation = new int[2];
150 |
151 | if (null != this.pickerBox) {
152 | this.pickerBox.getLocationInWindow(selectboxLocation);
153 | this.cellHeight = this.pickerBox.getHeight();
154 | }
155 |
156 | if (null != this.adapter && this.adapter instanceof DSDefaultAdapter)
157 | ((DSDefaultAdapter) this.adapter).setCellHeight(cellHeight);
158 |
159 | // Calculate positions of selector and self position
160 | int[] selfLocation = new int[2];
161 | this.getLocationInWindow(selfLocation);
162 | selectorTopMargin = selectboxLocation[1] - selfLocation[1];
163 | if (selectorTopMargin < 0) selectorTopMargin = 0;
164 |
165 | // Move selectorView to required position, by the top margin
166 | if (selectorView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
167 | ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) selectorView.getLayoutParams();
168 | p.height = cellHeight;
169 | p.setMargins(0, selectorTopMargin, 0, 0);
170 | selectorView.requestLayout();
171 | }
172 |
173 | topMarginCompensation = cellHeight - selectorTopMargin % cellHeight;
174 | cellsBeforeSelector = selectorTopMargin / cellHeight;
175 | cellsBeforeSelector += topMarginCompensation == 0 ? 0 : 1;
176 |
177 | // Add negative margin to list view to compensate remained space smaller than cell height
178 | if (listView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
179 | ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) listView.getLayoutParams();
180 | p.setMargins(0, -topMarginCompensation, 0, 0);
181 | listView.requestLayout();
182 | }
183 |
184 | // Add empty space before list elements to make sure that all list items reachable
185 | for (int i = 0; i < cellsBeforeSelector; i++) {
186 | Space topSpace = new Space(context);
187 | topSpace.setMinimumHeight(cellHeight);
188 | listView.addHeaderView(topSpace);
189 | }
190 |
191 | // Add space after list elements to make sure that all list items reachable
192 | Space bottomSpace = new Space(context);
193 | bottomSpace.setMinimumHeight((DSListView.this.getHeight() - selectorTopMargin - cellHeight));
194 | listView.addFooterView(bottomSpace);
195 |
196 | // Set adapter and scroll listener
197 | listView.setAdapter(adapter);
198 | listView.setOnScrollListener(this);
199 |
200 | pickerInitialized = true;
201 |
202 | // Set initial selection
203 | this.listView.setSelection(selectedItem);
204 |
205 | if (null != pickerBox)
206 | this.pickerBox.onSelect(this.adapter.getItem(selectedItem), selectedItem);
207 | }
208 |
209 | @Override
210 | public void onAttachedToWindow() {
211 | super.onAttachedToWindow();
212 | if (null == this.pickerBox && this.pickerBoxResId > 0)
213 | setPickerBox((DSAbstractPickerBox) getRootView().findViewById(pickerBoxResId));
214 | }
215 |
216 | private void hideListView() {
217 | if (!readyToHide || animationInProgress || scrollInProgress || !listViewIsShown || adapter == null) return;
218 |
219 | readyToHide = false;
220 | animationInProgress = true;
221 | listView.setEnabled(false);
222 |
223 | this.setVisibility(View.INVISIBLE);
224 |
225 | this.pickerBox.onSelect(adapter.getItem(selectedItem), selectedItem);
226 |
227 | AlphaAnimation hideAnimation = new AlphaAnimation(1f, 0f);
228 | hideAnimation.setStartOffset(subScrollDuration);
229 | hideAnimation.setDuration(200);
230 | hideAnimation.setInterpolator(new DecelerateInterpolator());
231 | hideAnimation.setAnimationListener(new AnimationListenerAdapter() {
232 | @Override
233 | public void onAnimationEnd(Animation animation) {
234 | listViewIsShown = false;
235 | animationInProgress = false;
236 | }
237 | });
238 | DSListView.this.startAnimation(hideAnimation);
239 |
240 | // Scale picker box text animation if animations enabled
241 | if (selectorAnimationsEnabled && null != this.pickerBox) {
242 | ScaleAnimation scaleAnimation = new ScaleAnimation(1f + scaleFactorDelta, 1f, 1f + scaleFactorDelta, 1f,
243 | Animation.RELATIVE_TO_SELF, selectorAnimationCenterPivot ? 0.5f : 0f, Animation.RELATIVE_TO_SELF, 0.5f);
244 | scaleAnimation.setInterpolator(new DecelerateInterpolator());
245 | scaleAnimation.setStartOffset(100 + subScrollDuration);
246 | scaleAnimation.setDuration(100);
247 | scaleAnimation.setFillAfter(true);
248 | this.pickerBox.getCellRoot().startAnimation(scaleAnimation);
249 | }
250 | }
251 |
252 | private void showListView() {
253 | if (animationInProgress || scrollInProgress || listViewIsShown) return;
254 | listView.setEnabled(true);
255 | animationInProgress = true;
256 |
257 | this.setVisibility(View.VISIBLE);
258 | this.bringToFront();
259 | this.readyToHide = false;
260 |
261 | // Scale picker box if animations enabled
262 | if (selectorAnimationsEnabled && null != this.pickerBox) {
263 | ScaleAnimation scaleAnimation = new ScaleAnimation(1f, 1f + scaleFactorDelta, 1f, 1f + scaleFactorDelta,
264 | Animation.RELATIVE_TO_SELF, selectorAnimationCenterPivot ? 0.5f : 0f, Animation.RELATIVE_TO_SELF, 0.5f);
265 | scaleAnimation.setInterpolator(new AccelerateInterpolator());
266 | scaleAnimation.setDuration(100);
267 | scaleAnimation.setFillAfter(true);
268 | this.pickerBox.getCellRoot().startAnimation(scaleAnimation);
269 | }
270 |
271 | // Show picker view animation
272 | AlphaAnimation showAnimation = new AlphaAnimation(0f, 1f);
273 | showAnimation.setDuration(200);
274 | showAnimation.setInterpolator(new AccelerateInterpolator());
275 | showAnimation.setAnimationListener(new AnimationListenerAdapter() {
276 | @Override
277 | public void onAnimationEnd(Animation animation) {
278 | animationInProgress = false;
279 | listViewIsShown = true;
280 | hideListView();
281 | }
282 | });
283 |
284 | this.startAnimation(showAnimation);
285 | }
286 |
287 | ///////////////////////////////////////// CLIENT METHODS ///////////////////////////////////////////
288 |
289 | public void setAdapter(ArrayAdapter adapter) {
290 | this.adapter = adapter;
291 | // If default adapter set - use mechanisms to do default_cell configuration
292 | if (null != this.adapter && this.adapter instanceof DSDefaultAdapter) {
293 | DSDefaultAdapter ad = (DSDefaultAdapter) this.adapter;
294 | ad.setCellHeight(cellHeight);
295 | ad.setCellTextSize(cellTextSize);
296 | if (this.pickerBox instanceof DSDefaultPickerBox)
297 | ad.setDsPickerBoxDefault((DSDefaultPickerBox) this.pickerBox);
298 | }
299 | listView.setAdapter(adapter);
300 | }
301 |
302 | public void setPickerBox(DSAbstractPickerBox pickerBox) {
303 | this.pickerBox = pickerBox;
304 | if (this.pickerBox == null) return;
305 | this.pickerBox.setOnTouchListener(new View.OnTouchListener() {
306 | @SuppressLint("ClickableViewAccessibility")
307 | @Override
308 | public boolean onTouch(View v, MotionEvent event) {
309 | switch (event.getAction()) {
310 | case MotionEvent.ACTION_DOWN:
311 | DSListView.this.showListView();
312 | break;
313 | case MotionEvent.ACTION_UP:
314 | DSListView.this.readyToHide = true;
315 | hideListView();
316 | break;
317 | }
318 | event.offsetLocation(0, selectorTopMargin + topMarginCompensation);
319 | event.setSource(MOTION_EVENT_SOURCE);
320 | DSListView.this.listView.onTouchEvent(event);
321 | return true;
322 | }
323 | });
324 |
325 | if (this.adapter != null && this.adapter instanceof DSDefaultAdapter && this.pickerBox instanceof DSDefaultPickerBox) {
326 | DSDefaultAdapter ad = (DSDefaultAdapter) this.adapter;
327 | DSDefaultPickerBox pbd = (DSDefaultPickerBox) this.pickerBox;
328 | ad.setDsPickerBoxDefault(pbd);
329 | pbd.setCellTextSize(cellTextSize);
330 | }
331 | }
332 |
333 | public void setSelectorBgColor(@ColorInt int chooserBgColor) {
334 | this.selectorBgColor = chooserBgColor;
335 | if (null != selectorView)
336 | selectorView.setBackgroundColor(chooserBgColor);
337 | }
338 |
339 | @SuppressLint("ResourceType")
340 | public void setSelectorBgDrawable(@DrawableRes int chooserBgDrawable) {
341 | this.selectorBgDrawable = chooserBgDrawable;
342 | if (chooserBgDrawable > 0 && null != selectorView)
343 | selectorView.setBackgroundResource(chooserBgDrawable);
344 | }
345 |
346 | public Integer getSelectedIndex() {
347 | return null == this.adapter ? null : this.selectedItem;
348 | }
349 |
350 | public void setSelectedIndex(int index) {
351 | this.selectedItem = index;
352 |
353 | if (pickerInitialized)
354 | this.listView.setSelection(index);
355 |
356 | if (null != pickerBox && null != this.adapter)
357 | this.pickerBox.onSelect(this.adapter.getItem(this.selectedItem), this.selectedItem);
358 | }
359 |
360 | public T getSelectedItem() {
361 | return null == this.adapter ? null : this.adapter.getItem(this.selectedItem);
362 | }
363 |
364 | //////////////////////////////////////// GETTERS&SETTERS ///////////////////////////////////////////
365 |
366 | public boolean isSelectorAnimationsEnabled() {
367 | return this.selectorAnimationsEnabled;
368 | }
369 |
370 | public void setSelectorAnimationsEnabled(boolean selectorAnimationsEnabled) {
371 | this.selectorAnimationsEnabled = selectorAnimationsEnabled;
372 | }
373 |
374 | /////////////////////////////////// ListView Scroll Listener ///////////////////////////////////////
375 |
376 | @Override
377 | public void onScrollStateChanged(AbsListView absListView, final int scrollState) {
378 | this.scrollInProgress = true;
379 |
380 | // If scroll not stopped - clear selector animations(hide/show scale) and return;
381 | if (scrollState != SCROLL_STATE_IDLE) {
382 | // if (null != this.pickerBox) {
383 | // Animation animation = DSListView.this.pickerBox.getAnimation();
384 | // if (animation != null)
385 | // animation.cancel();
386 | //
387 | // }
388 | return;
389 | }
390 |
391 | // So, scroll is stopped - we need to detect position and make subscroll to selected element
392 | this.scrollInProgress = false;
393 |
394 | // Get first visible child of list (invisible child are removed for recycling, so first visible child is always 0 index)
395 | View topChild = absListView.getChildAt(0);
396 | if (topChild == null) return;
397 |
398 | // Get position of of first visible child in dataFromAttributes array
399 | this.firstVisibleItem = this.listView.getFirstVisiblePosition();
400 |
401 | // Switch to next item if height of visible part of top view is smaller than half height of one row
402 | if (-topChild.getTop() > topChild.getHeight() / 2) {
403 | this.firstVisibleItem++;
404 | }
405 |
406 | // Dirty trick with post-delayed handler to avoid known "fixed" issue (https://issuetracker.google.com/issues/36952786)
407 | new Handler().postDelayed(new Runnable() {
408 | @Override
409 | public void run() {
410 | listView.smoothScrollToPositionFromTop(firstVisibleItem, 0, subScrollDuration);
411 | hideListView();
412 | }
413 | }, 0);
414 |
415 | this.selectedItem = this.firstVisibleItem;
416 | }
417 |
418 | @Override
419 | public void onScroll(AbsListView listView, int firstVisible, int visibleItemCount, int totalItemCount) {
420 | if (!pickerInitialized || !selectorAnimationsEnabled) return;
421 |
422 | int selectorPosY = cellHeight * cellsBeforeSelector;
423 | int applyingRangeY = cellHeight;
424 |
425 | for (int i = 0; i < listView.getChildCount(); i++) {
426 |
427 | // Exclude elements that does not need to edit
428 | if (!(listView.getChildAt(i) instanceof FrameLayout))
429 | continue;
430 |
431 | ViewGroup itemRoot = (ViewGroup) listView.getChildAt(i);
432 |
433 | float deviation = 2f;
434 | if (itemRoot.getTop() > selectorPosY + applyingRangeY * deviation || itemRoot.getTop() < selectorPosY - applyingRangeY * deviation)
435 | continue;
436 |
437 | View cellContent = itemRoot.getChildAt(0);
438 |
439 | // Edit elements regarding to their position from selector
440 | float dy = Math.abs(itemRoot.getTop() - selectorPosY);
441 | if (!selectorAnimationCenterPivot) {
442 | cellContent.setPivotX(0);
443 | cellContent.setPivotY(cellContent.getHeight() / 2);
444 | }
445 |
446 | // Scale and "3d effect" for big scale factors on API>=LOLLIPOP
447 | if (dy <= applyingRangeY) {
448 | float k1 = 1 - (dy / applyingRangeY);
449 | float scale = 1 + scaleFactorDelta * k1;
450 | cellContent.setScaleX(scale);
451 | cellContent.setScaleY(scale);
452 |
453 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
454 | itemRoot.setZ((dy <= applyingRangeY / 2) ? 2 : 1);
455 |
456 | } else {
457 | cellContent.setScaleX(1f);
458 | cellContent.setScaleY(1f);
459 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
460 | itemRoot.setZ(0);
461 | }
462 |
463 | }
464 | }
465 |
466 | }
467 |
--------------------------------------------------------------------------------
/direct-select/src/main/res/layout/ds_default_cell.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/direct-select/src/main/res/layout/ds_default_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/direct-select/src/main/res/layout/ds_default_picker_box.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/direct-select/src/main/res/layout/ds_list_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
16 |
17 |
23 |
24 |
--------------------------------------------------------------------------------
/direct-select/src/main/res/values/attr.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/direct_select_preview.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/direct_select_preview.gif
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | android.useAndroidX=true
11 | android.enableJetifier=true
12 |
13 | # Specifies the JVM arguments used for the daemon process.
14 | # The setting is particularly useful for tweaking memory settings.
15 | org.gradle.jvmargs=-Xmx1536m
16 |
17 | # When configured, Gradle will run in incubating parallel mode.
18 | # This option should only be used with decoupled projects. More details, visit
19 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
20 | # org.gradle.parallel=true
21 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Feb 08 15:11:33 MSK 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/direct-select-android/6a4cf41153c522fc332293b7ad508f58ec028f07/header.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':direct-select-example-advanced', ':direct-select', ':direct-select-example-basic'
2 |
--------------------------------------------------------------------------------