Summary: Restyle of page, including changes to spelling, grammar, links, and structure (where relevant). Reviewed By: aigoncharov Differential Revision: D36632888 fbshipit-source-id: 41c4ddceab4ae6a665559093465a73c595aa494f
140 lines
5.9 KiB
Plaintext
140 lines
5.9 KiB
Plaintext
---
|
|
id: layout-inspector
|
|
title: Extending the Layout Inspector
|
|
---
|
|
import useBaseUrl from '@docusaurus/useBaseUrl';
|
|
|
|
The Layout Inspector plugin can be extended to support new kinds of UI components. You can also extend it to customize the data made available in the sidebar.
|
|
Depending on whether or not you want to expose new data on Android or iOS, there are different interfaces you can use.
|
|
|
|
The following screenshot shows the Layout Inspector in action.
|
|
|
|
<img alt="Layout Inspector" src={useBaseUrl("img/layoutinspector.png")} />
|
|
|
|
## Android
|
|
|
|
### NodeDescriptor
|
|
|
|
To expose an object to the Layout Inspector in Flipper, you have to implement a `NodeDescriptor` that describes your object. For example, the `ViewDescriptor` describes `View` objects and the `FragmentDescriptor` describe `Fragment` instances. These descriptors have a set of callbacks used to expose children and data associated with the object they describe.
|
|
|
|
For the full API, see See [NodeDescriptor.java](https://github.com/facebook/flipper/blob/b0d2983bd440dc41ec67089e11acd394e6566b8f/android/src/main/java/com/facebook/flipper/plugins/inspector/NodeDescriptor.java) in GitHub.
|
|
|
|
`NodeDescriptor` implementations should not subclass other `NodeDescriptor` implementations. Instead, re-use existing behavior from a more generic descriptor, it's best to use a delegate.
|
|
|
|
Following are code snippets that illustrate [how to use](#how-to-use-the-nodedescriptor-on-android) and [how not to use](#how-not-to-use-the-nodedescriptor-on-android) the NodeDescriptor on Android.
|
|
|
|
### How to use the NodeDescriptor on Android
|
|
|
|
```java
|
|
class ViewGroupDescriptor extends NodeDescriptor<ViewGroup> {
|
|
public String getName(ViewGroup node) {
|
|
NodeDescriptor descriptor = descriptorForClass(View.class);
|
|
return descriptor.getName(node);
|
|
}
|
|
}
|
|
```
|
|
|
|
### How not to use the NodeDescriptor on Android
|
|
|
|
```java
|
|
class ViewGroupDescriptor extends ViewDescriptor<ViewGroup> {
|
|
public String getName(ViewGroup node) {
|
|
return super.getName(node);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Register a descriptor
|
|
|
|
Register your descriptor in the `DescriptorMapping` used to instantiate the `InspectorFlipperPlugin`:
|
|
|
|
```java
|
|
final FlipperClient client = FlipperClient.createInstance(mContext);
|
|
final DescriptorMapping descriptorMapping = DescriptorMapping.withDefaults();
|
|
descriptorMapping.register(MyObject.class, new MyObjectDescriptor());
|
|
client.addPlugin(new InspectorFlipperPlugin(mContext, descriptorMapping));
|
|
```
|
|
|
|
### Extending an existing descriptor
|
|
|
|
You may not need to create a whole new descriptor. Instead, you may just want to change extend an existing one to expose some new piece of data. In such a case, just locate the correct descriptor and edit its `getData`, `getAttributes`, and perhaps `setData` methods.
|
|
|
|
## iOS
|
|
|
|
### SKNodeDescriptor
|
|
|
|
To expose an object to the layout inspector in Sonar, you have to implement a `SKNodeDescriptor` that describes the object. For example, `SKViewDescriptor` describes `UIView` objects, and the `SKComponentDescriptor` describes `CKComponent` objects. These descriptors have necessary callbacks that are used to expose its children and data associated with the object they describe.
|
|
|
|
For the full available API, see [SKNodeDescriptor.h](https://github.com/facebook/flipper/blob/b0d2983bd440dc41ec67089e11acd394e6566b8f/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/SKNodeDescriptor.h) in GitHub.
|
|
|
|
`SKNodeDescriptor` implementations should **never** be subclass other `SKNodeDescriptor` implementations. Instead, re-use existing behaviour by explicitly using other descriptors and delegate behaviour.
|
|
|
|
Following are code snippets that illustrate [how to use](#how-to-use-the-sknodedescriptor-on-ios) and [how not to use](#how-not-to-use-the-sknodedescriptor-on-ios) the SKNodeDescriptor on iOS.
|
|
|
|
### How to use the SKNodeDescriptor on iOS
|
|
|
|
```objectivec
|
|
@interface SKArbitraryViewDescriptor : SKNodeDescriptor<ArbitraryView *>
|
|
@end
|
|
|
|
@implementation SKArbitraryViewDescriptor
|
|
|
|
- (NSString *)identifierForNode:(ArbitraryView *)node
|
|
{
|
|
SKNodeDescriptor *descriptor = [self descriptorForClass:[UIView class]];
|
|
return [descriptor identifierForNode:node];
|
|
}
|
|
|
|
@end
|
|
```
|
|
|
|
### How not to use the SKNodeDescriptor on iOS
|
|
|
|
```objectivec
|
|
@interface SKArbitraryViewDescriptor : SKViewDescriptor<ArbitraryView *>
|
|
|
|
@end
|
|
|
|
@implementation SKArbitraryViewDescriptor
|
|
|
|
- (NSString *)identifierForNode:(ArbitraryView *)node
|
|
{
|
|
return [super identifierForNode:node];
|
|
}
|
|
|
|
@end
|
|
```
|
|
|
|
### Register a Descriptor
|
|
|
|
In order to register your descriptor for an object, use `SKDescriptorMapper`. After registering all descriptors, pass on the descriptor-mapper object to the plugin during initialisation:
|
|
|
|
```objectivec
|
|
[descriptorMapper registerDescriptor:[SKArbitraryViewDescriptor new]
|
|
forClass:[ArbitraryView class]];
|
|
|
|
```
|
|
|
|
There's already a set of descriptors registered by default in `SKDescriptorMapper`. If you want to add a descriptor to the default set, you can do it in the [SKDescriptorMapper](https://github.com/facebook/flipper/blob/b0d2983bd440dc41ec67089e11acd394e6566b8f/iOS/Plugins/FlipperKitLayoutPlugin/FlipperKitLayoutPlugin/SKDescriptorMapper.mm).
|
|
|
|
### Extending an existing Descriptor
|
|
|
|
Sometimes, all you need is to extend the functionality of an existing descriptor. In such as case, you just need to locate the correct descriptor and edit the methods `dataForNode`, `attributesForNode`, and possibly `dataMutationsForNode`.
|
|
|
|
### Subdescriptors
|
|
|
|
If you want to extend the `SKComponentKitLayoutDescriptor` and add an additional section based on the nodes of the `SKComponentLayoutDescriptor`, you can use `SKSubDescriptor`:
|
|
|
|
```objectivec
|
|
#import <FlipperKitLayoutComponentKitSupport/SKComponentLayoutWrapper.h>
|
|
|
|
NSString *YourSubDescriptor(SKComponentLayoutWrapper *)node {
|
|
return @"Meta data";
|
|
}
|
|
|
|
// At setup time, you must register it:
|
|
[SKComponentLayoutDescriptor registerSubDescriptor:&YourSubDescriptor forName:@"Section Name"];
|
|
```
|
|
|
|
Swift support is not yet available because you must access `SKComponentLayoutWrapper` to implement a subdescriptor.
|