全部产品
Search
文档中心

SuperApp:UI定制化开发文档

更新时间:Mar 30, 2026

UI定制化开发文档

一、背景

部分客户希望授权页面自定义

二、目标

支持客户全部/部分 UI自定义

三、如何开发配置

3.1 Native场景

3.1.1 引入相关包

    // in build.gradle
    implementation "com.aliyun.emas.suite.foundation:mini-app-plugin-base:xxx"

3.1.2 预定义UI接口

public interface UIExtension {

    public default Fragment createMoreDialogFragment(HashMap<String, Object> params) {    return null;    }

    public default Fragment createFavoriteDialogFragment(HashMap<String, Object> params) {    return null;    }

    public default Fragment createAuthDialogFragment(HashMap<String, Object> params) {    return null;    }

    public default Fragment createLoadingFragment(HashMap<String, Object> params) {    return null;    }

    public default Fragment createErrorPageFragment(HashMap<String, Object> params) {    return null;    }

    public default Fragment createSplashFragment(HashMap<String, Object> params) {    return null;    }

    public default void createStyle(HashMap<String, Object> params) {    return ;    }


    public default void createTheme(HashMap<String, Object> params) {    return ;    }
}

3.1.3 实现部分或全部接口

    @Override
    public Fragment createMoreDialogFragment(HashMap<String, Object> params) {
        MoreDialogFragment fragment = MoreDialogFragment.newInstance("/ui/more", arguments);
        return fragment;
    }

    @Override
    public Fragment createAuthDialogFragment(HashMap<String, Object> params) {
        AuthDialogFragment fragment = AuthDialogFragment.newInstance("/ui/auth", arguments);
        return fragment;
    }

3.1.4 实现插件

public class CustomUIPlugin extends BasePlugin implements UIExtension {


    public CustomUIPlugin(Context context) {
        super(context);
    }

    @Override
    public Fragment createMoreDialogFragment(HashMap<String, Object> params) {
        MoreDialogFragment fragment = MoreDialogFragment.newInstance("/ui/more", arguments);
        return fragment;
    }

    @Override
    public Fragment createAuthDialogFragment(HashMap<String, Object> params) {
        AuthDialogFragment fragment = AuthDialogFragment.newInstance("/ui/auth", arguments);
        return fragment;
    }

    ...
}

3.1.5 注册插件

    private void initWindVaneMiniApp() {

        // 1. config the MiniAppService params
        MiniAppInitConfig config = new MiniAppInitConfig.Builder()
                .setUseWindVane(true)
                .setUseUniApp(false)
                .setHost("poc.superapp-intl.com")
                .setAppCode("YourAppCode")
                .setAccessKey("YourAccessKey")
                .setSecretKey("YourSecretKey")
                .build();

        // 2. create miniAppService object and init it
        IMiniAppService miniAppService = new MiniAppService();
        miniAppService.initialize(application, config);

        ...

        // 2. register plugin
        miniAppService.registerPlugin("CustomUIPlugin", CustomUIPlugin(this));
    }

3.2 Flutter场景

3.2.1 引入相关包

    // in build.gradle
    implementation "com.aliyun.emas.suite.foundation:mini-app-plugin-base:xxx"

3.2.2 实现FlutterFragment容器 Implement FlutterFragment Container

对于想使用flutter页面展示弹框的客户需要先实现FlutterFragment容器

public class FlutterAuthDialogFragment extends FlutterFragment {
    private static final String TAG = FlutterAuthDialogFragment.class.getName();

    public FlutterAuthDialogFragment() {
        // Required empty public constructor
    }

    // TODO: Rename and change types and number of parameters
    public static FlutterFragment newInstance(String route, Map<String, Object> arguments) {

        praseParams(arguments);
        
        FlutterFragment flutterFragment = FlutterAuthDialogFragment.withNewEngine()
                .initialRoute(route)
                .dartEntrypoint(dartEntrypoint)
                .build();

        return flutterFragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_flutter_auth_dialog, container, false);
    }


    @Override
    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        super.configureFlutterEngine(flutterEngine);

        GeneratedPluginRegistrant.registerWith(flutterEngine);

        // "flutter_auth_dialog" is flutter channel name
        new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), "flutter_auth_dialog").setMethodCallHandler(
                new MethodChannel.MethodCallHandler() {
                    @Override
                    public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {

                        IAuthService authService = PluginEnv.getInstance().getContainerContext().getAuthService();

                        
                        if (FlutterUIPluginConstant.FLUTTER_APPROVAL_AUTH_ACTION.equals(call.method)) {

                            Log.i(TAG, "approval auth");

                            Map<String, Object> arguments = (Map<String, Object>)call.arguments;
                            String permission = (String)arguments.get("permission");
                            String userId = (String)arguments.get("userId");
                            String miniAppId = (String)arguments.get("miniAppId");

                            
                            // Handle approval authorization actions
                            authService.applyAuth(FlutterAuthDialogFragment.this.getActivity(), permission, userId, miniAppId)

                            // return 'result' to flutter code
                            result.success(true);
                        } else if (FlutterUIPluginConstant.FLUTTER_CHECK_AUTH_ACTION.equals(call.method)) {
                            Log.i(TAG, "check auth");

                            Map<String, Object> arguments = (Map<String, Object>)call.arguments;
                            String permission = (String)arguments.get("permission");
                            String userId = (String)arguments.get("userId");
                            String miniAppId = (String)arguments.get("miniAppId");

                            // Handle check authorization actions
                            boolean isAuthorized = authService.isAuthorized(FlutterAuthDialogFragment.this.getActivity(), permission, userId, miniAppId);

                            // return 'result' to flutter code
                            result.success(isAuthorized);
                        } else {
                            result.notImplemented();
                        }
                    }
                }
        );
    }

}

