问题
In my NativeScript project i want to include RecyclerView
from Android Support Library.
I included the dependency in app/App_Resources/Android/app.gradle
:
// Uncomment to add recyclerview-v7 dependency
dependencies {
compile 'com.android.support:recyclerview-v7:+'
}
From git issue#2295 and other related issues, i read that tns-platform-declarations
can be included to offer definition files for native android/ios libraries.
So i installed them and followed tns platform declarations documentation
I want to compile following example snippet:
import { ContentView } from "ui/content-view";
declare var android: any;
export class OptimizedListView extends ContentView {
private _android: android.support.v7.widget.RecyclerView;
public _createUI() {
this._android = new android.support.v7.widget.RecyclerView(this._context);
}
};
Declaring the var android
like above cleans up the second reference of RecyclerView
. But the following error on the top reference of RecyclerView remains:
message: 'Namespace 'android.support.v7.widget' has no exported member 'RecyclerView'.'
I also tried declaring the RecyclerView class without success:
export declare class RecyclerView extends ContentView {}
I am aware of the fact, that tns-platform-declarations
has definitions until android.support.v7.widget
.
Workaround of "noEmitOnError" set to false feels not right.
So how can i extend this declaration to android.support.v7.widget.RecyclerView
without compile issues?
Versions:
- "nativescript-dev-typescript": "^0.3.2"
- "tns-platform-declarations": "^2.4.0-2016-09-28-1"
- "typescript": "^2.1.1"
- "tns-core-modules": "next"
回答1:
Finally I did not go with tns-platform-declarations
at all, because performance was very bad (especially if you have <= 8GB RAM in your dev machine).
My solution was to define a own my-typings.d.ts
file (e.g. in the project root dir) in which I defined the augmenting type RecyclerView
. With tsconfig.json
defaults it should be automatically be caught up by tsc
. Otherwise exclude
/ include
, or files
expressions can be added.
Then you can place a /// <reference path="path/to/RecyclerView/file.d.ts" />
inside, so that the following ambient global namespace
can be found by Typescript compiler.
declare namespace android {
namespace view {
namespace ViewGroup {
namespace LayoutParams {
const MATCH_PARENT;
const WRAP_CONTENT;
}
}
class ViewGroup {
}
}
namespace support.v7.widget {
namespace RecyclerView {
type AdapterImpl = {
onCreateViewHolder(parent: android.view.ViewGroup, viewType: number): ViewHolder;
onBindViewHolder(holder: android.support.v7.widget.RecyclerView.ViewHolder, position: number): void;
getItemCount(): number
};
class Adapter {
static extend(AdapterImpl): { new () }
}
class LayoutParams {
constructor(width: any, height: any);
}
class ViewHolder {
static extend: any;
}
}
class RecyclerView {
constructor(context: any);
setAdapter(Adapter): void;
setLayoutManager(LinearLayoutManager): void;
}
class LinearLayoutManager {
constructor(context: any);
}
}
}
Basically, namespaces can be used to emulate nested object properties (e.g. android.view.xxx
). This is also the way, if inner classes are defined in Java (Typescript seems to forbid nested class
statements).
I also had to define a class with the same name as the namespace in cases, where I actually use the type (like in android.view.ViewGroup
). Otherwise you get above error
no exported member xxx
, even if the class type is explicitly declared with export
(and it's not necessary, because you have globally declared the namespace).
For the special case of extending native Java types with extend
, I defined a static method for the relevant classes like static extend(AdapterImpl): { new () }
, whose return type can be instantiated with new
.
Hope, that helps other with similar issues.
来源:https://stackoverflow.com/questions/40702610/nativescript-augment-tns-platform-declarations