@maccesar/titools 3.2.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -61
- package/lib/cleanup.js +29 -0
- package/lib/commands/agents.js +8 -7
- package/lib/commands/skills.js +118 -23
- package/lib/config.js +13 -15
- package/lib/installer.js +5 -3
- package/lib/utils.js +36 -0
- package/package.json +1 -1
- package/skills/alloy-guides/SKILL.md +188 -0
- package/skills/alloy-guides/references/CLI_TASKS.md +233 -0
- package/skills/alloy-guides/references/CONCEPTS.md +171 -0
- package/skills/alloy-guides/references/CONTROLLERS.md +279 -0
- package/skills/alloy-guides/references/MODELS.md +742 -0
- package/skills/alloy-guides/references/MODELS_ADVANCED.md +482 -0
- package/skills/alloy-guides/references/PURGETSS.md +57 -0
- package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +235 -0
- package/skills/alloy-guides/references/VIEWS_STYLES.md +375 -0
- package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +102 -0
- package/skills/alloy-guides/references/VIEWS_XML.md +581 -0
- package/skills/alloy-guides/references/WIDGETS.md +160 -0
- package/skills/alloy-howtos/SKILL.md +179 -0
- package/skills/alloy-howtos/references/best_practices.md +121 -0
- package/skills/alloy-howtos/references/cli_reference.md +230 -0
- package/skills/alloy-howtos/references/config_files.md +158 -0
- package/skills/alloy-howtos/references/custom_tags.md +148 -0
- package/skills/alloy-howtos/references/debugging_troubleshooting.md +78 -0
- package/skills/alloy-howtos/references/samples.md +156 -0
- package/skills/purgetss/SKILL.md +184 -181
- package/skills/purgetss/references/EXAMPLES.md +8 -6
- package/skills/purgetss/references/app-branding.md +5 -0
- package/skills/purgetss/references/apply-directive.md +1 -1
- package/skills/purgetss/references/class-categories.md +1 -1
- package/skills/purgetss/references/class-index-properties.md +618 -0
- package/skills/purgetss/references/class-index.md +4 -610
- package/skills/purgetss/references/cli-commands.md +41 -410
- package/skills/purgetss/references/custom-fonts.md +292 -0
- package/skills/purgetss/references/custom-rules.md +1 -1
- package/skills/purgetss/references/customization-deep-dive.md +64 -1
- package/skills/purgetss/references/icon-fonts.md +208 -118
- package/skills/purgetss/references/installation-setup.md +4 -4
- package/skills/purgetss/references/migration-guide.md +53 -1
- package/skills/purgetss/references/multi-density-images.md +53 -2
- package/skills/purgetss/references/svg-pipeline.md +249 -0
- package/skills/purgetss/references/tikit-components.md +2 -2
- package/skills/purgetss/references/titanium-resets.md +2 -2
- package/skills/purgetss/references/ui-ux-design.md +7 -5
- package/skills/purgetss/references/version-history.md +71 -82
- package/skills/ti-api/SKILL.md +128 -0
- package/skills/ti-api/references/api-android.md +675 -0
- package/skills/ti-api/references/api-app-platform.md +636 -0
- package/skills/ti-api/references/api-core.md +764 -0
- package/skills/ti-api/references/api-data-network.md +641 -0
- package/skills/ti-api/references/api-media.md +655 -0
- package/skills/ti-api/references/api-modules-ble-bluetooth.md +657 -0
- package/skills/ti-api/references/api-modules-coremotion-urlsession.md +411 -0
- package/skills/ti-api/references/api-modules-map.md +632 -0
- package/skills/ti-api/references/api-modules-nfc.md +725 -0
- package/skills/ti-api/references/api-modules-social-misc.md +526 -0
- package/skills/ti-api/references/api-services.md +700 -0
- package/skills/ti-api/references/api-ui-android.md +499 -0
- package/skills/ti-api/references/api-ui-extras.md +702 -0
- package/skills/ti-api/references/api-ui-ios-animator.md +378 -0
- package/skills/ti-api/references/api-ui-ios.md +756 -0
- package/skills/ti-api/references/api-ui-lists.md +581 -0
- package/skills/ti-api/references/api-ui-text-input.md +607 -0
- package/skills/ti-api/references/api-ui-views.md +572 -0
- package/skills/ti-api/references/api-ui-windows-navigation.md +676 -0
- package/skills/ti-api/references/api-xml-global.md +743 -0
- package/skills/ti-guides/SKILL.md +82 -0
- package/skills/ti-guides/references/advanced-data-and-images.md +155 -0
- package/skills/ti-guides/references/android-manifest.md +97 -0
- package/skills/ti-guides/references/app-distribution.md +373 -0
- package/skills/ti-guides/references/application-frameworks.md +366 -0
- package/skills/ti-guides/references/cli-reference.md +700 -0
- package/skills/ti-guides/references/coding-best-practices.md +150 -0
- package/skills/ti-guides/references/commonjs-advanced.md +279 -0
- package/skills/ti-guides/references/hello-world.md +99 -0
- package/skills/ti-guides/references/hyperloop-native-access.md +458 -0
- package/skills/ti-guides/references/javascript-primer.md +402 -0
- package/skills/ti-guides/references/reserved-words.md +36 -0
- package/skills/ti-guides/references/resources.md +172 -0
- package/skills/ti-guides/references/style-and-conventions.md +104 -0
- package/skills/ti-guides/references/tiapp-config.md +655 -0
- package/skills/ti-howtos/SKILL.md +131 -0
- package/skills/ti-howtos/references/android-platform-deep-dives.md +609 -0
- package/skills/ti-howtos/references/automation-fastlane-appium.md +96 -0
- package/skills/ti-howtos/references/buffer-codec-streams.md +162 -0
- package/skills/ti-howtos/references/cross-platform-development.md +358 -0
- package/skills/ti-howtos/references/debugging-profiling.md +473 -0
- package/skills/ti-howtos/references/extending-titanium.md +684 -0
- package/skills/ti-howtos/references/google-maps-v2.md +172 -0
- package/skills/ti-howtos/references/ios-map-kit.md +149 -0
- package/skills/ti-howtos/references/ios-platform-deep-dives.md +595 -0
- package/skills/ti-howtos/references/local-data-sources.md +310 -0
- package/skills/ti-howtos/references/location-and-maps.md +267 -0
- package/skills/ti-howtos/references/media-apis.md +268 -0
- package/skills/ti-howtos/references/notification-services.md +539 -0
- package/skills/ti-howtos/references/remote-data-sources.md +339 -0
- package/skills/ti-howtos/references/tutorials.md +552 -0
- package/skills/ti-howtos/references/using-modules.md +182 -0
- package/skills/ti-howtos/references/web-content-integration.md +288 -0
- package/skills/ti-howtos/references/webpack-build-pipeline.md +125 -0
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
# Hyperloop: native API access
|
|
2
|
+
|
|
3
|
+
Hyperloop lets you access native APIs (iOS Objective-C/Swift and Android Java/Kotlin) directly from JavaScript. It ships with the Titanium SDK and works as a native module.
|
|
4
|
+
|
|
5
|
+
## 1. Requirements
|
|
6
|
+
|
|
7
|
+
- Titanium SDK: 9.0.0+
|
|
8
|
+
- Titanium CLI: 7.0.0+
|
|
9
|
+
- Alloy (optional): 1.8.0+
|
|
10
|
+
- CocoaPods (optional, iOS only): 1.0.0+
|
|
11
|
+
- Xcode location: must be at `/Applications/Xcode.app`. Hyperloop uses a bundled Xcode library to inspect native APIs. If Xcode is in a non-default location while another installation exists in the default folder, metadata errors can occur.
|
|
12
|
+
|
|
13
|
+
## 2. Enabling Hyperloop
|
|
14
|
+
|
|
15
|
+
Add the Hyperloop module to your `tiapp.xml`:
|
|
16
|
+
|
|
17
|
+
```xml
|
|
18
|
+
<modules>
|
|
19
|
+
<module>hyperloop</module>
|
|
20
|
+
</modules>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The `run-on-main-thread` property should already be in `tiapp.xml` by default:
|
|
24
|
+
```xml
|
|
25
|
+
<property name="run-on-main-thread" type="bool">true</property>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Do not name your app "Hyperloop" in `tiapp.xml`. It is a reserved word and will cause build failures.
|
|
29
|
+
|
|
30
|
+
## 3. Framework namespace conventions
|
|
31
|
+
|
|
32
|
+
Each platform uses different `require()` conventions.
|
|
33
|
+
|
|
34
|
+
iOS: use `Framework/Class` with a forward slash:
|
|
35
|
+
```javascript
|
|
36
|
+
const UIView = require('UIKit/UIView');
|
|
37
|
+
const NSBundle = require('Foundation/NSBundle');
|
|
38
|
+
const UIColor = require('UIKit/UIColor');
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Android: use the full Java package with dots:
|
|
42
|
+
```javascript
|
|
43
|
+
const View = require('android.view.View');
|
|
44
|
+
const Activity = require('android.app.Activity');
|
|
45
|
+
const Context = require('android.content.Context');
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 4. iOS (Objective-C)
|
|
49
|
+
|
|
50
|
+
### Instantiation: `new` vs `alloc().init()`
|
|
51
|
+
|
|
52
|
+
- `new Class()` is equivalent to `alloc().init()`. It only calls the default initializer (`init`).
|
|
53
|
+
- `Class.alloc().initWith*()` is for special initializers that take arguments.
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
const UIView = require('UIKit/UIView');
|
|
57
|
+
|
|
58
|
+
// Default initializer (both are equivalent)
|
|
59
|
+
const view1 = new UIView();
|
|
60
|
+
const view2 = UIView.alloc().init();
|
|
61
|
+
|
|
62
|
+
// Special initializer with arguments
|
|
63
|
+
const CGRectMake = require('CoreGraphics').CGRectMake;
|
|
64
|
+
const view3 = UIView.alloc().initWithFrame(CGRectMake(0, 0, 100, 100));
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Named methods (selector concatenation)
|
|
68
|
+
|
|
69
|
+
Selectors with multiple parameters are camel-cased and colons are removed. Arguments are passed in the same order as in Objective-C.
|
|
70
|
+
|
|
71
|
+
Selector `addAttribute:value:range:` becomes `addAttributeValueRange(attr, val, range)`.
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
// Objective-C: [myView insertSubview:anotherView atIndex:0]
|
|
75
|
+
myView.insertSubviewAtIndex(anotherView, 0);
|
|
76
|
+
|
|
77
|
+
// Objective-C: [UIView animateWithDuration:1.0 animations:^{} completion:^(BOOL){}]
|
|
78
|
+
UIView.animateWithDurationAnimationsCompletion(1.0, () => {
|
|
79
|
+
view.layer.opacity = 0.0;
|
|
80
|
+
}, (finished) => {
|
|
81
|
+
// Animation completed
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Properties
|
|
86
|
+
|
|
87
|
+
Objective-C properties map to JavaScript property accessors. Auto-generated setters are also available:
|
|
88
|
+
```javascript
|
|
89
|
+
view.backgroundColor = UIColor.redColor;
|
|
90
|
+
// or
|
|
91
|
+
view.setBackgroundColor(UIColor.redColor);
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Casting
|
|
95
|
+
|
|
96
|
+
Use `Class.cast(object)` to convert a generic return type (`NSObject` / `id`) or a Titanium proxy to a native view:
|
|
97
|
+
```javascript
|
|
98
|
+
const UIView = require('UIKit/UIView');
|
|
99
|
+
|
|
100
|
+
// Cast a generic object
|
|
101
|
+
const view = UIView.cast(someObject);
|
|
102
|
+
|
|
103
|
+
// Cast a Titanium view to its native equivalent
|
|
104
|
+
const tiView = Ti.UI.createView({ backgroundColor: 'red' });
|
|
105
|
+
const nativeView = UIView.cast(tiView);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Be careful with casting. Casting to the wrong type can crash.
|
|
109
|
+
|
|
110
|
+
### Blocks
|
|
111
|
+
|
|
112
|
+
Blocks are translated to JavaScript callback functions:
|
|
113
|
+
```javascript
|
|
114
|
+
const UIView = require('UIKit/UIView');
|
|
115
|
+
|
|
116
|
+
UIView.animateWithDurationAnimationsCompletion(1.0, () => {
|
|
117
|
+
view.layer.opacity = 0.0;
|
|
118
|
+
}, (done) => {
|
|
119
|
+
// Animation completed
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Constants, enumerations, and functions
|
|
124
|
+
|
|
125
|
+
Framework-level constants and enums are accessed by requiring the framework itself:
|
|
126
|
+
```javascript
|
|
127
|
+
const UIKit = require('UIKit');
|
|
128
|
+
const unspecified = UIKit.UISemanticContentAttributeUnspecified;
|
|
129
|
+
view.semanticContentAttribute = unspecified;
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### TiApp utility class
|
|
133
|
+
|
|
134
|
+
Access Titanium's app instance for the app delegate, key window, and app-level properties:
|
|
135
|
+
```javascript
|
|
136
|
+
const TiApp = require('TiApp/TiApp');
|
|
137
|
+
const app = TiApp.app();
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## 5. iOS: creating custom classes
|
|
141
|
+
|
|
142
|
+
Use `Hyperloop.defineClass()` to create Objective-C classes at runtime:
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
// defineClass(className, superClass, protocolsArray)
|
|
146
|
+
const MyView = Hyperloop.defineClass('MyView', 'UIView', ['UIAppearance']);
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Add methods with `addMethod()`:
|
|
150
|
+
```javascript
|
|
151
|
+
MyView.addMethod({
|
|
152
|
+
selector: 'drawRect:',
|
|
153
|
+
instance: true,
|
|
154
|
+
arguments: ['CGRect'],
|
|
155
|
+
callback: function(rect) {
|
|
156
|
+
// Called when drawRect: is invoked
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Methods with multiple arguments and return types:
|
|
162
|
+
```javascript
|
|
163
|
+
MyView.addMethod({
|
|
164
|
+
selector: 'foo:bar:hello:',
|
|
165
|
+
instance: true,
|
|
166
|
+
returnType: 'void',
|
|
167
|
+
arguments: ['int', 'float', 'id'],
|
|
168
|
+
callback: function(a, b, c) {
|
|
169
|
+
// Invoked when the method is called
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
`addMethod` properties:
|
|
175
|
+
- `selector`: Objective-C selector string
|
|
176
|
+
- `instance`: `true` for instance methods, `false` for class methods
|
|
177
|
+
- `arguments`: array or string of argument types (Objective-C encoding types or general types like `float`, `int`, `id`)
|
|
178
|
+
- `returnType`: string return type (omit for `void`)
|
|
179
|
+
- `callback`: JavaScript implementation
|
|
180
|
+
|
|
181
|
+
Instantiate the custom class normally:
|
|
182
|
+
```javascript
|
|
183
|
+
const myView = new MyView();
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## 6. iOS: CocoaPods support
|
|
187
|
+
|
|
188
|
+
### Installation
|
|
189
|
+
|
|
190
|
+
Install CocoaPods if needed:
|
|
191
|
+
```bash
|
|
192
|
+
sudo gem install cocoapods
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Podfile configuration
|
|
196
|
+
|
|
197
|
+
Create a `Podfile` in your Titanium project root:
|
|
198
|
+
```ruby
|
|
199
|
+
# Required for CocoaPods 1.x
|
|
200
|
+
install! 'cocoapods',
|
|
201
|
+
:integrate_targets => false
|
|
202
|
+
|
|
203
|
+
platform :ios, '12.0'
|
|
204
|
+
target 'YourProjectName' do
|
|
205
|
+
pod 'SomeLibrary'
|
|
206
|
+
end
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Replace `YourProjectName` with your Titanium project name.
|
|
210
|
+
|
|
211
|
+
### Using the pod
|
|
212
|
+
|
|
213
|
+
```javascript
|
|
214
|
+
const JBBarChartView = require('JBChartView/JBBarChartView');
|
|
215
|
+
const chart = new JBBarChartView();
|
|
216
|
+
chart.minimumValue = 1;
|
|
217
|
+
chart.maximumValue = 100;
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Bitcode handling for Ad Hoc builds
|
|
221
|
+
|
|
222
|
+
If your build fails due to mixed Bitcode frameworks, disable Bitcode in your Podfile:
|
|
223
|
+
```ruby
|
|
224
|
+
post_install do |installer|
|
|
225
|
+
installer.pods_project.targets.each do |target|
|
|
226
|
+
target.build_configurations.each do |config|
|
|
227
|
+
config.build_settings['ENABLE_BITCODE'] = 'NO'
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Custom frameworks (without CocoaPods)
|
|
234
|
+
|
|
235
|
+
Drop native iOS frameworks (static or dynamic) into `app/platform/ios` (Alloy) or `platform/ios` (Classic). They will be detected and linked.
|
|
236
|
+
|
|
237
|
+
## 7. iOS: Swift support
|
|
238
|
+
|
|
239
|
+
Hyperloop supports Swift classes alongside Objective-C:
|
|
240
|
+
- Swift and Objective-C classes can be mixed in the same app
|
|
241
|
+
- Use the same `require()` syntax for Swift classes
|
|
242
|
+
- For Swift frameworks via CocoaPods, use the `use_frameworks!` flag in your Podfile
|
|
243
|
+
|
|
244
|
+
## 8. iOS: XIB and Storyboards
|
|
245
|
+
|
|
246
|
+
XIB files and Storyboards must be loaded programmatically. Place them in `app/assets/iphone` (Alloy) or `Resources/iphone` (Classic) and they will be compiled automatically.
|
|
247
|
+
|
|
248
|
+
```javascript
|
|
249
|
+
const NSBundle = require('Foundation/NSBundle');
|
|
250
|
+
const UINib = require('UIKit/UINib');
|
|
251
|
+
|
|
252
|
+
const nib = UINib.nibWithNibNameBundle('MyView', NSBundle.mainBundle);
|
|
253
|
+
const objects = nib.instantiateWithOwnerOptions(null, null);
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
The following resources are compiled automatically: `*.storyboard`, `*.xcdatamodel`, `*.xcdatamodeld`, `*.xcmappingmodel`, `*.xib`.
|
|
257
|
+
|
|
258
|
+
## 9. iOS: customizing the Xcode build
|
|
259
|
+
|
|
260
|
+
> **⚠️ Legacy: `appc.js`**
|
|
261
|
+
> The `appc.js` file was an Appcelerator/AMPLIFY Platform hook. It is no longer supported. For modern Titanium projects, use `tiapp.xml` or native Xcode project settings for build customization.
|
|
262
|
+
|
|
263
|
+
For historical reference, `appc.js` at the project root passed custom flags to `xcodebuild`:
|
|
264
|
+
```javascript
|
|
265
|
+
module.exports = {
|
|
266
|
+
hyperloop: {
|
|
267
|
+
ios: {
|
|
268
|
+
xcodebuild: {
|
|
269
|
+
flags: {
|
|
270
|
+
GCC_PREPROCESSOR_DEFINITIONS: 'foo=bar'
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## 10. Android (Java)
|
|
279
|
+
|
|
280
|
+
### Activity context
|
|
281
|
+
|
|
282
|
+
Most Android view constructors require an Activity context:
|
|
283
|
+
```javascript
|
|
284
|
+
const Activity = require('android.app.Activity');
|
|
285
|
+
const activity = new Activity(Ti.Android.currentActivity);
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Methods and fields
|
|
289
|
+
|
|
290
|
+
Java methods map to JavaScript functions. Java fields map to JavaScript property accessors. Static methods and constants are attached to the class type:
|
|
291
|
+
```javascript
|
|
292
|
+
const View = require('android.view.View');
|
|
293
|
+
const generatedId = View.generateViewId();
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Method overloading
|
|
297
|
+
|
|
298
|
+
Hyperloop selects the matching overload based on parameter types. It is slightly more liberal with numeric primitives because JavaScript numbers are all `Number`.
|
|
299
|
+
|
|
300
|
+
### Casting
|
|
301
|
+
|
|
302
|
+
Pass the object to the constructor of the target type:
|
|
303
|
+
```javascript
|
|
304
|
+
const View = require('android.view.View');
|
|
305
|
+
|
|
306
|
+
// Cast a generic Object to a View
|
|
307
|
+
const view = new View(someObject);
|
|
308
|
+
|
|
309
|
+
// Cast a Titanium view to native
|
|
310
|
+
const tiView = Ti.UI.createView({ backgroundColor: 'red' });
|
|
311
|
+
const nativeView = new View(tiView);
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Interfaces
|
|
315
|
+
|
|
316
|
+
Implement Java interfaces by passing a JavaScript object with matching method names:
|
|
317
|
+
```javascript
|
|
318
|
+
const OnTouchListener = require('android.view.View.OnTouchListener');
|
|
319
|
+
const listener = new OnTouchListener({
|
|
320
|
+
onTouch: (v, event) => {
|
|
321
|
+
// Handle touch
|
|
322
|
+
return true;
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Creating custom classes (Android)
|
|
328
|
+
|
|
329
|
+
Use `.extend()` on the class to subclass, passing an object with method overrides:
|
|
330
|
+
```javascript
|
|
331
|
+
const Activity = require('android.app.Activity');
|
|
332
|
+
const View = require('android.view.View');
|
|
333
|
+
const activity = new Activity(Ti.Android.currentActivity);
|
|
334
|
+
|
|
335
|
+
const MyView = View.extend({
|
|
336
|
+
onDraw: function(canvas) {
|
|
337
|
+
this.super.onDraw(canvas);
|
|
338
|
+
// Custom drawing implementation
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
const customView = new MyView(activity);
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## 11. Android: native XML layouts
|
|
345
|
+
|
|
346
|
+
### Creating the layout
|
|
347
|
+
|
|
348
|
+
Place XML layout files in `app/platform/android/res/layout/` (Alloy) or `platform/android/res/layout/` (Classic).
|
|
349
|
+
|
|
350
|
+
Example `main_content.xml`:
|
|
351
|
+
```xml
|
|
352
|
+
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
353
|
+
android:id="@+id/main_content"
|
|
354
|
+
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
355
|
+
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
356
|
+
android:layout_width="match_parent"
|
|
357
|
+
android:layout_height="match_parent">
|
|
358
|
+
|
|
359
|
+
<ListView
|
|
360
|
+
android:id="@+id/lvToDoList"
|
|
361
|
+
android:layout_width="match_parent"
|
|
362
|
+
android:layout_height="match_parent" />
|
|
363
|
+
|
|
364
|
+
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
|
365
|
+
android:layout_width="wrap_content"
|
|
366
|
+
android:layout_height="wrap_content"
|
|
367
|
+
android:layout_gravity="bottom|right"
|
|
368
|
+
android:layout_margin="16dp" />
|
|
369
|
+
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Inflating the layout
|
|
373
|
+
|
|
374
|
+
```javascript
|
|
375
|
+
const Activity = require('android.app.Activity');
|
|
376
|
+
const Context = require('android.content.Context');
|
|
377
|
+
const Inflater = require('android.view.LayoutInflater');
|
|
378
|
+
|
|
379
|
+
const activity = new Activity(Ti.Android.currentActivity);
|
|
380
|
+
const inflater = Inflater.cast(
|
|
381
|
+
activity.getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)
|
|
382
|
+
);
|
|
383
|
+
|
|
384
|
+
// getIdentifier(name, defType, defPackage) retrieves the R.layout.* ID
|
|
385
|
+
const resId = activity.getResources().getIdentifier('main_content', 'layout', activity.getPackageName());
|
|
386
|
+
const view = inflater.inflate(resId, null);
|
|
387
|
+
|
|
388
|
+
// Add to a Titanium view
|
|
389
|
+
$.myView.add(view);
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
`getIdentifier()` also works for other resource types: `R.color.*`, `R.string.*`, `R.drawable.*`, and others.
|
|
393
|
+
|
|
394
|
+
## 12. Android: third-party libraries
|
|
395
|
+
|
|
396
|
+
### AndroidX requirement
|
|
397
|
+
|
|
398
|
+
As of Titanium SDK 9.0.0, you must use AndroidX libraries. The deprecated Support libraries (`android.support.*`) are not supported.
|
|
399
|
+
|
|
400
|
+
### Gradle dependencies (preferred)
|
|
401
|
+
|
|
402
|
+
Add a `build.gradle` file to `app/platform/android/` (Alloy) or `platform/android/` (Classic):
|
|
403
|
+
|
|
404
|
+
```groovy
|
|
405
|
+
dependencies {
|
|
406
|
+
implementation 'com.google.android.material:material:1.1.0'
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Local JAR/AAR dependencies
|
|
411
|
+
|
|
412
|
+
Place JAR and AAR files directly in `app/platform/android/` (Alloy) or `platform/android/` (Classic). Hyperloop will:
|
|
413
|
+
- Load Java classes and generate bindings
|
|
414
|
+
- For AARs, extract resources, assets, `*.so` libraries, and merge `AndroidManifest.xml`
|
|
415
|
+
|
|
416
|
+
### Third-party library example
|
|
417
|
+
|
|
418
|
+
```javascript
|
|
419
|
+
// After adding the AAR to app/platform/android/
|
|
420
|
+
const Activity = require('android.app.Activity');
|
|
421
|
+
const ParkedTextView = require('com.goka.parkedtextview.ParkedTextView');
|
|
422
|
+
|
|
423
|
+
const activity = new Activity(Ti.Android.currentActivity);
|
|
424
|
+
const parkedView = new ParkedTextView(activity);
|
|
425
|
+
parkedView.setParkedText('.slack.com');
|
|
426
|
+
parkedView.setHintText('your-team');
|
|
427
|
+
|
|
428
|
+
// Listen to events via interfaces
|
|
429
|
+
const TextWatcher = require('android.text.TextWatcher');
|
|
430
|
+
const watcher = new TextWatcher({
|
|
431
|
+
onTextChanged: () => { console.log('Changed'); },
|
|
432
|
+
afterTextChanged: (s) => { console.log('After:', s); },
|
|
433
|
+
beforeTextChanged: () => { console.log('Before'); }
|
|
434
|
+
});
|
|
435
|
+
parkedView.addTextChangedListener(watcher);
|
|
436
|
+
|
|
437
|
+
$.myView.add(parkedView);
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
## 13. Debugging Hyperloop
|
|
441
|
+
|
|
442
|
+
- iOS: use Safari Web Inspector to debug Hyperloop code up to the native transition point
|
|
443
|
+
- Android: use Chrome DevTools for JavaScript debugging
|
|
444
|
+
- Breakpoints may not hit correctly because Hyperloop modifies source files during the build process
|
|
445
|
+
- No source maps are available for processed Alloy controllers
|
|
446
|
+
|
|
447
|
+
## 14. Performance tips
|
|
448
|
+
|
|
449
|
+
- Do not use Hyperloop for things Titanium already does well.
|
|
450
|
+
- Use it for specialized APIs: custom UI components, hardware access not covered by modules, or native third-party library integration.
|
|
451
|
+
- Existing Titanium modules (Java for Android, Objective-C for iOS) continue to be supported alongside Hyperloop.
|
|
452
|
+
|
|
453
|
+
## 15. Sample projects
|
|
454
|
+
|
|
455
|
+
The cross-platform example app demonstrates native APIs for iOS and Android, including CocoaPods, Android AAR packages, UICollectionView, Beacons, BottomNavigationView, native XML layouts, Storyboards, XIBs, and more.
|
|
456
|
+
|
|
457
|
+
- Repository: https://github.com/tidev/hyperloop-examples
|
|
458
|
+
- Community modules: https://github.com/hyperloop-modules (JavaScript wrappers around native APIs such as Speech, Mapbox, Snackbar)
|