3.2.3 实现flutter授权页面

class AuthListPage extends StatelessWidget {
  AuthListPage({super.key});

  final List<String> permissionsItem = [
    "location",
    "album",
    "camera",
    "bluetooth",
    "contacts",
    "microphone",
    "file",
    "call",
    "vibrate",
    "screen",
  ];
  final List<bool> approvalItem = [
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
  ];


  @override
  Widget build(BuildContext context) {

    return SizedBox(
      height: 1000,
      child: ListView.builder(
        itemCount: permissionsItem.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(permissionsItem[index]),
            onTap: () {
              print("click item:${permissionsItem[index]}");


              Map<String, String> args = {
                "permission": permissionsItem[index],
                "userId": "123",
                "miniAppId": "17856810363",
              };


              WindVaneMiniAppManager.authChannel.invokeMethod(approvalItem[index] ? "flutter_revoke_auth_action" : "flutter_approval_auth_action", args).then((result) {
                approvalItem[index] = result;
              });

            },
          );
        },
      ),
    );

    
  }

}

3.2.4 实现flutter method channel

class WindVaneMiniAppManager {
  static const MethodChannel authChannel = const MethodChannel("flutter_auth_dialog");
}

3.2.5 声明flutter页面路由

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      
      onGenerateRoute: (RouteSettings settings) {
        final uri = Uri.parse(settings.name ?? '/');
        Map<String, String> params = uri.queryParameters;
        String path = uri.path;

        if (path == "/ui/auth") {
            
          return MaterialPageRoute(builder: (BuildContext context) {
            return AuthListPage();
          });
            
        } else if (path == "/ui/more") {
            
          return MaterialPageRoute(builder: (BuildContext context) {
            return const MoreDialogPage();
          });
            
        } else {
          ...
        }
      },
      initialRoute: 'home',
      builder: EasyLoading.init(),
    );
  }
}

3.2.6 实现UI接口

public class FlutterUIPlugin extends BasePlugin implements UIExtension {


    public FlutterUIPlugin(Context context) {
        super(context);
    }

    @Override
    public Fragment createMoreDialogFragment(HashMap<String, Object> params) {
        FlutterMoreDialogFragment fragment = FlutterMoreDialogFragment.newInstance("/ui/more", "");
        return fragment;
    }

    @Override
    public Fragment createAuthDialogFragment(HashMap<String, Object> params) {

        // "/ui/auth" is flutter page route
        FlutterFragment fragment = FlutterAuthDialogFragment.newInstance("/ui/auth", "");
        return fragment;
    }
}

3.2.7 注册插件

    private void initWindVaneMiniApp() {

        // 1. config the MiniAppService params
        MiniAppInitConfig config = new MiniAppInitConfig.Builder()
                .setUseWindVane(true)
                .setUseUniApp(false)
                .setHost("poc.superapp-intl.com")
                .setAppCode("YourAppCode")
                .setAccessKey("YourAccessKey")
                .setSecretKey("YourSecretKey")
                .build();

        // 2. create miniAppService object and init it
        IMiniAppService miniAppService = new MiniAppService();
        miniAppService.initialize(application, config);

        ...

        // 2. register plugin
        miniAppService.registerPlugin("FlutterUIPlugin", FlutterUIPlugin(this));
    }

3.3 授权库接口

3.3.1 预定义Auth接口

public interface IAuthService {

    public void applyAuth(Context context, String permission, String userId, String miniAppId);

    public void applyAuthList(Context context, List<String> permissions, String userId, String miniAppId);

    public void revokeAuth(Context context, String permission, String userId, String miniAppId);

    public void revokeAuthList(Context context, List<String> permissions, String userId, String miniAppId);
    
    public String queryAuthInfo(Context context, String userId, String miniAppId);

    public boolean isAuthorized(Context context, String permission, String userId, String miniAppId);
    
    
}

3.3.2 引入AuthService

    // in build.gradle
    implementation "com.aliyun.emas.suite.foundation:mini-app-plugin-base:xxx"


3.3.3 使用AuthService

    IAuthService authService = PluginEnv.getInstance().getContainerContext().getAuthService();
    authService.authorize(context, permission, userId, miniAppId);