├── .gitignore
├── Gruntfile.js
├── LICENSE
├── README.md
├── android
├── assets
│ └── README
├── build.xml
├── dist
│ ├── com.tripvi.drawerlayout-android-1.4.0.zip
│ ├── com.tripvi.drawerlayout-android-1.4.2.zip
│ ├── com.tripvi.drawerlayout-android-2.0.0.zip
│ ├── com.tripvi.drawerlayout-android-3.0.0.zip
│ ├── com.tripvi.drawerlayout-android-3.0.1.zip
│ └── drawerlayout.jar
├── lib
│ └── .gitkeep
├── manifest
├── platform
│ ├── README
│ └── android
│ │ └── res
│ │ ├── layout
│ │ └── drawer_main.xml
│ │ └── values
│ │ └── strings.xml
├── src
│ └── com
│ │ └── tripvi
│ │ └── drawerlayout
│ │ ├── ContentFrame.java
│ │ ├── Drawer.java
│ │ ├── DrawerProxy.java
│ │ └── DrawerlayoutModule.java
└── timodule.xml
├── documentation
└── index.md
├── example
└── app.js
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | tmp
3 | bin
4 | build
5 | .apt_generated
6 | .project
7 | .classpath
8 | .settings
9 | libs
10 | build.properties
11 | *.apk
12 | .idea
13 | node_modules
14 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 |
3 | module.exports = function(grunt) {
4 |
5 | grunt.registerTask('build', 'build the module', function() {
6 |
7 | var done = this.async();
8 |
9 | // runt titanium script to build the module
10 | var ti = grunt.util.spawn({
11 | cmd: 'ti',
12 | args: ['build', '-p', 'android', '--build-only'],
13 | opts: {
14 | cwd: 'android'
15 | }
16 | }, function(error, result, code) {
17 | if(error) {
18 | grunt.fail.warn(error, code);
19 | } else {
20 | grunt.log.ok('build successful');
21 | }
22 | done(error, result);
23 | });
24 | ti.stdout.on('data', grunt.log.write);
25 | ti.stderr.on('data', grunt.log.error);
26 |
27 | });
28 |
29 | grunt.registerTask('deploy', 'install the module', function() {
30 |
31 | var done = this.async();
32 | var version = grunt.file.readJSON('package.json').version;
33 | var modPath = path.join(__dirname, 'android/dist/com.tripvi.drawerlayout-android-'+version+'.zip');
34 |
35 | var install = grunt.util.spawn({
36 | cmd: 'gittio',
37 | args: ['install', '-g', modPath]
38 | }, function(error, result, code) {
39 | if(error) {
40 | grunt.fail.warn(error, code);
41 | } else {
42 | grunt.log.ok('installed');
43 | }
44 | done(error, result);
45 | });
46 | install.stdout.on('data', grunt.log.write);
47 | install.stderr.on('data', grunt.log.error);
48 | });
49 |
50 | grunt.registerTask('version', 'update version from package.json', function() {
51 |
52 | // read files
53 | var version = grunt.file.readJSON('package.json').version;
54 | var manifest = grunt.file.read('android/manifest');
55 | var readme = grunt.file.read('README.md');
56 |
57 | // update manifest
58 | grunt.file.write('android/manifest', manifest.replace(/^version.*$/m, "version: " + version));
59 |
60 | // update readme
61 | grunt.file.write('README.md', readme.replace(/gittio-[\d\.]{2,}-00B4CC\.svg/g, "gittio-" + version + "-00B4CC.svg"));
62 |
63 | });
64 |
65 | grunt.registerTask('default', ['version', 'build', 'deploy']);
66 |
67 | };
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (C) 2013 - 2014 Tripvi.Inc
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
21 |
22 | Copyright (c) 2015 - 2016 Manuel Lehner
23 |
24 | Permission is hereby granted, free of charge, to any person obtaining a copy
25 | of this software and associated documentation files (the "Software"), to deal
26 | in the Software without restriction, including without limitation the rights
27 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
28 | copies of the Software, and to permit persons to whom the Software is
29 | furnished to do so, subject to the following conditions:
30 |
31 | The above copyright notice and this permission notice shall be included in
32 | all copies or substantial portions of the Software.
33 |
34 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
37 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
39 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
40 | THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ⚠️
2 |
3 | *THIS REPO IS DEPRECATED SINCE THE DRAWER LAYOUT WAS INTEGRATED INTO THE TITANIUM CORE. CONSIDER USING: https://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.Android.DrawerLayout*
4 |
5 | ___
6 |
7 | # DEPRECATED (Ti.DrawerLayout) [](http://gitt.io/component/com.tripvi.drawerlayout) [](http://unmaintained.tech/)
8 | Native Android [Navigation Drawer](http://developer.android.com/design/patterns/navigation-drawer.html) for [Titanium](http://www.appcelerator.com/titanium/)
9 |
10 | - [Overview](#overview)
11 | - [Installation](#installation)
12 | - [Usage](#usage)
13 | - [Docs](documentation/index.md)
14 | - [Demo](https://github.com/manumaticx/NavigationDrawer-Demo)
15 | - [License](#license)
16 |
17 |
18 | _This is a fork of [Tripvi/Ti.DrawerLayout](https://github.com/Tripvi/Ti.DrawerLayout)_
19 |
20 | ## Overview
21 |
22 |
23 |
24 | This module adds support for using the [DrawerLayout](http://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html) in Titanium Apps.
25 |
26 | The Drawer Layout is a view that can be pulled from the edge of a window. This can answer various purposes. The most common use case is the Navigation Drawer as seen in the above screenshot. The Navigation Drawer displays navigation options in a drawer which slides in from the left edge.
27 |
28 | To expand the drawer the user can either touch the app icon or swipe from the left edge. The navigation drawer overlays the content but not the action bar.
29 |
30 | ## Installation
31 |
32 | * Grab the latest package from the [dist](android/dist) folder
33 | * Install it following [this guide](http://docs.appcelerator.com/titanium/latest/#!/guide/Using_a_Module)
34 | * with [gittio](http://gitt.io/): `$ gittio install com.tripvi.drawerlayout`
35 |
36 | ## Usage
37 |
38 | Here's an example of how to use the module.
39 |
40 | > **Please note:** This module requires a Theme without ActionBar such as `Theme.AppCompat.Light.NoActionBar` since it adds a Toolbar to its own layout. If you do not want the Toolbar, just pass the `hideToolbar` property at creation-time.
41 |
42 | ```javascript
43 | // Load module
44 | var TiDrawerLayout = require('com.tripvi.drawerlayout');
45 |
46 | // define left and center view
47 | var leftView = Ti.UI.createView({backgroundColor:'gray'});
48 | var centerView = Ti.UI.createView({backgroundColor:'white'});
49 |
50 | // create the Drawer
51 | var drawer = TiDrawerLayout.createDrawer({
52 | leftView: leftView,
53 | centerView: centerView
54 | });
55 |
56 | // create a window
57 | var win = Ti.UI.createWindow();
58 |
59 | // add the drawer to the window
60 | win.add(drawer);
61 |
62 | // listen for the open event...
63 | win.addEventListener('open', function(){
64 |
65 | // ...to access activity and action bar
66 | var activity = win.getActivity();
67 | var actionbar = activity.getActionBar();
68 |
69 | if (actionbar){
70 |
71 | // this makes the drawer indicator visible in the action bar
72 | actionbar.displayHomeAsUp = true;
73 |
74 | // open and close with the app icon
75 | actionbar.onHomeIconItemSelected = function() {
76 | drawer.toggleLeftWindow();
77 | };
78 | }
79 | });
80 |
81 | // open the window
82 | win.open();
83 | ```
84 |
85 | #### [API Documentation](documentation/index.md)
86 | #### [Demo App](https://github.com/manumaticx/NavigationDrawer-Demo)
87 |
88 | ## Development
89 |
90 | Contributions are very welcome. If you are able to fix bugs or want to add features to the module, please refer to the [official module development guide](http://docs.appcelerator.com/platform/latest/#!/guide/Android_Module_Development_Guide). You can build the module with `appc` as described there. You can also use `grunt build` here. For distribution a new version, please update the version number in `package.json` and run `grunt`. It will update the version number in manifest and readme. Then it builds the new version and installs it globally with `gittio`.
91 |
92 | ## License
93 |
94 | MIT license, see [LICENSE](LICENSE)
95 |
96 | Copyright (c) 2013 - 2014 by Tripvi Inc., 2015 - 2016 by Manuel Lehner
97 |
98 |
--------------------------------------------------------------------------------
/android/assets/README:
--------------------------------------------------------------------------------
1 | Place your assets like PNG files in this directory and they will be packaged with your module.
2 |
3 | If you create a file named com.tripvi.drawerlayout.js in this directory, it will be
4 | compiled and used as your module. This allows you to run pure Javascript
5 | modules that are pre-compiled.
6 |
7 |
--------------------------------------------------------------------------------
/android/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Ant build script for Titanium Android module drawerlayout
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/android/dist/com.tripvi.drawerlayout-android-1.4.0.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manumaticx/Ti.DrawerLayout/48bd052446172905d24ae545568215a3fe7ffd4a/android/dist/com.tripvi.drawerlayout-android-1.4.0.zip
--------------------------------------------------------------------------------
/android/dist/com.tripvi.drawerlayout-android-1.4.2.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manumaticx/Ti.DrawerLayout/48bd052446172905d24ae545568215a3fe7ffd4a/android/dist/com.tripvi.drawerlayout-android-1.4.2.zip
--------------------------------------------------------------------------------
/android/dist/com.tripvi.drawerlayout-android-2.0.0.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manumaticx/Ti.DrawerLayout/48bd052446172905d24ae545568215a3fe7ffd4a/android/dist/com.tripvi.drawerlayout-android-2.0.0.zip
--------------------------------------------------------------------------------
/android/dist/com.tripvi.drawerlayout-android-3.0.0.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manumaticx/Ti.DrawerLayout/48bd052446172905d24ae545568215a3fe7ffd4a/android/dist/com.tripvi.drawerlayout-android-3.0.0.zip
--------------------------------------------------------------------------------
/android/dist/com.tripvi.drawerlayout-android-3.0.1.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manumaticx/Ti.DrawerLayout/48bd052446172905d24ae545568215a3fe7ffd4a/android/dist/com.tripvi.drawerlayout-android-3.0.1.zip
--------------------------------------------------------------------------------
/android/dist/drawerlayout.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manumaticx/Ti.DrawerLayout/48bd052446172905d24ae545568215a3fe7ffd4a/android/dist/drawerlayout.jar
--------------------------------------------------------------------------------
/android/lib/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manumaticx/Ti.DrawerLayout/48bd052446172905d24ae545568215a3fe7ffd4a/android/lib/.gitkeep
--------------------------------------------------------------------------------
/android/manifest:
--------------------------------------------------------------------------------
1 | version: 3.0.1
2 | apiversion: 4
3 | architectures: arm64-v8a armeabi-v7a x86
4 | description: Native Android DrawerLayout for Titanium
5 | author: metacortex, manumaticx
6 | license: MIT license
7 | copyright: Copyright (c) 2013 - 2014 by Tripvi Inc., 2015 - 2016 by Manuel Lehner
8 |
9 | # these should not be edited
10 | name: drawerlayout
11 | moduleid: com.tripvi.drawerlayout
12 | guid: f0a61bb9-3c4d-457f-84c7-3980a13e3dd2
13 | platform: android
14 | minsdk: 7.0.0
15 |
--------------------------------------------------------------------------------
/android/platform/README:
--------------------------------------------------------------------------------
1 | You can place platform-specific files here in sub-folders named "android" and/or "iphone", just as you can with normal Titanium Mobile SDK projects. Any folders and files you place here will be merged with the platform-specific files in a Titanium Mobile project that uses this module.
2 |
3 | When a Titanium Mobile project that uses this module is built, the files from this platform/ folder will be treated the same as files (if any) from the Titanium Mobile project's platform/ folder.
4 |
--------------------------------------------------------------------------------
/android/platform/android/res/layout/drawer_main.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
10 |
14 |
15 |
26 |
27 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/android/platform/android/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Open
4 | Close
5 |
--------------------------------------------------------------------------------
/android/src/com/tripvi/drawerlayout/ContentFrame.java:
--------------------------------------------------------------------------------
1 | package com.tripvi.drawerlayout;
2 |
3 | import org.appcelerator.titanium.view.TiCompositeLayout;
4 |
5 | import android.content.Context;
6 | import android.util.AttributeSet;
7 |
8 | public class ContentFrame extends TiCompositeLayout {
9 | private static final String TAG = "TripviContentFrame";
10 |
11 | public ContentFrame(Context context) {
12 | super(context);
13 | }
14 |
15 | public ContentFrame(Context context, AttributeSet set) {
16 | super(context, set);
17 | setId(Drawer.id_content_frame);
18 |
19 | }
20 |
21 |
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/android/src/com/tripvi/drawerlayout/Drawer.java:
--------------------------------------------------------------------------------
1 | package com.tripvi.drawerlayout;
2 |
3 | import android.app.Activity;
4 | import android.support.v7.widget.Toolbar;
5 | import android.view.*;
6 | import org.appcelerator.kroll.KrollDict;
7 | import org.appcelerator.kroll.KrollProxy;
8 | import org.appcelerator.titanium.TiBaseActivity;
9 | import org.appcelerator.titanium.TiDimension;
10 | import org.appcelerator.titanium.TiC;
11 | import org.appcelerator.titanium.proxy.TiViewProxy;
12 | import org.appcelerator.titanium.util.TiConvert;
13 | import org.appcelerator.titanium.util.TiRHelper;
14 | import org.appcelerator.titanium.util.TiRHelper.ResourceNotFoundException;
15 | import org.appcelerator.titanium.view.TiCompositeLayout;
16 | import org.appcelerator.titanium.view.TiUIView;
17 |
18 | import ti.modules.titanium.ui.WindowProxy;
19 | import android.support.v4.widget.DrawerLayout;
20 | import android.support.v4.widget.DrawerLayout.LayoutParams;
21 | import android.support.v4.widget.ViewDragHelper;
22 | import android.support.v7.app.AppCompatActivity;
23 | import android.support.v7.app.ActionBarDrawerToggle;
24 | import android.util.Log;
25 | import android.widget.FrameLayout;
26 | import java.lang.reflect.Field;
27 |
28 | public class Drawer extends TiUIView {
29 |
30 | private ActionBarDrawerToggle mDrawerToggle;
31 |
32 | private FrameLayout menu; /* left drawer */
33 | private FrameLayout filter; /* right drawer */
34 | private int menuWidth;
35 | private int filterWidth;
36 | private boolean hasMenu = false;
37 | private boolean hasFilter = false;
38 | private boolean setToolbar = false;
39 | private boolean hasToggle = true;
40 | private boolean hideToolbar = false;
41 |
42 | private TiViewProxy leftView;
43 | private TiViewProxy rightView;
44 | private TiViewProxy centerView;
45 | private Toolbar toolbar;
46 |
47 | // Static Properties
48 | public static final String PROPERTY_LEFT_VIEW = "leftView";
49 | public static final String PROPERTY_CENTER_VIEW = "centerView";
50 | public static final String PROPERTY_RIGHT_VIEW = "rightView";
51 | public static final String PROPERTY_LEFT_VIEW_WIDTH = "leftDrawerWidth";
52 | public static final String PROPERTY_RIGHT_VIEW_WIDTH = "rightDrawerWidth";
53 | public static final String PROPERTY_DRAWER_INDICATOR_ENABLED = "drawerIndicatorEnabled";
54 | public static final String PROPERTY_DRAWER_INDICATOR_IMAGE = "drawerIndicatorImage";
55 | public static final String PROPERTY_RIGHT_DRAWER_LOCK_MODE = "rightDrawerLockMode";
56 | public static final String PROPERTY_LEFT_DRAWER_LOCK_MODE = "leftDrawerLockMode";
57 | public static final String PROPERTY_DRAWER_LOCK_MODE = "drawerLockMode";
58 | public static final String PROPERTY_HIDE_TOOLBAR = "hideToolbar";
59 | public static final String PROPERTY_SWIPE_AREA_WIDTH = "dragMargin";
60 |
61 | private static final String TAG = "TripviDrawer";
62 |
63 | int string_drawer_open = 0;
64 | int string_drawer_close = 0;
65 | int layout_drawer_main = 0;
66 | public static int id_content_frame = 0;
67 | public static int id_main_container = 0;
68 | public static int id_toolbar = 0;
69 |
70 | public Drawer(final DrawerProxy proxy) {
71 | super(proxy);
72 |
73 | try {
74 | string_drawer_open = TiRHelper.getResource("string.drawer_open");
75 | string_drawer_close = TiRHelper.getResource("string.drawer_close");
76 | layout_drawer_main = TiRHelper.getResource("layout.drawer_main");
77 | id_content_frame = TiRHelper.getResource("id.content_frame");
78 | id_main_container = TiRHelper.getResource("id.main_container");
79 | id_toolbar = TiRHelper.getResource("id.toolbar");
80 | } catch (ResourceNotFoundException e) {
81 | Log.e(TAG, "XML resources could not be found!!!");
82 | }
83 |
84 | AppCompatActivity activity = (AppCompatActivity) proxy.getActivity();
85 |
86 | // DrawerLayout
87 | LayoutInflater inflater = LayoutInflater.from(activity);
88 | DrawerLayout layout = (DrawerLayout) inflater.inflate(layout_drawer_main, null,
89 | false);
90 |
91 | layout.setDrawerListener(new DrawerListener());
92 |
93 | toolbar = (Toolbar)layout.findViewById(id_toolbar);
94 | // If no actionbar exists,
95 | if (activity.getSupportActionBar() == null && activity.getActionBar() == null) {
96 | setToolbar = true;
97 | activity.setSupportActionBar(toolbar);
98 | if (!hideToolbar) {
99 | setToolbarVisible(true);
100 | }
101 | }
102 |
103 | // TiUIView
104 | setNativeView(layout);
105 |
106 | }
107 |
108 | private void setToolbarVisible(boolean isVisible) {
109 | if (isVisible) {
110 | toolbar.setVisibility(View.VISIBLE);
111 | } else {
112 | toolbar.setVisibility(View.GONE);
113 | }
114 | }
115 |
116 | private class DrawerListener implements DrawerLayout.DrawerListener {
117 |
118 | @Override
119 | public void onDrawerClosed(View drawerView) {
120 | if (proxy.hasListeners("drawerclose")) {
121 | KrollDict options = new KrollDict();
122 | if (drawerView.equals(menu)) {
123 | options.put("drawer", "left");
124 | } else if (drawerView.equals(filter)) {
125 | options.put("drawer", "right");
126 | }
127 | proxy.fireEvent("drawerclose", options);
128 | }
129 | }
130 |
131 | @Override
132 | public void onDrawerOpened(View drawerView) {
133 | if (proxy.hasListeners("draweropen")) {
134 | KrollDict options = new KrollDict();
135 | if (drawerView.equals(menu)) {
136 | options.put("drawer", "left");
137 | } else if (drawerView.equals(filter)) {
138 | options.put("drawer", "right");
139 | }
140 | proxy.fireEvent("draweropen", options);
141 | }
142 | }
143 |
144 | @Override
145 | public void onDrawerSlide(View drawerView, float slideOffset) {
146 | if (proxy.hasListeners("drawerslide")) {
147 | KrollDict options = new KrollDict();
148 | options.put("offset", slideOffset);
149 | if (drawerView.equals(menu)) {
150 | options.put("drawer", "left");
151 | } else if (drawerView.equals(filter)) {
152 | options.put("drawer", "right");
153 | }
154 | proxy.fireEvent("drawerslide", options);
155 | }
156 | }
157 |
158 | @Override
159 | public void onDrawerStateChanged(int newState) {
160 | if (proxy.hasListeners("change")) {
161 | KrollDict options = new KrollDict();
162 | options.put("state", newState);
163 | options.put("idle", (newState == 0 ? 1 : 0));
164 | options.put("dragging", (newState == 1 ? 1 : 0));
165 | options.put("settling", (newState == 2 ? 1 : 0));
166 | proxy.fireEvent("change", options);
167 | }
168 | }
169 | }
170 |
171 | /**
172 | * Open/Close/Toggle drawers
173 | */
174 | public void toggleLeftDrawer() {
175 | if (((DrawerLayout)getNativeView()).isDrawerOpen(Gravity.START)) {
176 | closeLeftDrawer();
177 | } else {
178 | openLeftDrawer();
179 | }
180 | }
181 |
182 | public void openLeftDrawer() {
183 | ((DrawerLayout) getNativeView()).openDrawer(Gravity.START);
184 | }
185 |
186 | public void closeLeftDrawer() {
187 | ((DrawerLayout) getNativeView()).closeDrawer(Gravity.START);
188 | }
189 |
190 | public void toggleRightDrawer() {
191 | if (((DrawerLayout)getNativeView()).isDrawerOpen(Gravity.END)) {
192 | closeRightDrawer();
193 | } else {
194 | openRightDrawer();
195 | }
196 | }
197 |
198 | public void openRightDrawer() {
199 | ((DrawerLayout) getNativeView()).openDrawer(Gravity.END);
200 | }
201 |
202 | public void closeRightDrawer() {
203 | ((DrawerLayout) getNativeView()).closeDrawer(Gravity.END);
204 | }
205 |
206 | public boolean isLeftDrawerOpen() {
207 | return ((DrawerLayout) getNativeView()).isDrawerOpen(Gravity.START);
208 | }
209 |
210 | public boolean isRightDrawerOpen() {
211 | return ((DrawerLayout) getNativeView()).isDrawerOpen(Gravity.END);
212 | }
213 |
214 | public boolean isLeftDrawerVisible() {
215 | return ((DrawerLayout) getNativeView()).isDrawerVisible(Gravity.START);
216 | }
217 |
218 | public boolean isRightDrawerVisible() {
219 | return ((DrawerLayout) getNativeView()).isDrawerVisible(Gravity.END);
220 | }
221 |
222 | private void initDrawerToggle() {
223 |
224 | AppCompatActivity activity = (AppCompatActivity) proxy.getActivity();
225 |
226 | if (activity.getSupportActionBar() == null) {
227 | return;
228 | }
229 |
230 | // enable ActionBar app icon to behave as action to toggle nav
231 | // drawer
232 | activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
233 | activity.getSupportActionBar().setHomeButtonEnabled(true);
234 |
235 | // ActionBarDrawerToggle ties together the the proper interactions
236 | // between the sliding drawer and the action bar app icon
237 | mDrawerToggle = new ActionBarDrawerToggle(activity, ((DrawerLayout) getNativeView()),
238 | string_drawer_open, string_drawer_close) {
239 | @Override
240 | public void onDrawerClosed(View drawerView) {
241 | if(!drawerView.equals(menu)){
242 | return;
243 | }
244 | super.onDrawerClosed(drawerView);
245 | if (proxy.hasListeners("drawerclose")) {
246 | KrollDict options = new KrollDict();
247 | if (drawerView.equals(menu)) {
248 | options.put("drawer", "left");
249 | } else if (drawerView.equals(filter)) {
250 | options.put("drawer", "right");
251 | }
252 | proxy.fireEvent("drawerclose", options);
253 | }
254 | }
255 |
256 | @Override
257 | public void onDrawerOpened(View drawerView) {
258 | if(!drawerView.equals(menu)){
259 | return;
260 | }
261 | super.onDrawerOpened(drawerView);
262 | if (proxy.hasListeners("draweropen")) {
263 | KrollDict options = new KrollDict();
264 | if (drawerView.equals(menu)) {
265 | options.put("drawer", "left");
266 | } else if (drawerView.equals(filter)) {
267 | options.put("drawer", "right");
268 | }
269 | proxy.fireEvent("draweropen", options);
270 | }
271 | }
272 |
273 | @Override
274 | public void onDrawerSlide(View drawerView, float slideOffset) {
275 |
276 | if(!drawerView.equals(menu)){
277 | return;
278 | }
279 |
280 | super.onDrawerSlide(drawerView, slideOffset);
281 | if (proxy.hasListeners("drawerslide")) {
282 | KrollDict options = new KrollDict();
283 | options.put("offset", slideOffset);
284 | if (drawerView.equals(menu)) {
285 | options.put("drawer", "left");
286 | } else if (drawerView.equals(filter)) {
287 | options.put("drawer", "right");
288 | }
289 | proxy.fireEvent("drawerslide", options);
290 | }
291 | }
292 |
293 | @Override
294 | public void onDrawerStateChanged(int newState) {
295 | super.onDrawerStateChanged(newState);
296 |
297 | if (proxy.hasListeners("change")) {
298 | KrollDict options = new KrollDict();
299 | options.put("state", newState);
300 | options.put("idle", (newState == 0 ? 1 : 0));
301 | options.put("dragging", (newState == 1 ? 1 : 0));
302 | options.put("settling", (newState == 2 ? 1 : 0));
303 | proxy.fireEvent("change", options);
304 | }
305 | }
306 | };
307 | // Set the drawer toggle as the DrawerListener
308 | ((DrawerLayout) getNativeView()).setDrawerListener(mDrawerToggle);
309 |
310 | // onPostCreate
311 | ((DrawerLayout) getNativeView()).post(new Runnable() {
312 | @Override
313 | public void run() {
314 | mDrawerToggle.syncState();
315 | }
316 | });
317 | }
318 |
319 | /**
320 | * drawer
321 | */
322 | private void initLeftDrawer() {
323 | if (hasMenu) {
324 | return;
325 | }
326 |
327 | Log.d(TAG, "initializing left drawer");
328 |
329 | // menu: left drawer
330 | menu = new FrameLayout(proxy.getActivity());
331 | LayoutParams menuLayout = new LayoutParams(LayoutParams.WRAP_CONTENT,
332 | LayoutParams.MATCH_PARENT);
333 | menuLayout.gravity = Gravity.START;
334 | menu.setLayoutParams(menuLayout);
335 |
336 | ((DrawerLayout) getNativeView()).addView(menu);
337 |
338 | hasMenu = true;
339 |
340 | if (hasToggle) {
341 | initDrawerToggle();
342 | }
343 | }
344 |
345 | private void initRightDrawer() {
346 | if (hasFilter) {
347 | return;
348 | }
349 |
350 | Log.d(TAG, "initializing right drawer");
351 |
352 | // filter: right drawer
353 | filter = new FrameLayout(proxy.getActivity());
354 | LayoutParams filterLayout = new LayoutParams(LayoutParams.WRAP_CONTENT,
355 | LayoutParams.MATCH_PARENT);
356 | filterLayout.gravity = Gravity.END;
357 | filter.setLayoutParams(filterLayout);
358 |
359 | ((DrawerLayout) getNativeView()).addView(filter);
360 |
361 | hasFilter = true;
362 | }
363 |
364 | /**
365 | * centerView
366 | */
367 | public void replaceCenterView(TiViewProxy viewProxy) {
368 | if (viewProxy == this.centerView) {
369 | Log.d(TAG, "centerView was not changed");
370 | return;
371 | }
372 | if (viewProxy == null) {
373 | return;
374 | }
375 |
376 | viewProxy.setActivity(proxy.getActivity());
377 | TiUIView contentView = getOrCreateView(viewProxy);
378 |
379 | View view = contentView.getOuterView();
380 | TiCompositeLayout fL = (TiCompositeLayout)getNativeView().findViewById(id_content_frame);
381 | ViewParent viewParent = view.getParent();
382 | if (viewParent == null) {
383 | fL.addView(view, contentView.getLayoutParams());
384 | }
385 | if (viewParent instanceof ViewGroup && viewParent != fL) {
386 | ((ViewGroup)viewParent).removeView(view);
387 | fL.addView(view, contentView.getLayoutParams());
388 | }
389 | if (this.centerView != null) {
390 | fL.removeView(getOrCreateView(this.centerView).getNativeView());
391 | this.centerView.releaseViews();
392 | }
393 | this.centerView = viewProxy;
394 | }
395 |
396 | public void setArrowState (Float state){
397 | // leaving this here for now, maybe replace it later
398 | }
399 |
400 | private void setSwipeArea (Integer width){
401 | try{
402 | Field mDragger = getNativeView().getClass().getDeclaredField("mLeftDragger");
403 | mDragger.setAccessible(true);
404 | ViewDragHelper draggerObj = (ViewDragHelper) mDragger.get(getNativeView());
405 | Field mEdgeSize = draggerObj.getClass().getDeclaredField("mEdgeSize");
406 | mEdgeSize.setAccessible(true);
407 | mEdgeSize.setInt(draggerObj, width);
408 | }catch(NoSuchFieldException e){
409 | Log.e(TAG, e.toString());
410 | }catch(IllegalAccessException e){
411 | Log.e(TAG, e.toString());
412 | }
413 | }
414 |
415 | @Override
416 | public void processProperties(KrollDict d) {
417 | if (d.containsKey(PROPERTY_DRAWER_INDICATOR_ENABLED)) {
418 | hasToggle = TiConvert.toBoolean(d,
419 | PROPERTY_DRAWER_INDICATOR_ENABLED);
420 | }
421 |
422 | if (d.containsKey(PROPERTY_LEFT_VIEW)) {
423 | Object leftView = d.get(PROPERTY_LEFT_VIEW);
424 | if (leftView != null && leftView instanceof TiViewProxy) {
425 | if (leftView instanceof WindowProxy)
426 | throw new IllegalStateException(
427 | "[ERROR] Cannot add window as a child view of other window");
428 | //
429 | this.leftView = (TiViewProxy) leftView;
430 | this.initLeftDrawer();
431 | this.menu.addView(getNativeView(this.leftView));
432 | } else {
433 | Log.e(TAG, "[ERROR] Invalid type for leftView");
434 | }
435 | }
436 | if (d.containsKey(PROPERTY_RIGHT_VIEW)) {
437 | Object rightView = d.get(PROPERTY_RIGHT_VIEW);
438 | if (rightView != null && rightView instanceof TiViewProxy) {
439 | if (rightView instanceof WindowProxy)
440 | throw new IllegalStateException(
441 | "[ERROR] Cannot add window as a child view of other window");
442 | this.rightView = (TiViewProxy) rightView;
443 | this.initRightDrawer();
444 | this.filter.addView(getNativeView(this.rightView));
445 | } else {
446 | Log.e(TAG, "[ERROR] Invalid type for rightView");
447 | }
448 | }
449 | if (d.containsKey(PROPERTY_CENTER_VIEW)) {
450 | Object centerView = d.get(PROPERTY_CENTER_VIEW);
451 | if (centerView != null && centerView instanceof TiViewProxy) {
452 | if (centerView instanceof WindowProxy)
453 | throw new IllegalStateException(
454 | "[ERROR] Cannot use window as a child view of other window");
455 | replaceCenterView((TiViewProxy) centerView);
456 | } else {
457 | Log.e(TAG, "[ERROR] Invalid type for centerView");
458 | }
459 | }
460 | if (d.containsKey(PROPERTY_LEFT_VIEW_WIDTH)) {
461 |
462 | if (menu != null){
463 | if (d.get(PROPERTY_LEFT_VIEW_WIDTH).equals(TiC.LAYOUT_SIZE)) {
464 | menu.getLayoutParams().width = LayoutParams.WRAP_CONTENT;
465 | } else if (d.get(PROPERTY_LEFT_VIEW_WIDTH).equals(TiC.LAYOUT_FILL)) {
466 | menu.getLayoutParams().width = LayoutParams.MATCH_PARENT;
467 | } else if (!d.get(PROPERTY_LEFT_VIEW_WIDTH).equals(TiC.SIZE_AUTO)) {
468 | menuWidth = getDevicePixels(d.get(PROPERTY_LEFT_VIEW_WIDTH));
469 | menu.getLayoutParams().width = menuWidth;
470 | }
471 | }
472 | } else {
473 | if (menu != null){
474 | menu.getLayoutParams().width = LayoutParams.MATCH_PARENT;
475 | }
476 | }
477 | if (d.containsKey(PROPERTY_RIGHT_VIEW_WIDTH)) {
478 |
479 | if (filter != null){
480 | if (d.get(PROPERTY_RIGHT_VIEW_WIDTH).equals(TiC.LAYOUT_SIZE)) {
481 | filter.getLayoutParams().width = LayoutParams.WRAP_CONTENT;
482 | } else if (d.get(PROPERTY_RIGHT_VIEW_WIDTH).equals(TiC.LAYOUT_FILL)) {
483 | filter.getLayoutParams().width = LayoutParams.MATCH_PARENT;
484 | } else if (!d.get(PROPERTY_RIGHT_VIEW_WIDTH).equals(TiC.SIZE_AUTO)) {
485 | filterWidth = getDevicePixels(d.get(PROPERTY_RIGHT_VIEW_WIDTH));
486 | filter.getLayoutParams().width = filterWidth;
487 | }
488 | }
489 | } else {
490 | if (filter != null){
491 | filter.getLayoutParams().width = LayoutParams.MATCH_PARENT;
492 | }
493 | }
494 | if (d.containsKey(PROPERTY_DRAWER_LOCK_MODE)) {
495 | ((DrawerLayout) getNativeView()).setDrawerLockMode(TiConvert.toInt(d
496 | .get(PROPERTY_DRAWER_LOCK_MODE)));
497 | }
498 | if (d.containsKey(PROPERTY_LEFT_DRAWER_LOCK_MODE)) {
499 | setLeftDrawerLockMode(TiConvert.toInt(d
500 | .get(PROPERTY_LEFT_DRAWER_LOCK_MODE)));
501 | }
502 | if (d.containsKey(PROPERTY_RIGHT_DRAWER_LOCK_MODE)) {
503 | setRightDrawerLockMode(TiConvert.toInt(d
504 | .get(PROPERTY_RIGHT_DRAWER_LOCK_MODE)));
505 | }
506 | if (d.containsKey(PROPERTY_HIDE_TOOLBAR)) {
507 | hideToolbar = (TiConvert.toBoolean(d.get(PROPERTY_HIDE_TOOLBAR)));
508 | if (hideToolbar) {
509 | setToolbarVisible(false);
510 | } else {
511 | setToolbarVisible(true);
512 | }
513 | }
514 | if (d.containsKey(PROPERTY_SWIPE_AREA_WIDTH)){
515 | setSwipeArea(getDevicePixels(d.get(PROPERTY_SWIPE_AREA_WIDTH)));
516 | }
517 |
518 | super.processProperties(d);
519 | }
520 |
521 | @Override
522 | public void propertyChanged(String key, Object oldValue, Object newValue,
523 | KrollProxy proxy) {
524 |
525 | Log.d(TAG, "propertyChanged Property: " + key + " old: " + oldValue
526 | + " new: " + newValue);
527 |
528 | if (key.equals(PROPERTY_LEFT_VIEW)) {
529 | if (newValue == this.leftView)
530 | return;
531 | TiViewProxy newProxy = null;
532 | int index = 0;
533 | if (this.leftView != null) {
534 | index = this.menu.indexOfChild(getOrCreateView(this.leftView)
535 | .getNativeView());
536 | }
537 | if (newValue != null && newValue instanceof TiViewProxy) {
538 | if (newValue instanceof WindowProxy)
539 | throw new IllegalStateException(
540 | "[ERROR] Cannot add window as a child view of other window");
541 | newProxy = (TiViewProxy) newValue;
542 | initLeftDrawer();
543 | this.menu.addView(getOrCreateView(newProxy).getOuterView(),
544 | index);
545 | } else {
546 | Log.e(TAG, "[ERROR] Invalid type for leftView");
547 | }
548 | if (this.leftView != null) {
549 | this.menu.removeView(getOrCreateView(this.leftView)
550 | .getNativeView());
551 | }
552 | this.leftView = newProxy;
553 | } else if (key.equals(PROPERTY_RIGHT_VIEW)) {
554 | if (newValue == this.rightView)
555 | return;
556 | TiViewProxy newProxy = null;
557 | int index = 0;
558 | if (this.rightView != null) {
559 | index = this.filter.indexOfChild(
560 | getOrCreateView(this.rightView).getNativeView());
561 | }
562 | if (newValue != null && newValue instanceof TiViewProxy) {
563 | if (newValue instanceof WindowProxy)
564 | throw new IllegalStateException(
565 | "[ERROR] Cannot add window as a child view of other window");
566 | newProxy = (TiViewProxy) newValue;
567 | initRightDrawer();
568 | this.filter.addView(getOrCreateView(newProxy).getOuterView(),
569 | index);
570 | } else {
571 | Log.e(TAG, "[ERROR] Invalid type for rightView");
572 | }
573 | if (this.rightView != null) {
574 | this.filter.removeView(getOrCreateView(this.rightView)
575 | .getNativeView());
576 | }
577 | this.rightView = newProxy;
578 | } else if (key.equals(PROPERTY_CENTER_VIEW)) {
579 | TiViewProxy newProxy = (TiViewProxy) newValue;
580 | replaceCenterView(newProxy);
581 | } else if (key.equals(PROPERTY_LEFT_VIEW_WIDTH)) {
582 |
583 | if (menu == null){
584 | return;
585 | }
586 |
587 | initLeftDrawer();
588 |
589 | if (newValue.equals(TiC.LAYOUT_SIZE)) {
590 | menuWidth = LayoutParams.WRAP_CONTENT;
591 | } else if (newValue.equals(TiC.LAYOUT_FILL)) {
592 | menuWidth = LayoutParams.MATCH_PARENT;
593 | } else if (!newValue.equals(TiC.SIZE_AUTO)) {
594 | menuWidth = getDevicePixels(newValue);
595 | }
596 |
597 | LayoutParams menuLayout = new LayoutParams(menuWidth,
598 | LayoutParams.MATCH_PARENT);
599 | menuLayout.gravity = Gravity.START;
600 | this.menu.setLayoutParams(menuLayout);
601 |
602 | } else if (key.equals(PROPERTY_RIGHT_VIEW_WIDTH)) {
603 |
604 | if (filter == null){
605 | return;
606 | }
607 |
608 | initRightDrawer();
609 |
610 | if (newValue.equals(TiC.LAYOUT_SIZE)) {
611 | filterWidth = LayoutParams.WRAP_CONTENT;
612 | } else if (newValue.equals(TiC.LAYOUT_FILL)) {
613 | filterWidth = LayoutParams.MATCH_PARENT;
614 | } else if (!newValue.equals(TiC.SIZE_AUTO)) {
615 | filterWidth = getDevicePixels(newValue);
616 | }
617 |
618 | LayoutParams filterLayout = new LayoutParams(filterWidth,
619 | LayoutParams.MATCH_PARENT);
620 | filterLayout.gravity = Gravity.END;
621 | this.filter.setLayoutParams(filterLayout);
622 |
623 | } else if (key.equals(PROPERTY_DRAWER_LOCK_MODE)) {
624 | ((DrawerLayout) getNativeView()).setDrawerLockMode(TiConvert.toInt(newValue));
625 | } else if (key.equals(PROPERTY_LEFT_DRAWER_LOCK_MODE)) {
626 | this.setLeftDrawerLockMode(TiConvert.toInt(newValue));
627 | } else if (key.equals(PROPERTY_RIGHT_DRAWER_LOCK_MODE)) {
628 | this.setRightDrawerLockMode(TiConvert.toInt(newValue));
629 | } else if (key.equals(PROPERTY_DRAWER_INDICATOR_ENABLED)) {
630 | boolean b = (Boolean) newValue;
631 | if (mDrawerToggle != null){
632 | mDrawerToggle.setDrawerIndicatorEnabled(b);
633 | }
634 | } else if (key.equals(PROPERTY_HIDE_TOOLBAR)) {
635 | hideToolbar = (TiConvert.toBoolean(newValue));
636 | if (hideToolbar) {
637 | setToolbarVisible(false);
638 | } else {
639 | setToolbarVisible(true);
640 | }
641 | } else if (key.equals(PROPERTY_SWIPE_AREA_WIDTH)){
642 | setSwipeArea(getDevicePixels(newValue));
643 | } else {
644 | super.propertyChanged(key, oldValue, newValue, proxy);
645 | }
646 | }
647 |
648 | public void setLeftDrawerLockMode(int mode) {
649 | setDrawerLockMode(mode, Gravity.START);
650 | }
651 |
652 | public void setRightDrawerLockMode(int mode) {
653 | setDrawerLockMode(mode, Gravity.END);
654 | }
655 |
656 | private void setDrawerLockMode(int mode, int gravity) {
657 | ((DrawerLayout) getNativeView()).setDrawerLockMode(mode, gravity);
658 | }
659 |
660 | @Override
661 | public void release() {
662 | Log.d(TAG, "release");
663 | DrawerLayout layout = (DrawerLayout) getNativeView();
664 | if (layout != null) {
665 | layout.removeAllViews();
666 | layout.setDrawerListener(null);
667 | }
668 | if (menu != null) {
669 | menu.removeAllViews();
670 | menu = null;
671 | }
672 | if (filter != null) {
673 | filter.removeAllViews();
674 | filter = null;
675 | }
676 | if (leftView != null) {
677 | leftView.releaseViews();
678 | leftView = null;
679 | }
680 | if (rightView != null) {
681 | rightView.releaseViews();
682 | rightView = null;
683 | }
684 | if (centerView != null) {
685 | centerView.releaseViews();
686 | centerView = null;
687 | }
688 | if (setToolbar) {
689 | AppCompatActivity activity = (AppCompatActivity) proxy.getActivity();
690 | toolbar.removeAllViews();
691 | toolbar = null;
692 | }
693 | super.release();
694 | proxy = null;
695 | }
696 |
697 | /**
698 | * Helpers
699 | */
700 | public int getDevicePixels(Object value) {
701 | TiDimension nativeSize = TiConvert.toTiDimension(TiConvert.toString(value), TiDimension.TYPE_WIDTH);
702 | return nativeSize.getAsPixels(getNativeView());
703 | }
704 |
705 | private View getNativeView(TiViewProxy viewProxy) {
706 | View nativeView = getOrCreateView(viewProxy).getOuterView();
707 | ViewGroup parentViewGroup = (ViewGroup) nativeView.getParent();
708 | if (parentViewGroup != null) {
709 | parentViewGroup.removeAllViews();
710 | }
711 | return nativeView;
712 | }
713 |
714 | private TiUIView getOrCreateView(TiViewProxy viewProxy) {
715 | if (viewProxy == null) {
716 | return null;
717 | }
718 | TiUIView view = viewProxy.getOrCreateView();
719 | if (view != null) {
720 | return view;
721 | }
722 | Log.w(TAG, "getOrCreateView failed. Returned value is null");
723 | TiBaseActivity originalActivity = (TiBaseActivity) viewProxy.getActivity();
724 | if (originalActivity.isDestroyed()) {
725 | Log.w(TAG, "Original viewProxy activity is destroyed.");
726 | }
727 | Activity thisActivity = this.proxy.getActivity();
728 | if (thisActivity != originalActivity) {
729 | viewProxy.attachActivityLifecycle(thisActivity);
730 | }
731 | return viewProxy.getOrCreateView();
732 | }
733 | }
734 |
--------------------------------------------------------------------------------
/android/src/com/tripvi/drawerlayout/DrawerProxy.java:
--------------------------------------------------------------------------------
1 | package com.tripvi.drawerlayout;
2 |
3 | import org.appcelerator.kroll.annotations.Kroll;
4 | import org.appcelerator.titanium.TiApplication;
5 | import org.appcelerator.titanium.proxy.TiViewProxy;
6 | import org.appcelerator.titanium.util.TiConvert;
7 | import org.appcelerator.titanium.view.TiUIView;
8 |
9 | import android.app.Activity;
10 | import android.os.Message;
11 | import android.util.Log;
12 |
13 | @Kroll.proxy(creatableInModule = DrawerlayoutModule.class)
14 | public class DrawerProxy extends TiViewProxy {
15 |
16 | private static final int MSG_FIRST_ID = TiViewProxy.MSG_LAST_ID + 1;
17 |
18 | private static final int MSG_TOGGLE_LEFT_VIEW = MSG_FIRST_ID + 100;
19 | private static final int MSG_TOGGLE_RIGHT_VIEW = MSG_FIRST_ID + 101;
20 | private static final int MSG_OPEN_LEFT_VIEW = MSG_FIRST_ID + 102;
21 | private static final int MSG_OPEN_RIGHT_VIEW = MSG_FIRST_ID + 103;
22 | private static final int MSG_CLOSE_LEFT_VIEW = MSG_FIRST_ID + 104;
23 | private static final int MSG_CLOSE_RIGHT_VIEW = MSG_FIRST_ID + 105;
24 | private static final int MSG_ARROW_STATE = MSG_FIRST_ID + 106;
25 |
26 | protected static final int MSG_LAST_ID = MSG_FIRST_ID + 999;
27 |
28 | private static final String TAG = "TripviDrawerProxy";
29 |
30 | public DrawerProxy() {
31 | super();
32 | }
33 |
34 | @Override
35 | public TiUIView createView(Activity activity) {
36 | Drawer drawer = new Drawer(this);
37 | drawer.getLayoutParams().autoFillsHeight = true;
38 | drawer.getLayoutParams().autoFillsWidth = true;
39 | return drawer;
40 | }
41 |
42 | @Override
43 | public boolean handleMessage(Message msg) {
44 | switch (msg.what) {
45 | case MSG_TOGGLE_LEFT_VIEW: {
46 | handleToggleLeftView();
47 | return true;
48 | }
49 | case MSG_OPEN_LEFT_VIEW: {
50 | handleOpenLeftView();
51 | return true;
52 | }
53 | case MSG_CLOSE_LEFT_VIEW: {
54 | handleCloseLeftView();
55 | return true;
56 | }
57 | case MSG_TOGGLE_RIGHT_VIEW: {
58 | handleToggleRightView();
59 | return true;
60 | }
61 | case MSG_OPEN_RIGHT_VIEW: {
62 | handleOpenRightView();
63 | return true;
64 | }
65 | case MSG_CLOSE_RIGHT_VIEW: {
66 | handleCloseRightView();
67 | return true;
68 | }
69 | case MSG_ARROW_STATE: {
70 | handleArrowState((Float) msg.obj);
71 | return true;
72 | }
73 | default: {
74 | return super.handleMessage(msg);
75 | }
76 | }
77 | }
78 |
79 | @Override
80 | public void releaseViews()
81 | {
82 | Log.d(TAG, "DrawerProxy releaseViews");
83 | super.releaseViews();
84 | }
85 |
86 | @Override
87 | public void release() {
88 | Log.d(TAG, "DrawerProxy release");
89 | super.release();
90 | }
91 |
92 | private void handleToggleLeftView() {
93 | Drawer v = (Drawer) peekView();
94 | if (v != null) {
95 | v.toggleLeftDrawer();
96 | }
97 | }
98 |
99 | private void handleOpenLeftView() {
100 | Drawer v = (Drawer) peekView();
101 | if (v != null) {
102 | v.openLeftDrawer();
103 | }
104 | }
105 |
106 | private void handleCloseLeftView() {
107 | Drawer v = (Drawer) peekView();
108 | if (v != null) {
109 | v.closeLeftDrawer();
110 | }
111 | }
112 |
113 | private void handleToggleRightView() {
114 | Drawer v = (Drawer) peekView();
115 | if (v != null) {
116 | v.toggleRightDrawer();
117 | }
118 | }
119 |
120 | private void handleOpenRightView() {
121 | Drawer v = (Drawer) peekView();
122 | if (v != null) {
123 | v.openRightDrawer();
124 | }
125 | }
126 |
127 | private void handleCloseRightView() {
128 | Drawer v = (Drawer) peekView();
129 | if (v != null) {
130 | v.closeRightDrawer();
131 | }
132 | }
133 |
134 | private void handleArrowState(Float state){
135 | Drawer v = (Drawer) peekView();
136 | if (v != null) {
137 | v.setArrowState(state);
138 | }
139 | }
140 |
141 | @Kroll.method
142 | public void toggleLeftWindow(@Kroll.argument(optional = true) Object obj) {
143 | if (TiApplication.isUIThread()) {
144 | handleToggleLeftView();
145 | return;
146 | }
147 | Message message = getMainHandler().obtainMessage(MSG_TOGGLE_LEFT_VIEW);
148 | message.sendToTarget();
149 | }
150 |
151 | @Kroll.method
152 | public void openLeftWindow() {
153 | if (TiApplication.isUIThread()) {
154 | handleOpenLeftView();
155 | return;
156 | }
157 | Message message = getMainHandler().obtainMessage(MSG_OPEN_LEFT_VIEW);
158 | message.sendToTarget();
159 | }
160 |
161 | @Kroll.method
162 | public void closeLeftWindow() {
163 | if (TiApplication.isUIThread()) {
164 | handleCloseLeftView();
165 | return;
166 | }
167 | Message message = getMainHandler().obtainMessage(MSG_CLOSE_LEFT_VIEW);
168 | message.sendToTarget();
169 | }
170 |
171 | @Kroll.method
172 | public void toggleRightWindow(@Kroll.argument(optional = true) Object obj) {
173 | if (TiApplication.isUIThread()) {
174 | handleToggleRightView();
175 | return;
176 | }
177 | Message message = getMainHandler().obtainMessage(MSG_TOGGLE_RIGHT_VIEW);
178 | message.sendToTarget();
179 | }
180 |
181 | @Kroll.method
182 | public void openRightWindow() {
183 | if (TiApplication.isUIThread()) {
184 | handleOpenRightView();
185 | return;
186 | }
187 | Message message = getMainHandler().obtainMessage(MSG_OPEN_RIGHT_VIEW);
188 | message.sendToTarget();
189 | }
190 |
191 | @Kroll.method
192 | public void closeRightWindow() {
193 | if (TiApplication.isUIThread()) {
194 | handleCloseRightView();
195 | return;
196 | }
197 | Message message = getMainHandler().obtainMessage(MSG_CLOSE_RIGHT_VIEW);
198 | message.sendToTarget();
199 | }
200 |
201 | @Kroll.method
202 | @Kroll.getProperty
203 | public boolean getIsLeftDrawerOpen() {
204 | Drawer v = (Drawer) peekView();
205 | if (v != null) {
206 | return v.isLeftDrawerOpen();
207 | } else {
208 | return false;
209 | }
210 | }
211 |
212 | @Kroll.method
213 | @Kroll.getProperty
214 | public boolean getIsRightDrawerOpen() {
215 | Drawer v = (Drawer) peekView();
216 | if (v != null) {
217 | return v.isRightDrawerOpen();
218 | } else {
219 | return false;
220 | }
221 | }
222 |
223 | @Kroll.method
224 | @Kroll.getProperty
225 | public boolean getIsLeftDrawerVisible() {
226 | Drawer v = (Drawer) peekView();
227 | if (v != null) {
228 | return v.isLeftDrawerVisible();
229 | } else {
230 | return false;
231 | }
232 | }
233 |
234 | @Kroll.method
235 | @Kroll.getProperty
236 | public boolean getIsRightDrawerVisible() {
237 | Drawer v = (Drawer) peekView();
238 | if (v != null) {
239 | return v.isRightDrawerVisible();
240 | } else {
241 | return false;
242 | }
243 | }
244 |
245 | @Kroll.method
246 | @Kroll.setProperty
247 | public void setLeftDrawerWidth(Object arg) {
248 | setPropertyAndFire(Drawer.PROPERTY_LEFT_VIEW_WIDTH, arg);
249 | }
250 |
251 | @Kroll.method
252 | @Kroll.setProperty
253 | public void setLeftView(Object arg) {
254 | setPropertyAndFire(Drawer.PROPERTY_LEFT_VIEW, arg);
255 | }
256 |
257 | @Kroll.method
258 | @Kroll.setProperty
259 | public void setRightDrawerWidth(Object arg) {
260 | setPropertyAndFire(Drawer.PROPERTY_RIGHT_VIEW_WIDTH, arg);
261 | }
262 |
263 | @Kroll.method
264 | @Kroll.setProperty
265 | public void setRightView(Object arg) {
266 | setPropertyAndFire(Drawer.PROPERTY_RIGHT_VIEW, arg);
267 | }
268 |
269 | @Kroll.method
270 | @Kroll.setProperty
271 | public void setCenterView(Object arg) {
272 | setPropertyAndFire(Drawer.PROPERTY_CENTER_VIEW, arg);
273 | }
274 |
275 | @Kroll.method
276 | public void replaceCenterView(Object arg, boolean backstack) {
277 | Log.w(TAG, "replaceCenterView is deprecated. Please use setCenterView instead.");
278 | setPropertyAndFire(Drawer.PROPERTY_CENTER_VIEW, arg);
279 | }
280 |
281 | @Kroll.method
282 | @Kroll.setProperty
283 | public void setDrawerIndicatorEnabled(Object arg) {
284 | setPropertyAndFire(Drawer.PROPERTY_DRAWER_INDICATOR_ENABLED, arg);
285 | }
286 |
287 | @Kroll.method
288 | @Kroll.setProperty
289 | public void setDrawerLockMode(Object arg) {
290 | setPropertyAndFire(Drawer.PROPERTY_DRAWER_LOCK_MODE, arg);
291 | }
292 |
293 | @Kroll.method
294 | @Kroll.setProperty
295 | public void setLeftDrawerLockMode(Object arg) {
296 | setPropertyAndFire(Drawer.PROPERTY_LEFT_DRAWER_LOCK_MODE, arg);
297 | }
298 |
299 | @Kroll.method
300 | @Kroll.setProperty
301 | public void setRightDrawerLockMode(Object arg) {
302 | setPropertyAndFire(Drawer.PROPERTY_RIGHT_DRAWER_LOCK_MODE, arg);
303 | }
304 |
305 | @Kroll.method
306 | @Kroll.setProperty
307 | public void setDrawerIndicatorImage(Object arg) {
308 | setPropertyAndFire(Drawer.PROPERTY_DRAWER_INDICATOR_IMAGE, arg);
309 | }
310 |
311 | @Kroll.method
312 | public void interceptTouchEvent (TiViewProxy view, Boolean disallowIntercept){
313 | view.getOrCreateView().getOuterView().getParent().requestDisallowInterceptTouchEvent(disallowIntercept);
314 | }
315 |
316 | @Kroll.method
317 | public void setArrowState (Integer state){
318 | Message message = getMainHandler().obtainMessage(MSG_ARROW_STATE, TiConvert.toFloat(state, 0));
319 | message.sendToTarget();
320 | }
321 |
322 | @Kroll.method
323 | @Kroll.setProperty
324 | public void setToolbarHidden(Object arg) {
325 | setPropertyAndFire(Drawer.PROPERTY_HIDE_TOOLBAR, arg);
326 | }
327 |
328 | }
329 |
--------------------------------------------------------------------------------
/android/src/com/tripvi/drawerlayout/DrawerlayoutModule.java:
--------------------------------------------------------------------------------
1 | package com.tripvi.drawerlayout;
2 |
3 | import org.appcelerator.kroll.KrollModule;
4 | import org.appcelerator.kroll.annotations.Kroll;
5 |
6 | import org.appcelerator.titanium.TiApplication;
7 |
8 | import android.support.v4.widget.DrawerLayout;
9 |
10 | @Kroll.module(name = "Drawerlayout", id = "com.tripvi.drawerlayout")
11 | public class DrawerlayoutModule extends KrollModule {
12 | // constants
13 | @Kroll.constant public static final int LOCK_MODE_LOCKED_CLOSED = DrawerLayout.LOCK_MODE_LOCKED_CLOSED;
14 | @Kroll.constant public static final int LOCK_MODE_LOCKED_OPEN = DrawerLayout.LOCK_MODE_LOCKED_OPEN;
15 | @Kroll.constant public static final int LOCK_MODE_UNLOCKED = DrawerLayout.LOCK_MODE_UNLOCKED;
16 |
17 | public DrawerlayoutModule() {
18 | super();
19 | }
20 |
21 | @Kroll.onAppCreate
22 | public static void onAppCreate(TiApplication app) {
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/android/timodule.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/documentation/index.md:
--------------------------------------------------------------------------------
1 | # Ti.DrawerLayout Documentation
2 |
3 | You can create a Drawer by calling `createDrawer` on the module. It must be added as a top-level view to a Ti.UI.Window. You may want to pass a `contentView` property at creation-time. In addition, you can also pass either a `leftView` or `rightView` property to add an actual drawer view to your layout. All of them (`contentView`, `leftView` and `rightView`) must be instances of Ti.UI.View.
4 |
5 | Here's an example:
6 |
7 | ```javascript
8 | var TiDrawerLayout = require('com.tripvi.drawerlayout');
9 | var contentView = Ti.UI.createView();
10 | var leftView = Ti.UI.createTableView({ backgroundColor: '#ccc' });
11 |
12 | var drawer = TiDrawerLayout.createDrawer({
13 | centerView: contentView,
14 | leftView: leftView
15 | });
16 | ```
17 |
18 | And this is how you'd do it in Alloy:
19 |
20 | ```xml
21 |
22 |
23 |
24 |
25 |
26 | ```
27 |
28 | ```javascript
29 | var menu = Alloy.createController('menu');
30 | var main = Alloy.createController('main');
31 |
32 | $.drawer.setLeftView( menu.getView() );
33 | $.drawer.setCenterView( main.getView() );
34 |
35 | ```
36 |
37 | ## Properties
38 |
39 | * `leftView` _(Ti.UI.View)_ - sets the left drawer
40 | * `rightView` _(Ti.UI.View)_ - sets the right drawer
41 | * `centerView` _(Ti.UI.View)_ - sets the center View
42 | * `isLeftDrawerOpen` _(Boolean)_ - wether the left drawer is currently in an open state or not
43 | * `isLeftDrawerVisible` _(Boolean)_ - wether the left drawer is currently visible on-screen or not
44 | * `isRightDrawerOpen` _(Boolean)_ - wether the right drawer is currently in an open state or not
45 | * `isRightDrawerVisible` _(Boolean)_ - wether the right drawer is currently visible on-screen or not
46 | * `leftDrawerWidth` _(Number/String)_ - sets the width of the left drawer
47 | * `rightDrawerWidth` _(Number/String)_ - sets the width of the right drawer
48 | * `drawerIndicatorEnabled` _(Boolean)_ - wether it should use the ActionBarDrawerToggle or not
49 | * ~~`drawerIndicatorImage`~~ _(String)_ - **(DEPRECATED)** path to a custom drawer indicator image
50 | * `drawerLockMode` _(Number)_ - sets the lock mode constant. TiDrawerLayout.LOCK_MODE_UNLOCKED (default), TiDrawerLayout.LOCK_MODE_LOCKED_CLOSED, TiDrawerLayout.LOCK_MODE_LOCKED_OPEN
51 | * `dragMargin` _(Number)_ - defines the width of the area the user can swipe the drawer in
52 | * `hideToolbar` _(Boolean)_ - hides the toolbar
53 |
54 | ## Methods
55 |
56 | * `setLeftView()` - sets the value for the `leftView` property
57 | * `setRightView()` - sets the value for the `rightView` property
58 | * `setCenterView()` - sets the value for the `centerView` property
59 | * ~~`replaceCenterView(view, backstack)`~~ - **(DEPRECATED)** same as `setCenterView` but with second parameter
60 | * `view` _(Ti.UI.View)_ - the new centerView
61 | * `backstack` _(Boolean)_ - set this to `true` if you want to add this to the backstack
62 | * `toggleLeftWindow()` - opens or closes the left drawer
63 | * `openLeftWindow()` - opens the left drawer
64 | * `closeLeftWindow()` - closes the left drawer
65 | * `toggleRightWindow()` - opens or closes the right drawer
66 | * `openRightWindow()` - opens the right drawer
67 | * `closeRightWindow()` - closes the right drawer
68 | * `getIsLeftDrawerOpen()` - returns the value of the `isLeftDrawerOpen` property
69 | * `getIsLeftDrawerVisible()` - returns the value of the `isLeftDrawerVisible` property
70 | * `getIsRightDrawerOpen()` - returns the value of the `isRightDrawerOpen` property
71 | * `getIsRightDrawerVisible()` - returns the value of the `isRightDrawerVisible` property
72 | * `setLeftDrawerWidth()` - sets the value for the `leftDrawerWidth` property
73 | * `setRightDrawerWidth()` - sets the value for the `rightDrawerWidth` property
74 | * `setDrawerIndicatorEnabled()` - sets the value for the `drawerIndicatorEnabled` property
75 | * ~~`setDrawerIndicatorImage()`~~ - **(DEPRECATED)** sets the value for the `drawerIndicatorImage` property
76 | * `setDrawerLockMode()` - sets the value for the `drawerLockMode` property
77 | * `setLeftDrawerLockMode()` - sets the value for the `drawerLockMode` property for the left drawer
78 | * `setRightDrawerLockMode()` - sets the value for the `drawerLockMode` property for the right drawer
79 | * ~~`setArrowState(value)`~~ - **(DEPRECATED)** sets the state of the drawerArrowIcon
80 | * `value` _(Number)_ - state (1 is arrow, 0 is hamburger, but you can set everything between)
81 | * `setToolbarHidden` - sets the value for `hideToolbar` property
82 |
83 | ## Events
84 |
85 | * `change` - fires when the drawer motion state changes
86 | * `state` _(Number)_ - the new drawer motion state
87 | * `idle` _(Boolean)_ - indicates that any drawers are in an idle, settled state. No animation is in progress
88 | * `dragging` _(Boolean)_ - indicates that a drawer is currently being dragged by the user
89 | * `settling` _(Boolean)_ - indicates that a drawer is in the process of settling to a final position
90 |
91 | * `drawerslide` - fires when a drawer's position changes
92 | * `offset` _(Number)_ - the new offset of this drawer within its range, from 0-1
93 | * `drawer` _(String)_ - left or right
94 |
95 | * `draweropen` - fires when the drawer motion state changes
96 | * `drawer` _(String)_ - left or right
97 |
98 | * `drawerclose` - fires when the drawer motion state changes
99 | * `drawer` _(String)_ - left or right
100 |
101 | ## Tricks & Pitfalls
102 |
103 | * Themes: Actionbar vs. Toolbar
104 | * There are two ways to setup the drawer module according to the App bar:
105 | 1. Traditional: Drawer *below* App bar (using the Actionbar)
106 | * use default `Theme.AppCompat` or `Theme.AppCompat.Light`
107 | 2. Material: Drawer *covers* App bar (using the Toolbar)
108 | * use `Theme.AppCompat.NoActionBar` or `Theme.AppCompat.Light.NoActionBar`
109 | * add toolbar padding
110 |
111 |
112 | * Using Drawer for Navigation
113 | * This module only provides the layout itself. The Navigation logic must be done in your own code.
114 | * I've put together an example app to demonstrate this here: [NavigationDrawer Demo App](https://github.com/manumaticx/NavigationDrawer-Demo)
115 |
116 |
117 | * Customizing the drawerArrowToggle
118 | * This is done in your ActionBar theme like this:
119 |
120 | ```xml
121 |
124 |
125 |
129 | ```
130 |
131 | Android Docs: http://developer.android.com/reference/android/support/v7/appcompat/R.styleable.html#DrawerArrowToggle
132 |
133 | * TabGroup & Drawer
134 | * Please refer to my answer [here](https://github.com/manumaticx/Ti.DrawerLayout/issues/32#issuecomment-111413941)
135 |
--------------------------------------------------------------------------------
/example/app.js:
--------------------------------------------------------------------------------
1 | // This is a test harness for your module
2 | // You should do something interesting in this harness
3 | // to test out the module and to provide instructions
4 | // to users on how to use it by example.
5 |
6 |
7 | // open a single window
8 | var TiDrawerLayout = require('com.tripvi.drawerlayout');
9 |
10 | var win = Ti.UI.createWindow({
11 | backgroundColor: 'white',
12 | });
13 |
14 | var menuTable = Ti.UI.createTableView({
15 | data: [
16 | { title: "menu A" },
17 | { title: "menu B" },
18 | { title: "menu C" },
19 | { title: "menu D" },
20 | { title: "menu E" },
21 | { title: "menu F" },
22 | { title: "menu A" },
23 | { title: "menu B" },
24 | { title: "menu C" },
25 | { title: "menu D" },
26 | { title: "menu E" },
27 | { title: "menu F" },
28 | { title: "menu A" },
29 | { title: "menu B" },
30 | { title: "menu C" },
31 | { title: "menu D" },
32 | { title: "menu E" },
33 | { title: "menu F" },
34 | { title: "menu A" },
35 | { title: "menu B" },
36 | { title: "menu C" },
37 | { title: "menu D" },
38 | { title: "menu E" },
39 | { title: "menu F" },
40 | { title: "menu A" },
41 | { title: "menu B" },
42 | { title: "menu C" },
43 | { title: "menu D" },
44 | { title: "menu E" },
45 | { title: "menu F" },
46 | { title: "menu A" },
47 | { title: "menu B" },
48 | { title: "menu C" },
49 | { title: "menu D" },
50 | { title: "menu E" },
51 | { title: "menu F" },
52 | ],
53 | backgroundColor: "#ddd",
54 | });
55 | menuTable.addEventListener("click", function(ev) {
56 | var cv = Ti.UI.createView({
57 | backgroundColor: 'orange',
58 | });
59 | drawer.centerView = cv;
60 | win.title = "ROW " + ev.index;
61 | drawer.closeLeftWindow();
62 | });
63 |
64 | var contentView = Ti.UI.createScrollView({
65 | backgroundColor: "#fff",
66 | layout: "vertical",
67 | });
68 |
69 | var title = Ti.UI.createLabel({
70 | top: "25dp",
71 | text: "Main Content View",
72 | font: {
73 | fontSize: 24,
74 | },
75 | color: "#000",
76 | });
77 | contentView.add(title);
78 |
79 | var changeDrawerWidthButton = Ti.UI.createButton({
80 | top: "25dp",
81 | title: "drawer width: 120",
82 | });
83 | changeDrawerWidthButton.addEventListener("click", function(e) {
84 | drawer.leftDrawerWidth = "120dp";
85 | });
86 | contentView.add(changeDrawerWidthButton);
87 |
88 | var openNewWindowButton = Ti.UI.createButton({
89 | top: "75dp",
90 | title: "open new window",
91 | });
92 | openNewWindowButton.addEventListener("click", function(e) {
93 | var w = Ti.UI.createWindow({
94 | backgroundColor: 'orange',
95 | title: "COOL"
96 | });
97 | w.addEventListener('open', function() {
98 | w.activity.actionBar.logo = "";
99 | w.activity.actionBar.displayHomeAsUp = true;
100 | w.activity.actionBar.subtitle = "hello actionBar";
101 | });
102 | w.open();
103 | });
104 | contentView.add(openNewWindowButton);
105 |
106 | var enableRightDrawerButton = Ti.UI.createButton({
107 | top: "125dp",
108 | title: "enable right drawer",
109 | });
110 | enableRightDrawerButton.addEventListener("click", function(e) {
111 | var rv = Ti.UI.createView({
112 | backgroundColor: "#def"
113 | });
114 |
115 | var caption = Ti.UI.createLabel({
116 | text: "Filter",
117 | font: {
118 | fontSize: 24,
119 | fontWeight: 'bold',
120 | },
121 | color: "#000",
122 | });
123 | rv.add(caption);
124 |
125 | drawer.rightView = rv;
126 | });
127 | contentView.add(enableRightDrawerButton);
128 |
129 |
130 | var drawer = TiDrawerLayout.createDrawer({
131 | leftView: menuTable,
132 | centerView: contentView
133 | //drawerLockMode:TiDrawerLayout.LOCK_MODE_LOCKED_CLOSED, // prevents user from swiping. manual use of toggleLeftWindow() still works
134 | //drawerIndicatorEnabled: false
135 | });
136 | drawer.addEventListener('draweropen', function(e) {
137 | win.title = "open " + e.drawer;
138 | });
139 | drawer.addEventListener('drawerclose', function(e) {
140 | win.title = "close";
141 | });
142 | drawer.addEventListener('drawerslide', function(e) {
143 | win.title = "slide: " + e.offset.toFixed(2);
144 | });
145 |
146 | win.addEventListener("open", function() {
147 | win.activity.actionBar.onHomeIconItemSelected = function() {
148 | drawer.toggleLeftWindow();
149 | };
150 | });
151 |
152 | win.add(drawer);
153 | win.open();
154 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "drawerlayout",
3 | "id": "com.tripvi.drawerlayout",
4 | "version": "3.0.1",
5 | "description": "Android Drawer for Titanium ",
6 | "license": "MIT",
7 | "devDependencies": {
8 | "grunt": "~0.4.5"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------