我应该在哪里调用集合中的 API(可配置)android 应用小部件
Where should I call API in collection (configurable) android App widget
我有一个 configurable/reconfigurable 集合小部件,我必须调用一个 API 来获取列表,所以我可以在哪里调用 API(我需要更改 API配置更改时)。
我正在尝试在工厂 class.
的 onCreate 中调用 post-API
我有 2 post-APIs,两个 APIs return 相同类型的 class 所以使用相同的列表和相同的设计当我从配置 activity 更改配置选项时加载数据的文件我想再次调用选定的 API。但是没用
@AndroidEntryPoint
class MyWidgetServices : RemoteViewsService() {
override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {
return ListViewFactory(this.applicationContext, intent)
}
@Inject
lateinit var repo: WidgetRepo
@Inject
lateinit var prefs: PrefUtil
inner class ListViewFactory(context: Context, intent: Intent) :
RemoteViewsFactory {
private val mContext: Context = context
private val mAppWidgetId: Int = intent.getIntExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID
)
private var list: MutableList<PendingResModel> = mutableListOf()
private var count: Long = 0
val appWidgetManager = AppWidgetManager.getInstance(mContext)
override
fun onCreate() {
// Since we reload the cursor in onDataSetChanged() which gets called immediately after
// onCreate(), we do nothing here.
this.hashCode().toString().logE()
if (prefs.showInProgress) {
CoroutineScope(Dispatchers.IO).launch {
repo.inProgress()?.let {
it.data?.let {
list.addAll(it)
appWidgetManager.notifyAppWidgetViewDataChanged(
mAppWidgetId,
R.id.lv_order
)
}
it.meta?.let { meta ->
count = meta.totalDataCount ?: 0
}
}
}
} else {
CoroutineScope(Dispatchers.IO).launch {
repo.toConfirm()?.let {
it.data?.let {
list.addAll(it)
appWidgetManager.notifyAppWidgetViewDataChanged(
mAppWidgetId,
R.id.lv_order
)
}
it.meta?.let { meta ->
count = meta.totalDataCount ?: 0
}
}
}
}
}
override fun onDestroy() {
list.clear()
}
override fun getCount(): Int {
return list.size
}
@SuppressLint("RemoteViewLayout")
override fun getViewAt(position: Int): RemoteViews {
val rv = RemoteViews(mContext.packageName, Layouts.row_widget)
val views = RemoteViews(mContext.packageName, R.layout.layout_widget)
views.setTextViewText(R.id.tv_count, count.toString())
Glide.with(mContext)
.asBitmap()
.load(list[position].user.profile)
.apply(RequestOptions.circleCropTransform())
.into(object : CustomTarget<Bitmap>() {
override fun onResourceReady(
resource: Bitmap,
transition: Transition<in Bitmap>?
) {
rv.setImageViewBitmap(R.id.iv_widget_profile, resource)
}
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
}
override fun onLoadCleared(placeHolder: Drawable?) {
}
})
rv.setTextViewText(R.id.tv_id, list[position].id)
rv.setTextViewText(R.id.tv_name, list[position].user.name)
return rv
}
override fun getLoadingView(): RemoteViews? {
// We aren't going to return a default loading view in this sample
return null
}
override fun getViewTypeCount(): Int {
// Technically, we have two types of views (the dark and light background views)
return 1
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun hasStableIds(): Boolean {
return true
}
override fun onDataSetChanged() {
}
}
}
这是在 widgetprovider 的 onUpdate 中调用的 updateAppWidget 函数 class
internal fun updateAppWidget(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: Int,
text: String = "In progress"
) {
val serviceIntent = Intent(context, MyWidgetServices::class.java)
serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
serviceIntent.data = Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME))
val views = RemoteViews(context.packageName, R.layout.layout_widget)
views.setTextViewText(R.id.tv_title, text)
views.setRemoteAdapter(appWidgetId, R.id.lv_widget, serviceIntent)
views.setEmptyView(R.id.lv_widget, R.id.empty_view)
appWidgetManager.updateAppWidget(appWidgetId, views)
}
这是从配置 activity
更改配置的代码
override fun onClick(v: View) {
super.onClick(v)
when (v) {
binding.tvProgress -> {
prefs.showInProgress = true
updateAppWidget(
this@ConfigureActivity,
appWidgetManager,
appWidgetId,
text = "In Progress"
)
// Make sure we pass back the original appWidgetId
val resultValue = Intent()
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
appWidgetId)
setResult(RESULT_OK, resultValue)
finish()
}
binding.tvConfirm -> {
prefs.showInProgress = false
updateAppWidget(this@ConfigureActivity,
appWidgetManager, appWidgetId, text = "To Confirm")
val resultValue = Intent()
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
setResult(RESULT_OK, resultValue)
finish()
}
}}
我找到了一个解决方案,我在 onDataSetChanged 而不是 onCreate 中调用 API,并采用全局布尔变量来管理调用 API
override fun onDataSetChanged() {
if (AppConstants.Misc.isRefreshWidget) {
list.clear()
if (prefs.showInProgress) {
CoroutineScope(Dispatchers.IO).launch {
repo.inProgress()?.let {
it.data?.let {
list.addAll(it)
appWidgetManager.notifyAppWidgetViewDataChanged(
mAppWidgetId,
R.id.lv_order
)
}
it.meta?.let { meta ->
count = meta.totalDataCount ?: 0
}
AppConstants.Misc.isRefreshWidget = false
}
}
} else {
CoroutineScope(Dispatchers.IO).launch {
repo.toConfirm()?.let {
it.data?.let {
list.addAll(it)
appWidgetManager.notifyAppWidgetViewDataChanged(
mAppWidgetId,
R.id.lv_order
)
}
it.meta?.let { meta ->
count = meta.totalDataCount ?: 0
}
AppConstants.Misc.isRefreshWidget = false
}
}
}
}
}
并在单击配置 activity 的按钮时或任何您想调用 api
时更改此全局变量 (isRefreshWidget)
我有一个 configurable/reconfigurable 集合小部件,我必须调用一个 API 来获取列表,所以我可以在哪里调用 API(我需要更改 API配置更改时)。 我正在尝试在工厂 class.
的 onCreate 中调用 post-API我有 2 post-APIs,两个 APIs return 相同类型的 class 所以使用相同的列表和相同的设计当我从配置 activity 更改配置选项时加载数据的文件我想再次调用选定的 API。但是没用
@AndroidEntryPoint
class MyWidgetServices : RemoteViewsService() {
override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {
return ListViewFactory(this.applicationContext, intent)
}
@Inject
lateinit var repo: WidgetRepo
@Inject
lateinit var prefs: PrefUtil
inner class ListViewFactory(context: Context, intent: Intent) :
RemoteViewsFactory {
private val mContext: Context = context
private val mAppWidgetId: Int = intent.getIntExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID
)
private var list: MutableList<PendingResModel> = mutableListOf()
private var count: Long = 0
val appWidgetManager = AppWidgetManager.getInstance(mContext)
override
fun onCreate() {
// Since we reload the cursor in onDataSetChanged() which gets called immediately after
// onCreate(), we do nothing here.
this.hashCode().toString().logE()
if (prefs.showInProgress) {
CoroutineScope(Dispatchers.IO).launch {
repo.inProgress()?.let {
it.data?.let {
list.addAll(it)
appWidgetManager.notifyAppWidgetViewDataChanged(
mAppWidgetId,
R.id.lv_order
)
}
it.meta?.let { meta ->
count = meta.totalDataCount ?: 0
}
}
}
} else {
CoroutineScope(Dispatchers.IO).launch {
repo.toConfirm()?.let {
it.data?.let {
list.addAll(it)
appWidgetManager.notifyAppWidgetViewDataChanged(
mAppWidgetId,
R.id.lv_order
)
}
it.meta?.let { meta ->
count = meta.totalDataCount ?: 0
}
}
}
}
}
override fun onDestroy() {
list.clear()
}
override fun getCount(): Int {
return list.size
}
@SuppressLint("RemoteViewLayout")
override fun getViewAt(position: Int): RemoteViews {
val rv = RemoteViews(mContext.packageName, Layouts.row_widget)
val views = RemoteViews(mContext.packageName, R.layout.layout_widget)
views.setTextViewText(R.id.tv_count, count.toString())
Glide.with(mContext)
.asBitmap()
.load(list[position].user.profile)
.apply(RequestOptions.circleCropTransform())
.into(object : CustomTarget<Bitmap>() {
override fun onResourceReady(
resource: Bitmap,
transition: Transition<in Bitmap>?
) {
rv.setImageViewBitmap(R.id.iv_widget_profile, resource)
}
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
}
override fun onLoadCleared(placeHolder: Drawable?) {
}
})
rv.setTextViewText(R.id.tv_id, list[position].id)
rv.setTextViewText(R.id.tv_name, list[position].user.name)
return rv
}
override fun getLoadingView(): RemoteViews? {
// We aren't going to return a default loading view in this sample
return null
}
override fun getViewTypeCount(): Int {
// Technically, we have two types of views (the dark and light background views)
return 1
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun hasStableIds(): Boolean {
return true
}
override fun onDataSetChanged() {
}
}
}
这是在 widgetprovider 的 onUpdate 中调用的 updateAppWidget 函数 class
internal fun updateAppWidget(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: Int,
text: String = "In progress"
) {
val serviceIntent = Intent(context, MyWidgetServices::class.java)
serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
serviceIntent.data = Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME))
val views = RemoteViews(context.packageName, R.layout.layout_widget)
views.setTextViewText(R.id.tv_title, text)
views.setRemoteAdapter(appWidgetId, R.id.lv_widget, serviceIntent)
views.setEmptyView(R.id.lv_widget, R.id.empty_view)
appWidgetManager.updateAppWidget(appWidgetId, views)
}
这是从配置 activity
更改配置的代码override fun onClick(v: View) {
super.onClick(v)
when (v) {
binding.tvProgress -> {
prefs.showInProgress = true
updateAppWidget(
this@ConfigureActivity,
appWidgetManager,
appWidgetId,
text = "In Progress"
)
// Make sure we pass back the original appWidgetId
val resultValue = Intent()
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
appWidgetId)
setResult(RESULT_OK, resultValue)
finish()
}
binding.tvConfirm -> {
prefs.showInProgress = false
updateAppWidget(this@ConfigureActivity,
appWidgetManager, appWidgetId, text = "To Confirm")
val resultValue = Intent()
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
setResult(RESULT_OK, resultValue)
finish()
}
}}
我找到了一个解决方案,我在 onDataSetChanged 而不是 onCreate 中调用 API,并采用全局布尔变量来管理调用 API
override fun onDataSetChanged() {
if (AppConstants.Misc.isRefreshWidget) {
list.clear()
if (prefs.showInProgress) {
CoroutineScope(Dispatchers.IO).launch {
repo.inProgress()?.let {
it.data?.let {
list.addAll(it)
appWidgetManager.notifyAppWidgetViewDataChanged(
mAppWidgetId,
R.id.lv_order
)
}
it.meta?.let { meta ->
count = meta.totalDataCount ?: 0
}
AppConstants.Misc.isRefreshWidget = false
}
}
} else {
CoroutineScope(Dispatchers.IO).launch {
repo.toConfirm()?.let {
it.data?.let {
list.addAll(it)
appWidgetManager.notifyAppWidgetViewDataChanged(
mAppWidgetId,
R.id.lv_order
)
}
it.meta?.let { meta ->
count = meta.totalDataCount ?: 0
}
AppConstants.Misc.isRefreshWidget = false
}
}
}
}
}
并在单击配置 activity 的按钮时或任何您想调用 api
时更改此全局变量 (isRefreshWidget)