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);