如何解决如何在 android:updatePeriodMillis="0" 时从 Flutter 更新 Android 小部件?
我是新来的。我正在慢慢掌握 Flutter 的窍门,但我完全是 Kotlin/Java 集成方面的新手。我正在尝试制作一个 Flutter 应用程序,其中一些数据在 Flutter istelf 中不定期更新,然后显示在主屏幕小部件上。
我不想定期更新 Android 小部件,因为每天可能不会有任何更改,但只是偶尔更新。在寻找实际制作小部件的方法时,我发现了这个 really helpful answer from bnxm 和一个很好的 implementation on Github from timobaehr。
以此为例,如果我想在应用程序中的按钮被按下(或后台服务运行)时更新主屏幕小部件上显示的“结果”,而不是在一组间隔? Timobaehr 在他的演示中使用了默认的 Flutter 计数应用程序,那么我可以对按下按钮时运行的这段代码做什么?
这里是 main.dart 中的更新函数:
from sklearn.base import BaseEstimator,TransformerMixin
class data_cleaner(BaseEstimator,TransformerMixin):
def __init__(self,cat_data,num_data):
self.cat_data = cat_data
self.num_data = num_data
def process_data(self,num_data):
cat_data = []
num_data = []
for i,c in enumerate(X.dtypes):
if c == object:
cat_data.append(X.iloc[:,i])
else :
num_data.append(X.iloc[:,i]
cat_data = pd.DataFrame(cat_data).transpose()
num_data = pd.DataFrame(num_data).transpose()
#filling the missing categorical data
cat_data = cat_data.apply(lambda value:value.fillna(value.value_counts().index[0]))
#mapping the data on the loan_status
target = {'Y': '1','N': '0'}
loan_status = cat_data['Loan_Status']
#dropping the loan_status from cat_data
cat_data.drop('Loan_Status',inplace=True,axis=1)
#mapping loan_status wrt target
loan_status = loan_status.map(target)
#changing the cat_data into numerical values
from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
for value in cat_data:
cat_data[value] = encoder.fit_transform(cat_data[value])
# Numerical data
# Fill every missing value with their prevIoUs value in the same column.
num_data.fillna(method='bfill',inplace=True)
#joining the cat_data and num_data
def transform(self,X,y=None):
X = pd.concat([cat_data,num_data,loan_status],axis=1)
def fit(self,*_):
return self
下面是代码中更新值的地方,基于默认的 Flutter 启动应用程序。我还将 void onWidgetUpdate() {
WidgetsFlutterBinding.ensureInitialized();
const MethodChannel channel = MethodChannel('com.example.app/widget');
channel.setMethodCallHandler(
(call) async {
final id = call.arguments;
print('on Dart ${call.method}!');
return {
'id': id,// Some data of type int - this is what I want to update
'value': counter,};
},);
}
移到了 dart 文件的顶部,以便它可以随处使用。
int counter = 0;
是在此处添加一些东西那么简单,还是需要在其他地方更改 Kotlin 代码?感谢您的帮助。
编辑:我应该说,从 increment 函数调用 onWidgetUpdate() 根本不会改变小部件,所以我认为一定有其他事情需要发生,也许在后台 Kotlin 代码中或使用 MethodChannels,我不熟悉。
如果你想自己运行它来测试,我从 timobaehr's Github project 克隆,只是将 'value' 更改为来自 'counter' 并且是 int 而不是 double。
解决方法
好吧,我想我明白了。把它贴在这里,以防它对其他人有帮助。
正如我所怀疑的那样,在 Kotlin 中必须改变一些东西。所以对我来说有点额外的学习!如果您跟随 timobaehr's project on Github,您可以尝试进行如下更改:
我编写了一个名为“updateFromFlutter”的新方法并将其添加到 MainActivity.kt:
when (call.method) {
"initialize" -> {
if (call.arguments == null) return
WidgetHelper.setHandle(this,call.arguments as Long)
}
"updateFromFlutter" -> {
val views = RemoteViews(context.packageName,R.layout.widget_layout).apply {
setTextViewText(R.id.text,call.argument("text"))
}
val id: Int = call.argument("id")!!
val manager = AppWidgetManager.getInstance(this)
manager.updateAppWidget(id,views)
}
}
记得在 MainActivity.kt 的顶部导入这些:
import android.widget.RemoteViews
import com.example.flutter_app_android_widget.R
import android.appwidget.AppWidgetManager
并在更新计数器值后从 main.dart 调用它:
const MethodChannel platform = MethodChannel('com.example.flutter_app_android_widget/widget');
platform.invokeMethod("updateFromFlutter",{
"text": counter.toString(),"id": //get the integer from Shared Preferences - up to you how you do this
//or feel free to suggest a better way of keeping track of the widget id
});
然后,您应该可以通过按下 Flutter 应用中的按钮来按需更新主屏幕小部件。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。