├── .gitignore
├── .idea
├── .name
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── gradle.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── LICENCE
├── README.md
├── ScrollHandleExample.iml
├── app
├── .gitignore
├── app.iml
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── werdpressed
│ │ └── partisan
│ │ └── scrollhandleexample
│ │ └── ApplicationTest.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── ic_cheeses_app_bar-web.png
│ ├── java
│ └── com
│ │ └── werdpressed
│ │ └── partisan
│ │ └── scrollhandleexample
│ │ ├── AppBarManager.java
│ │ ├── Cheeses.java
│ │ ├── ConfigurableRecyclerView.java
│ │ ├── MainActivity.java
│ │ ├── RecyclerFragment.java
│ │ ├── RecyclerFragmentAdapter.java
│ │ └── RecyclerLayoutManager.java
│ └── res
│ ├── drawable-hdpi
│ ├── ic_lock_open_white_24dp.png
│ └── ic_lock_outline_white_24dp.png
│ ├── drawable-mdpi
│ ├── ic_lock_open_white_24dp.png
│ └── ic_lock_outline_white_24dp.png
│ ├── drawable-xhdpi
│ ├── ic_lock_open_white_24dp.png
│ └── ic_lock_outline_white_24dp.png
│ ├── drawable-xxhdpi
│ ├── ic_lock_open_white_24dp.png
│ └── ic_lock_outline_white_24dp.png
│ ├── drawable
│ ├── cheeses.jpg
│ └── drop_shadow.xml
│ ├── layout
│ ├── activity_main.xml
│ ├── rv_fragment.xml
│ └── rv_row.xml
│ ├── menu
│ └── menu_main.xml
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxxhdpi
│ └── ic_cheeses_app_bar.png
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | /local.properties
3 | /.idea/workspace.xml
4 | /.idea/libraries
5 | .DS_Store
6 | /build
7 | /captures
8 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | ScrollHandleExample
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | 1.7
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/LICENCE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Tom Calver
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 | # ScrollHandleExample
2 |
3 | [](http://www.youtube.com/watch?v=YgcmQS_zPTY "YouTube: Scroll Handle Example")
4 |
5 | Demonstrates how to progammatically scroll a `RecyclerView` by manipulating a `View` with a `TouchListener`. Although only a `RecyclerView` is shown in the code, the same method works just as well with `NestedScrollView`.
6 |
7 | The method can be especially useful when constructing layouts that make use of `CollapsingToolbarLayout` from the Android Design Support Library. This is because layout elements beyond the `RecyclerView` can be added below the collapsing toolbar, yet still cause it to collapse and expand based on touch events in the same way as a `RecyclerView` or `NestedScrollView`.
8 |
9 | A demonstration video is on [YouTube](https://www.youtube.com/watch?v=YgcmQS_zPTY&feature=youtu.be "YoutTube: Scroll Handle Example") and a blog post at [Partisan Apps](http://partisanapps.com/2015/10/trigger-nested-scrolls-with-custom-views/ "Partisan Apps: Blog") that goes into more detail.
10 |
--------------------------------------------------------------------------------
/ScrollHandleExample.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | generateDebugSources
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.1"
6 |
7 | defaultConfig {
8 | applicationId "com.werdpressed.partisan.scrollhandleexample"
9 | minSdkVersion 15
10 | targetSdkVersion 23
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | compile 'com.android.support:appcompat-v7:23.4.0'
25 | compile 'com.android.support:recyclerview-v7:23.4.0'
26 | compile 'com.android.support:design:23.4.0'
27 | }
28 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /home/tom/Android/Sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/werdpressed/partisan/scrollhandleexample/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.werdpressed.partisan.scrollhandleexample;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/ic_cheeses_app_bar-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PPartisan/ScrollHandleExample/dc0beb9ecd7535ef7de352c036618f7298a0523b/app/src/main/ic_cheeses_app_bar-web.png
--------------------------------------------------------------------------------
/app/src/main/java/com/werdpressed/partisan/scrollhandleexample/AppBarManager.java:
--------------------------------------------------------------------------------
1 | package com.werdpressed.partisan.scrollhandleexample;
2 |
3 | /**
4 | * Inspired by http://novoda.com/blog/fixing-hiding-appbarlayout-android-tv/
5 | */
6 |
7 | public interface AppBarManager {
8 |
9 | void collapseAppBar();
10 | void expandAppBar();
11 | int getVisibleHeightForRecyclerViewInPx();
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/werdpressed/partisan/scrollhandleexample/Cheeses.java:
--------------------------------------------------------------------------------
1 | package com.werdpressed.partisan.scrollhandleexample;
2 |
3 | public final class Cheeses {
4 |
5 | private Cheeses() { throw new AssertionError(); }
6 |
7 | public static final String[] CHEESES = {
8 | "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
9 | "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale",
10 | "Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
11 | "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell",
12 | "Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc",
13 | "Asadero", "Asiago", "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss",
14 | "Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", "Banon",
15 | "Barry's Bay Cheddar", "Basing", "Basket Cheese", "Bath Cheese", "Bavarian Bergkase",
16 | "Baylough", "Beaufort", "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
17 | "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir", "Bierkase", "Bishop Kennedy",
18 | "Blarney", "Bleu d'Auvergne", "Bleu de Gex", "Bleu de Laqueuille",
19 | "Bleu de Septmoncel", "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
20 | "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini", "Bocconcini (Australian)",
21 | "Boeren Leidenkaas", "Bonchester", "Bosworth", "Bougon", "Boule Du Roves",
22 | "Boulette d'Avesnes", "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
23 | "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois", "Brebis du Puyfaucon",
24 | "Bresse Bleu", "Brick", "Brie", "Brie de Meaux", "Brie de Melun", "Brillat-Savarin",
25 | "Brin", "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
26 | "Briquette de Brebis", "Briquette du Forez", "Broccio", "Broccio Demi-Affine",
27 | "Brousse du Rove", "Bruder Basil", "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
28 | "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase", "Button (Innes)",
29 | "Buxton Blue", "Cabecou", "Caboc", "Cabrales", "Cachaille", "Caciocavallo", "Caciotta",
30 | "Caerphilly", "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
31 | "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux", "Capricorn Goat",
32 | "Capriole Banon", "Carre de l'Est", "Casciotta di Urbino", "Cashel Blue", "Castellano",
33 | "Castelleno", "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
34 | "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou", "Chabichou du Poitou",
35 | "Chabis de Gatine", "Chaource", "Charolais", "Chaumes", "Cheddar",
36 | "Cheddar Clothbound", "Cheshire", "Chevres", "Chevrotin des Aravis", "Chontaleno",
37 | "Civray", "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby", "Cold Pack",
38 | "Comte", "Coolea", "Cooleney", "Coquetdale", "Corleggy", "Cornish Pepper",
39 | "Cotherstone", "Cotija", "Cottage Cheese", "Cottage Cheese (Australian)",
40 | "Cougar Gold", "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
41 | "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza",
42 | "Croghan", "Crottin de Chavignol", "Crottin du Chavignol", "Crowdie", "Crowley",
43 | "Cuajada", "Curd", "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
44 | "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo", "Danish Fontina",
45 | "Daralagjazsky", "Dauphin", "Delice des Fiouves", "Denhany Dorset Drum", "Derby",
46 | "Dessertnyj Belyj", "Devon Blue", "Devon Garland", "Dolcelatte", "Doolin",
47 | "Doppelrhamstufel", "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
48 | "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra", "Dunlop", "Dunsyre Blue",
49 | "Duroblando", "Durrus", "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
50 | "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne", "Esbareich",
51 | "Esrom", "Etorki", "Evansdale Farmhouse Brie", "Evora De L'Alentejo", "Exmoor Blue",
52 | "Explorateur", "Feta", "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
53 | "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis", "Flor de Guia",
54 | "Flower Marie", "Folded", "Folded cheese with mint", "Fondant de Brebis",
55 | "Fontainebleau", "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
56 | "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire", "Fourme de Montbrison",
57 | "Fresh Jack", "Fresh Mozzarella", "Fresh Ricotta", "Fresh Truffles", "Fribourgeois",
58 | "Friesekaas", "Friesian", "Friesla", "Frinault", "Fromage a Raclette", "Fromage Corse",
59 | "Fromage de Montagne de Savoie", "Fromage Frais", "Fruit Cream Cheese",
60 | "Frying Cheese", "Fynbo", "Gabriel", "Galette du Paludier", "Galette Lyonnaise",
61 | "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail", "Garrotxa", "Gastanberra",
62 | "Geitost", "Gippsland Blue", "Gjetost", "Gloucester", "Golden Cross", "Gorgonzola",
63 | "Gornyaltajski", "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
64 | "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
65 | "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh", "Greve",
66 | "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny", "Halloumi",
67 | "Halloumy (Australian)", "Haloumi-Style Cheese", "Harbourne Blue", "Havarti",
68 | "Heidi Gruyere", "Hereford Hop", "Herrgardsost", "Herriot Farmhouse", "Herve",
69 | "Hipi Iti", "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
70 | "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu", "Isle of Mull", "Jarlsberg",
71 | "Jermi Tortes", "Jibneh Arabieh", "Jindi Brie", "Jubilee Blue", "Juustoleipa",
72 | "Kadchgall", "Kaseri", "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
73 | "Kikorangi", "King Island Cape Wickham Brie", "King River Gold", "Klosterkaese",
74 | "Knockalara", "Kugelkase", "L'Aveyronnais", "L'Ecir de l'Aubrac", "La Taupiniere",
75 | "La Vache Qui Rit", "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
76 | "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin", "Le Fium Orbo", "Le Lacandou",
77 | "Le Roule", "Leafield", "Lebbene", "Leerdammer", "Leicester", "Leyden", "Limburger",
78 | "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer", "Little Rydings",
79 | "Livarot", "Llanboidy", "Llanglofan Farmhouse", "Loch Arthur Farmhouse",
80 | "Loddiswell Avondale", "Longhorn", "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam",
81 | "Macconais", "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
82 | "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses", "Maredsous", "Margotin",
83 | "Maribo", "Maroilles", "Mascares", "Mascarpone", "Mascarpone (Australian)",
84 | "Mascarpone Torta", "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
85 | "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)", "Meyer Vintage Gouda",
86 | "Mihalic Peynir", "Milleens", "Mimolette", "Mine-Gabhar", "Mini Baby Bells", "Mixte",
87 | "Molbo", "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
88 | "Monterey Jack", "Monterey Jack Dry", "Morbier", "Morbier Cru de Montagne",
89 | "Mothais a la Feuille", "Mozzarella", "Mozzarella (Australian)",
90 | "Mozzarella di Bufala", "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
91 | "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais", "Neufchatel",
92 | "Neufchatel (Australian)", "Niolo", "Nokkelost", "Northumberland", "Oaxaca",
93 | "Olde York", "Olivet au Foin", "Olivet Bleu", "Olivet Cendre",
94 | "Orkney Extra Mature Cheddar", "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty",
95 | "Oszczypek", "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer", "Panela",
96 | "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)", "Parmigiano Reggiano",
97 | "Pas de l'Escalette", "Passendale", "Pasteurized Processed", "Pate de Fromage",
98 | "Patefine Fort", "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac", "Pave du Berry",
99 | "Pecorino", "Pecorino in Walnut Leaves", "Pecorino Romano", "Peekskill Pyramid",
100 | "Pelardon des Cevennes", "Pelardon des Corbieres", "Penamellera", "Penbryn",
101 | "Pencarreg", "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
102 | "Picodon de Chevre", "Picos de Europa", "Piora", "Pithtviers au Foin",
103 | "Plateau de Herve", "Plymouth Cheese", "Podhalanski", "Poivre d'Ane", "Polkolbin",
104 | "Pont l'Eveque", "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
105 | "Pourly", "Prastost", "Pressato", "Prince-Jean", "Processed Cheddar", "Provolone",
106 | "Provolone (Australian)", "Pyengana Cheddar", "Pyramide", "Quark",
107 | "Quark (Australian)", "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
108 | "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango", "Queso de Murcia",
109 | "Queso del Montsec", "Queso del Tietar", "Queso Fresco", "Queso Fresco (Adobera)",
110 | "Queso Iberico", "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
111 | "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette", "Ragusano", "Raschera",
112 | "Reblochon", "Red Leicester", "Regal de la Dombes", "Reggianito", "Remedou",
113 | "Requeson", "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata", "Ridder",
114 | "Rigotte", "Rocamadour", "Rollot", "Romano", "Romans Part Dieu", "Roncal", "Roquefort",
115 | "Roule", "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu", "Saaland Pfarr",
116 | "Saanenkaese", "Saga", "Sage Derby", "Sainte Maure", "Saint-Marcellin",
117 | "Saint-Nectaire", "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
118 | "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza", "Schabzieger", "Schloss",
119 | "Selles sur Cher", "Selva", "Serat", "Seriously Strong Cheddar", "Serra da Estrela",
120 | "Sharpam", "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene", "Smoked Gouda",
121 | "Somerset Brie", "Sonoma Jack", "Sottocenare al Tartufo", "Soumaintrain",
122 | "Sourire Lozerien", "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
123 | "Stilton", "Stinking Bishop", "String", "Sussex Slipcote", "Sveciaost", "Swaledale",
124 | "Sweet Style Swiss", "Swiss", "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
125 | "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea", "Testouri",
126 | "Tete de Moine", "Tetilla", "Texas Goat Cheese", "Tibet", "Tillamook Cheddar",
127 | "Tilsit", "Timboon Brie", "Toma", "Tomme Brulee", "Tomme d'Abondance",
128 | "Tomme de Chevre", "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans", "Tommes",
129 | "Torta del Casar", "Toscanello", "Touree de L'Aubier", "Tourmalet",
130 | "Trappe (Veritable)", "Trois Cornes De Vendee", "Tronchon", "Trou du Cru", "Truffe",
131 | "Tupi", "Turunmaa", "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
132 | "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco", "Vendomois",
133 | "Vieux Corse", "Vignotte", "Vulscombe", "Waimata Farmhouse Blue",
134 | "Washed Rind Cheese (Australian)", "Waterloo", "Weichkaese", "Wellington",
135 | "Wensleydale", "White Stilton", "Whitestone Farmhouse", "Wigmore", "Woodside Cabecou",
136 | "Xanadu", "Xynotyro", "Yarg Cornish", "Yarra Valley Pyramid", "Yorkshire Blue",
137 | "Zamorano", "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"
138 | };
139 | }
140 |
141 |
--------------------------------------------------------------------------------
/app/src/main/java/com/werdpressed/partisan/scrollhandleexample/ConfigurableRecyclerView.java:
--------------------------------------------------------------------------------
1 | package com.werdpressed.partisan.scrollhandleexample;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.util.AttributeSet;
6 | import android.view.MotionEvent;
7 |
8 | public class ConfigurableRecyclerView extends RecyclerView {
9 |
10 | private boolean isScrollingActive;
11 |
12 | private int y;
13 |
14 | public ConfigurableRecyclerView(Context context) {
15 | super(context);
16 | }
17 |
18 | public ConfigurableRecyclerView(Context context, AttributeSet attrs) {
19 | super(context, attrs);
20 | }
21 |
22 | @Override
23 | public boolean onTouchEvent(MotionEvent e) {
24 | return isScrollingActive || super.onTouchEvent(e);
25 | }
26 |
27 | //Enables/Disables scrolling through touch interaction with the RecyclerView directly
28 | public void setScrollingActive(boolean isScrollingActive) {
29 | this.isScrollingActive = isScrollingActive;
30 | }
31 |
32 | //Responsible for starting a programmatic scroll
33 | public boolean dispatchHandlerScroll(MotionEvent e) {
34 | switch (e.getAction()) {
35 | case MotionEvent.ACTION_DOWN:
36 | y = (int) e.getY();
37 | startNestedScroll(2);
38 | break;
39 | case MotionEvent.ACTION_MOVE:
40 | int dY = y - ((int)e.getY());
41 | dispatchNestedPreScroll(0, dY, null, null);
42 | dispatchNestedScroll(0, 0, 0, dY, null);
43 | break;
44 | case MotionEvent.ACTION_UP:
45 | stopNestedScroll();
46 | break;
47 | }
48 | return true;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/werdpressed/partisan/scrollhandleexample/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.werdpressed.partisan.scrollhandleexample;
2 |
3 | import android.os.Bundle;
4 | import android.support.design.widget.AppBarLayout;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.support.v7.widget.Toolbar;
7 | import android.view.Menu;
8 | import android.view.MenuItem;
9 | import android.view.MotionEvent;
10 | import android.widget.Toast;
11 |
12 | public class MainActivity extends AppCompatActivity implements AppBarManager{
13 |
14 | private Toolbar mToolbar;
15 | private RecyclerFragment mRecyclerFragment;
16 | private AppBarLayout mAppBarLayout;
17 |
18 | @Override
19 | protected void onCreate(Bundle savedInstanceState) {
20 | super.onCreate(savedInstanceState);
21 |
22 | setContentView(R.layout.activity_main);
23 |
24 | mToolbar = (Toolbar) findViewById(R.id.toolbar);
25 | setSupportActionBar(mToolbar);
26 |
27 | mAppBarLayout = (AppBarLayout) findViewById(R.id.app_bar);
28 |
29 | if (getSupportFragmentManager().findFragmentById(R.id.rv_container) == null) {
30 | mRecyclerFragment = RecyclerFragment.newInstance();
31 | getSupportFragmentManager()
32 | .beginTransaction()
33 | .add(R.id.rv_container, mRecyclerFragment, RecyclerFragment.TAG)
34 | .commit();
35 | }
36 | }
37 |
38 | @Override
39 | public boolean onCreateOptionsMenu(Menu menu) {
40 | getMenuInflater().inflate(R.menu.menu_main, menu);
41 | return true;
42 | }
43 |
44 | @Override
45 | public boolean onOptionsItemSelected(MenuItem item) {
46 |
47 | if (mRecyclerFragment == null) {
48 | mRecyclerFragment =
49 | (RecyclerFragment) getSupportFragmentManager()
50 | .findFragmentByTag(RecyclerFragment.TAG);
51 | }
52 |
53 | int id = item.getItemId();
54 | switch (id) {
55 | case R.id.action_lock:
56 | makeToast(getString(R.string.action_lock));
57 | mRecyclerFragment.getConfigurableRecyclerView().setScrollingActive(true);
58 | break;
59 | case R.id.action_unlock:
60 | makeToast(getString(R.string.action_unlock));
61 | mRecyclerFragment.getConfigurableRecyclerView().setScrollingActive(false);
62 | break;
63 | }
64 |
65 | return super.onOptionsItemSelected(item);
66 | }
67 |
68 | @Override
69 | public boolean dispatchTouchEvent(MotionEvent event) {
70 | if (event.getAction() == MotionEvent.ACTION_UP) {
71 | float per = Math.abs(mAppBarLayout.getY()) / mAppBarLayout.getTotalScrollRange();
72 | boolean setExpanded = (per <= 0.5F);
73 | mAppBarLayout.setExpanded(setExpanded, true);
74 | }
75 | return super.dispatchTouchEvent(event);
76 | }
77 |
78 | private void makeToast(String content) {
79 | Toast.makeText(this, content, Toast.LENGTH_SHORT).show();
80 | }
81 |
82 | @Override
83 | public void collapseAppBar() {
84 | mAppBarLayout.setExpanded(false, true);
85 | }
86 |
87 | @Override
88 | public void expandAppBar() {
89 | mAppBarLayout.setExpanded(true, true);
90 | }
91 |
92 | @Override
93 | public int getVisibleHeightForRecyclerViewInPx() {
94 |
95 | if (mRecyclerFragment == null) mRecyclerFragment =
96 | (RecyclerFragment) getSupportFragmentManager().findFragmentByTag(RecyclerFragment.TAG);
97 |
98 | int windowHeight, appBarHeight, headerViewHeight;
99 | windowHeight = getWindow().getDecorView().getHeight();
100 | appBarHeight = mAppBarLayout.getHeight();
101 | headerViewHeight = mRecyclerFragment.getHeaderView().getHeight();
102 | return windowHeight - (appBarHeight + headerViewHeight);
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/app/src/main/java/com/werdpressed/partisan/scrollhandleexample/RecyclerFragment.java:
--------------------------------------------------------------------------------
1 | package com.werdpressed.partisan.scrollhandleexample;
2 |
3 | import android.graphics.Color;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.app.Fragment;
7 | import android.support.v7.widget.LinearLayoutManager;
8 | import android.support.v7.widget.RecyclerView;
9 | import android.util.Log;
10 | import android.view.KeyEvent;
11 | import android.view.LayoutInflater;
12 | import android.view.MotionEvent;
13 | import android.view.View;
14 | import android.view.ViewGroup;
15 | import android.view.inputmethod.EditorInfo;
16 | import android.widget.Button;
17 | import android.widget.EditText;
18 | import android.widget.TextView;
19 | import android.widget.Toast;
20 |
21 | public class RecyclerFragment extends Fragment {
22 |
23 | public static final String TAG = "RecyclerFragment";
24 |
25 | private View rootView;
26 | private View headerView;
27 |
28 | private ConfigurableRecyclerView mRecyclerView;
29 | private RecyclerFragmentAdapter mAdapter;
30 | private RecyclerLayoutManager mLayoutManager;
31 |
32 | private int maxAdapterPosition;
33 |
34 | private TextView mDragTextView;
35 | private EditText mScrollToEntry;
36 | private Button mScrollToBtn;
37 |
38 | public static RecyclerFragment newInstance() {
39 | return new RecyclerFragment();
40 | }
41 |
42 | @Nullable
43 | @Override
44 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
45 |
46 | rootView = inflater.inflate(R.layout.rv_fragment, container, false);
47 |
48 | headerView = rootView.findViewById(R.id.rvf_header_parent);
49 |
50 | mRecyclerView = (ConfigurableRecyclerView) rootView.findViewById(R.id.rvf_recycler_view);
51 | mAdapter = new RecyclerFragmentAdapter();
52 | mLayoutManager = new RecyclerLayoutManager(getActivity());
53 | mRecyclerView.setAdapter(mAdapter);
54 | mRecyclerView.setLayoutManager(mLayoutManager);
55 | mRecyclerView.setHasFixedSize(true);
56 |
57 | mLayoutManager.setAppBarManager((AppBarManager) getActivity());
58 |
59 | maxAdapterPosition = mAdapter.getItemCount() - 1;
60 |
61 | mDragTextView = (TextView) rootView.findViewById(R.id.rvf_drag_text_view);
62 | mDragTextView.setOnTouchListener(new View.OnTouchListener() {
63 | @Override
64 | public boolean onTouch(View v, MotionEvent event) {
65 | TextView tv = (TextView) v;
66 |
67 | switch (event.getAction()) {
68 | case MotionEvent.ACTION_DOWN:
69 | tv.setBackgroundColor(Color.LTGRAY);
70 | tv.setText(getString(R.string.drag_message_active));
71 | break;
72 | case MotionEvent.ACTION_UP:
73 | v.setBackgroundColor(0);
74 | tv.setText(getString(R.string.drag_message_idle));
75 | break;
76 | }
77 | return mRecyclerView.dispatchHandlerScroll(event);
78 | }
79 | });
80 |
81 | String scrollToEntryHintText = getString(R.string.rvf_scroll_to_value_et, maxAdapterPosition);
82 | mScrollToEntry = (EditText) rootView.findViewById(R.id.rvf_et);
83 | mScrollToEntry.setHint(scrollToEntryHintText);
84 | mScrollToEntry.setOnEditorActionListener(new TextView.OnEditorActionListener() {
85 | @Override
86 | public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
87 | if (actionId == EditorInfo.IME_ACTION_GO) {
88 | mScrollToBtn.performClick();
89 | }
90 | return false;
91 | }
92 | });
93 |
94 | mScrollToBtn = (Button) rootView.findViewById(R.id.rvf_scroll_to_btn);
95 | mScrollToBtn.setOnClickListener(new View.OnClickListener() {
96 | @Override
97 | public void onClick(View v) {
98 | int target;
99 |
100 | try {
101 | target = Integer.valueOf(mScrollToEntry.getText().toString());
102 | } catch (NumberFormatException e) {
103 | makeToast("Entry must be of type int");
104 | return;
105 | }
106 |
107 | if ((target < 0) || (target > mAdapter.getItemCount() - 1)) {
108 | makeToast("Entry must range from 0 to " + maxAdapterPosition);
109 | return;
110 | }
111 |
112 | mRecyclerView.smoothScrollToPosition(target);
113 | }
114 | });
115 |
116 | return rootView;
117 | }
118 |
119 | public View getHeaderView() {
120 | return headerView;
121 | }
122 |
123 | public ConfigurableRecyclerView getConfigurableRecyclerView() {
124 | return mRecyclerView;
125 | }
126 |
127 | private void makeToast(String content) {
128 | Toast.makeText(getActivity(), content, Toast.LENGTH_SHORT).show();
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/app/src/main/java/com/werdpressed/partisan/scrollhandleexample/RecyclerFragmentAdapter.java:
--------------------------------------------------------------------------------
1 | package com.werdpressed.partisan.scrollhandleexample;
2 |
3 | import android.support.design.widget.AppBarLayout;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.TextView;
9 |
10 | public class RecyclerFragmentAdapter extends RecyclerView.Adapter {
11 |
12 | private final String[] data;
13 |
14 | public RecyclerFragmentAdapter() {
15 | data = Cheeses.CHEESES;
16 | }
17 |
18 | @Override
19 | public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
20 | View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.rv_row, viewGroup, false);
21 | return new ViewHolder(v);
22 | }
23 |
24 | @Override
25 | public void onBindViewHolder(ViewHolder viewHolder, int i) {
26 | viewHolder.mTextView.setText(data[i]);
27 | }
28 |
29 | @Override
30 | public int getItemCount() {
31 | return data.length;
32 | }
33 |
34 | public static class ViewHolder extends RecyclerView.ViewHolder {
35 |
36 | private TextView mTextView;
37 |
38 | public ViewHolder(View itemView) {
39 | super(itemView);
40 | mTextView = (TextView) itemView.findViewById(R.id.rvr_text);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/werdpressed/partisan/scrollhandleexample/RecyclerLayoutManager.java:
--------------------------------------------------------------------------------
1 | package com.werdpressed.partisan.scrollhandleexample;
2 |
3 | import android.content.Context;
4 | import android.graphics.PointF;
5 | import android.support.v7.widget.LinearLayoutManager;
6 | import android.support.v7.widget.LinearSmoothScroller;
7 | import android.support.v7.widget.RecyclerView;
8 | import android.util.Log;
9 | import android.view.View;
10 |
11 | public class RecyclerLayoutManager extends LinearLayoutManager {
12 |
13 | private AppBarManager mAppBarManager;
14 | private int visibleHeightForRecyclerView;
15 |
16 | public RecyclerLayoutManager(Context context) {
17 | super(context);
18 | }
19 |
20 | @Override
21 | public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
22 | View firstVisibleChild = recyclerView.getChildAt(0);
23 | final int childHeight = firstVisibleChild.getHeight();
24 | int distanceInPixels = ((findFirstVisibleItemPosition() - position) * childHeight);
25 | if (distanceInPixels == 0) {
26 | distanceInPixels = (int) Math.abs(firstVisibleChild.getY());
27 | }
28 | //Called Once
29 | if (visibleHeightForRecyclerView == 0) {
30 | visibleHeightForRecyclerView = mAppBarManager.getVisibleHeightForRecyclerViewInPx();
31 | }
32 | //Subtract one as adapter position 0 based
33 | final int visibleChildCount = visibleHeightForRecyclerView/childHeight - 1;
34 |
35 | if (position <= visibleChildCount) {
36 | //Scroll to the very top and expand the app bar
37 | position = 0;
38 | mAppBarManager.expandAppBar();
39 | } else {
40 | mAppBarManager.collapseAppBar();
41 | }
42 |
43 | SmoothScroller smoothScroller = new SmoothScroller(recyclerView.getContext(), Math.abs(distanceInPixels), 1000);
44 | smoothScroller.setTargetPosition(position);
45 | startSmoothScroll(smoothScroller);
46 | }
47 |
48 | public void setAppBarManager(AppBarManager appBarManager) {
49 | mAppBarManager = appBarManager;
50 | }
51 |
52 | private class SmoothScroller extends LinearSmoothScroller {
53 | private static final int TARGET_SEEK_SCROLL_DISTANCE_PX = 10000;
54 | private final float distanceInPixels;
55 | private final float duration;
56 |
57 | public SmoothScroller(Context context, int distanceInPixels, int duration) {
58 | super(context);
59 | this.distanceInPixels = distanceInPixels;
60 | float millisecondsPerPx = calculateSpeedPerPixel(context.getResources().getDisplayMetrics());
61 | this.duration = distanceInPixels < TARGET_SEEK_SCROLL_DISTANCE_PX ?
62 | (int) (Math.abs(distanceInPixels) * millisecondsPerPx) : duration;
63 | }
64 |
65 | @Override
66 | public PointF computeScrollVectorForPosition(int targetPosition) {
67 | return RecyclerLayoutManager.this
68 | .computeScrollVectorForPosition(targetPosition);
69 | }
70 |
71 | @Override
72 | protected int calculateTimeForScrolling(int dx) {
73 | float proportion = (float) dx / distanceInPixels;
74 | return (int) (duration * proportion);
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_lock_open_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PPartisan/ScrollHandleExample/dc0beb9ecd7535ef7de352c036618f7298a0523b/app/src/main/res/drawable-hdpi/ic_lock_open_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_lock_outline_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PPartisan/ScrollHandleExample/dc0beb9ecd7535ef7de352c036618f7298a0523b/app/src/main/res/drawable-hdpi/ic_lock_outline_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_lock_open_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PPartisan/ScrollHandleExample/dc0beb9ecd7535ef7de352c036618f7298a0523b/app/src/main/res/drawable-mdpi/ic_lock_open_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_lock_outline_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PPartisan/ScrollHandleExample/dc0beb9ecd7535ef7de352c036618f7298a0523b/app/src/main/res/drawable-mdpi/ic_lock_outline_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_lock_open_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PPartisan/ScrollHandleExample/dc0beb9ecd7535ef7de352c036618f7298a0523b/app/src/main/res/drawable-xhdpi/ic_lock_open_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_lock_outline_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PPartisan/ScrollHandleExample/dc0beb9ecd7535ef7de352c036618f7298a0523b/app/src/main/res/drawable-xhdpi/ic_lock_outline_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_lock_open_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PPartisan/ScrollHandleExample/dc0beb9ecd7535ef7de352c036618f7298a0523b/app/src/main/res/drawable-xxhdpi/ic_lock_open_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_lock_outline_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PPartisan/ScrollHandleExample/dc0beb9ecd7535ef7de352c036618f7298a0523b/app/src/main/res/drawable-xxhdpi/ic_lock_outline_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/cheeses.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PPartisan/ScrollHandleExample/dc0beb9ecd7535ef7de352c036618f7298a0523b/app/src/main/res/drawable/cheeses.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable/drop_shadow.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
14 |
15 |
21 |
22 |
29 |
30 |
31 |
39 |
40 |
41 |
42 |
43 |
44 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/rv_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
21 |
22 |
27 |
28 |
35 |
36 |
46 |
47 |
48 |
49 |
50 |
51 |
56 |
57 |
62 |
63 |
69 |
70 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/rv_row.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
18 |
19 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
12 |
13 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PPartisan/ScrollHandleExample/dc0beb9ecd7535ef7de352c036618f7298a0523b/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PPartisan/ScrollHandleExample/dc0beb9ecd7535ef7de352c036618f7298a0523b/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PPartisan/ScrollHandleExample/dc0beb9ecd7535ef7de352c036618f7298a0523b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PPartisan/ScrollHandleExample/dc0beb9ecd7535ef7de352c036618f7298a0523b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_cheeses_app_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PPartisan/ScrollHandleExample/dc0beb9ecd7535ef7de352c036618f7298a0523b/app/src/main/res/mipmap-xxxhdpi/ic_cheeses_app_bar.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFC107
4 | #FFA000
5 | #FFECB3
6 | #7C4DFF
7 | #212121
8 | #727272
9 | #212121
10 | #B6B6B6
11 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Scroll Handle Example
3 |
4 | Settings
5 | Lock
6 | Unlock
7 |
8 | Drag Here!
9 | Dragging…
10 |
11 | Cheeses
12 | Enter Value (0 to %1$d)
13 | Scroll!
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.1.0'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/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 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PPartisan/ScrollHandleExample/dc0beb9ecd7535ef7de352c036618f7298a0523b/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon May 30 16:37:18 BST 2016
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-2.10-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 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------