목적 : 홈 화면의 위젯에서 바로가기 메뉴 클릭시 웹뷰의 메뉴 이동
개념도
홈화면 위젯에서 버튼 클릭시 아래와 같은 순서로 실행됩니다.
홈화면 위젯에서 버튼 클릭 -> WidgetProvider -> flutter(main.dart)
WidgetProvider 에서는 홈위젯의 어떤 메뉴가 클릭되었는지 확인합니다.
해결되지 않았던부분이 menu1 클릭시 앱이 화면에 보여줘야 되는데 안보이고 내부 데이터만 보여진 부분입니다.
이때의 코드는 아래와 같습니다.
수정전
val backgroundIntentMenu1 = HomeWidgetBackgroundIntent.getBroadcast(context,
Uri.parse("myAppWidget://updatecountermenu1"))
setOnClickPendingIntent(R.id.bt_menu1, backgroundIntentMenu1)
수정후
val backgroundIntentMenu1 = HomeWidgetLaunchIntent.getActivity(
context,
MainActivity::class.java,
Uri.parse("myAppWidget://updatecountermenu1")
);
setOnClickPendingIntent(R.id.bt_menu1, backgroundIntentMenu1)
HomeWidgetLaunchIntent.getActivity 호출해야 하는데
HomeWidgetBackgroundIntent.getBroadcast 호출 원인입니다.
HomeWidgetLaunchIntent.getActivity: HomeWidgetLaunchIntent 클래스의 getActivity 메서드를 호출하여 PendingIntent를 생성합니다.
이 메서드는 주어진 액티비티를 실행하는 PendingIntent를 반환합니다.
context: 현재 컨텍스트를 나타냅니다.
액티비티나 서비스 등에서 제공되는 컨텍스트입니다.
MainActivity::class.java: 실행할 액티비티의 클래스를 지정합니다.
여기서는 MainActivity입니다.
Uri.parse("myAppWidget://updatecountermenu1"): Intent에 추가할 URI를 지정합니다.
이 URI는 특정 동작 또는 데이터를 식별하는 데 사용됩니다.
여기서 "myAppWidget://updatecountermenu1"은 사용자 정의 스킴인 "myAppWidget"을 가진 URI입니다.
이는 나중에 해당 URI로 전달된 데이터를 처리하는 데 사용됩니다.
setOnClickPendingIntent: 위젯의 레이아웃에서 특정 뷰(여기서는 R.id.bt_menu1)에 대한 클릭 이벤트에 대한 PendingIntent를 설정합니다.
R.id.bt_menu1: 클릭 이벤트를 설정할 위젯의 뷰 ID입니다.
이 경우에는 bt_menu1이라는 뷰의 ID를 나타냅니다.
backgroundIntentMenu1: 앞서 생성한 PendingIntent입니다.
이 PendingIntent는 bt_menu1이 클릭될 때 실행되는 동작을 정의합니다.
여기서는 MainActivity를 실행하는 Intent입니다.
즉, 이 코드는 bt_menu1이라는 버튼이 클릭될 때 MainActivity를 실행하는 PendingIntent를 설정하는 역할을 합니다.
그렇다면 이제 실제 myAppWidget URI 가지고 main.dart 의 어떤 부분이 실행될까요?
보통 backgroundCallback 함수가 호출되는데 backgroundCallback 호출되면 실제 webviewController 에 접근이 안됩니다.
그래서 backgroundCallback 함수를 class _WebViewAppState extends State<WebViewApp> 안에 정의 합니다.
main.dart
class _WebViewAppState extends State<WebViewApp> {
late WebViewController controller;
@override
void initState() {
super.initState();
WebViewControllerManager webViewControllerManager = WebViewControllerManager();
controller = webViewControllerManager.getIns();
HomeWidget.registerBackgroundCallback(homeWidgetBackgroundCallback);
HomeWidget.widgetClicked.listen((uri) => loadData(uri));
}
late WebViewController controller;: _WebViewAppState 클래스에 속하는 WebViewController 변수를 선언합니다.
이 컨트롤러는 웹 뷰의 동작을 제어하고 상태를 관리하는 데 사용됩니다.
late 키워드는 나중에 초기화되는 변수임을 나타냅니다.
initState 메서드: 위젯이 생성될 때 호출되는 생명 주기 메서드 중 하나입니다.
super.initState()를 호출하여 부모 클래스의 initState를 실행한 후에 추가적인 초기화를 진행합니다.
WebViewControllerManager webViewControllerManager = WebViewControllerManager();: WebViewControllerManager 클래스의 인스턴스를 생성합니다.
이 클래스는 웹 뷰 컨트롤러를 관리하는데 사용됩니다.
controller = webViewControllerManager.getIns();
: 위에서 생성한 WebViewControllerManager 인스턴스를 통해 웹 뷰 컨트롤러를 가져와 controller 변수에 할당합니다.
HomeWidget.registerBackgroundCallback(homeWidgetBackgroundCallback);
: 홈 위젯의 백그라운드 콜백을 등록합니다.
이 콜백은 홈 위젯이 백그라운드에서 실행될 때 호출되는 함수를 지정합니다.
HomeWidget.widgetClicked.listen((uri) => loadData(uri));
: HomeWidget에서 제공하는 widgetClicked 스트림을 구독합니다.
이 스트림은 위젯이 클릭될 때 발생하는 이벤트를 수신할 수 있도록 합니다.
클릭된 URI에 대해 loadData 함수를 호출합니다.
총괄적으로 보면, 이 코드는 웹 뷰 컨트롤러를 초기화하고, 홈 위젯의 백그라운드 콜백 및 클릭 이벤트에 대한 처리를 설정하는 부분입니다.
다음 코드는 homeWidgetBackgroundCallback 함수로, 홈 위젯이 백그라운드에서 실행될 때 호출되는 콜백 함수입니다.
주어진 Uri 매개변수를 기반으로 특정 동작을 수행합니다.
@pragma("vm:entry-point")
void homeWidgetBackgroundCallback(Uri? uri) async {
WebViewControllerManager webViewControllerManager = WebViewControllerManager();
print(">>>>>backgroundCallback");
print(uri?.host);
// 1번 위젯
if (uri?.host == 'updatecounter') {
// 스타루트 페이지 가지고오 C110816
String html = await fetchPrdCd();
// fetch page 를 분석
Map<String, dynamic> parsedPrdcdJson = fetchSplit(html);
var prdcdSell = parsedPrdcdJson['USDKRW']['sell'];
var prdcdBuy = parsedPrdcdJson['USDKRW']['buy'];
print("fetch 숫자 Sell: $prdcdSell");
print("fetch 숫자 Buy : $prdcdBuy");
int _counter = 0;
await HomeWidget.getWidgetData<int>('_counter', defaultValue: 0)
.then((int? value) {
_counter = value ?? 0;
_counter++;
});
await HomeWidget.saveWidgetData<String>('_prdcdSell', prdcdSell);
await HomeWidget.saveWidgetData<String>('_prdcdBuy', prdcdBuy);
await HomeWidget.saveWidgetData<int>('_counter', _counter);
await HomeWidget.updateWidget(name: 'AppWidgetProvider', iOSName: 'AppWidgetProvider');
}
else if (uri?.host == 'updatecounterlarge') {
// 스타루트 페이지 가지고오 C110816
String html = await fetchPrdCd();
// fetch page 를 분석
Map<String, dynamic> parsedPrdcdJson = fetchSplit(html);
var prdcdSell = parsedPrdcdJson['USDKRW']['sell'];
var prdcdBuy = parsedPrdcdJson['USDKRW']['buy'];
print("fetch 숫자 Sell: $prdcdSell");
print("fetch 숫자 Buy : $prdcdBuy");
int _counter = 0;
await HomeWidget.getWidgetData<int>('_counter', defaultValue: 0)
.then((int? value) {
_counter = value ?? 0;
_counter++;
});
await HomeWidget.saveWidgetData<String>('_prdcdSell', prdcdSell);
await HomeWidget.saveWidgetData<String>('_prdcdBuy', prdcdBuy);
await HomeWidget.saveWidgetData<int>('_counter', _counter);
await HomeWidget.updateWidget(name: 'AppWidgetProviderLarge', iOSName: 'AppWidgetProviderLarge');
}
else if (uri?.host == 'updatecountermenu1') {
print("============= menu1");
// 새로운 URL 설정
controller.loadRequest(Uri.parse("http://ar.com/?110641"));
}
else if (uri?.host == 'updatecountermenu2') {
print("============= menu2");
controller.loadRequest(Uri.parse("http://ar.com/?110630"));
}
else if (uri?.host == 'updatecountermenu3') {
print("============= menu3");
controller.loadRequest(Uri.parse("http://ar.com/?110624"));
}
}
WebViewControllerManager webViewControllerManager = WebViewControllerManager();
: WebViewControllerManager 클래스의 인스턴스를 생성합니다.
이 클래스는 웹 뷰 컨트롤러를 관리하는데 사용됩니다.
print(">>>>>backgroundCallback");
print(uri?.host);
: 콜백이 실행되었음을 알리는 디버깅 출력과 함께, 전달된 Uri의 호스트를 출력합니다.
if (uri?.host == 'updatecounter') { ... }
: URI의 호스트가 'updatecounter'인 경우, 특정 작업을 수행합니다.
주로 fetchPrdCd 함수를 호출하여 데이터를 가져오고, 해당 데이터를 가공하여 홈 위젯에 업데이트하고자 하는 것입니다.
else if (uri?.host == 'updatecountermenu1') { ... }
: URI의 호스트가 'updatecountermenu1'인 경우, 특정 URL로 웹 뷰의 페이지를 로드하도록 합니다.
else if (uri?.host == 'updatecountermenu2') { ... }, else if (uri?.host == 'updatecountermenu3') { ... }
: 'updatecountermenu2' 및 'updatecountermenu3'에 대해서도 각각 다른 URL을 로드하도록 설정되어 있습니다.
이러한 방식으로 homeWidgetBackgroundCallback 함수는 URI의 호스트에 따라 다양한 작업을 수행하고, 웹 뷰의 내용을 업데이트하거나 특정 URL로 이동하는 등의 동작을 수행합니다.
'프로그래밍 > flutter' 카테고리의 다른 글
[flutter] iOS 빌드시 오류 Error (Xcode): Cycle inside Runner (0) | 2024.01.15 |
---|---|
[flutter] home_widget 0.4.0 이용하여 iOS 홈위젯 생성 방법 (1) | 2023.12.07 |
[flutter] Flutter에서 홈 화면 앱 위젯 2개 만드는 방법 (안드로이드) (0) | 2023.10.25 |
[flutter] 인터넷에서 데이터 가져오기 GET/POST (fetch) (0) | 2023.10.25 |
[flutter] Flutter에서 홈 화면 앱 위젯을 만드는 방법 1 (안드로이드) (1) | 2023.10.24 |