如何解决AppWidget 中的 ListView 不显示来自 firebase 的数据
我有一个带有 ListView 的 AppWidget。当使用一个虚拟的arrayList exampleData
时,ListView 会显示它的数据。但是当我尝试从 firebase RD 检索数据到 todayList
时,我的 ListView 不显示数据。当我检查 todayList
的大小时,它不是 0,这意味着 todayList
成功检索到数据。你能帮我吗?
ListView 使用 todayList
ListView 使用虚拟 exampleData
这是我的 ExampleWidgetItemFactory
课:
internal class ExampleWidgetItemFactory(private val context: Context,intent: Intent) :
RemoteViewsFactory {
private lateinit var database: DatabaseReference
private lateinit var preferences: Preferences
private val mGoogleSignInClient: GoogleSignInClient? = null
private lateinit var auth: FirebaseAuth
private lateinit var user: FirebaseUser
private lateinit var userId: String
private lateinit var userName:String
private var todayList: ArrayList<Task> = arraylistof()
private val appWidgetId: Int
private val exampleData = arraylistof(
"one","two","three","four","five","six","seven","eight","nine","ten"
)
override fun onCreate() {
//connect to data source
//Initialize
database = FirebaseDatabase.getInstance().reference
auth = Firebase.auth
//User
user = auth.currentUser
userId = user.uid.toString()
//Calendar
val calendar = Calendar.getInstance()
val year = calendar.get(Calendar.YEAR)
val month = calendar.get(Calendar.MONTH) + 1
val day = calendar.get(Calendar.DAY_OF_MONTH)
val date = String.format("%02d/%02d/%04d",day,month,year)
database
.child("users")
.child(userId)
.child("tasks")
.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
//Hapus data dalam arraylist agar tidak jadi penumpukan data
todayList.clear()
//Ambil semua child dalam goal dan masukan ke items
var items = snapshot.children
//Lakukan iterasi pada setiap item lalu buat class dan tambahkan ke list
items.forEach {
var task = it.getValue(Task::class.java)
todayList.add(task!!)
}
Log.v("gal",todayList.size.toString())
Log.v("gal",todayList[0].title.toString())
SystemClock.sleep(3000)
}
override fun onCancelled(error: DatabaseError) {
Todo("Not yet implemented")
}
})
}
override fun onDataSetChanged() {
}
override fun onDestroy() {
//close data source
}
override fun getCount(): Int {
return exampleData.size
}
override fun getViewAt(position: Int): RemoteViews {
val views = RemoteViews(context.packageName,R.layout.example_widget_item)
views.setTextViewText(R.id.example_widget_item_text,todayList[position].title)
val fillIntent = Intent()
fillIntent.putExtra(ExampleWidgetProvider().EXTRA_ITEM_POSITION,position)
views.setonClickFillInIntent(R.id.example_widget_item_text,fillIntent)
SystemClock.sleep(500)
return views
}
override fun getLoadingView(): RemoteViews? {
return null
}
override fun getViewTypeCount(): Int {
return 1
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun hasstableIds(): Boolean {
return true
}
init {
appWidgetId = intent.getIntExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID,AppWidgetManager.INVALID_APPWIDGET_ID
)
}
}
**ExampleWidgetProvider **
class ExampleWidgetProvider : appwidgetprovider() {
val ACTION_TOAST = "actionToast"
val EXTRA_ITEM_POSITION = "extraItemPosition"
override fun onUpdate(
context: Context,appWidgetManager: AppWidgetManager,appWidgetIds: IntArray
) {
super.onUpdate(context,appWidgetManager,appWidgetIds)
for (appWidgetId in appWidgetIds) {
val buttonIntent = Intent(context,HomeActivity::class.java)
val buttonPendingIntent = PendingIntent.getActivity(
context,buttonIntent,0
)
val prefs = context.getSharedPreferences(
ExampleAppWidgetConfig().SHARED_PREFS,Context.MODE_PRIVATE
)
val buttonText = prefs.getString(
ExampleAppWidgetConfig().KEY_BUTTON_TEXT + appWidgetId,"Press me"
)
val serviceIntent = Intent(context,ExampleWidgetService::class.java)
serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetId)
serviceIntent.data = Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME))
val clickIntent =
Intent(
context,ExampleWidgetProvider::class.java
)
clickIntent.action = ACTION_TOAST
val clickPendingIntent = PendingIntent.getbroadcast(
context,clickIntent,0
)
val views = RemoteViews(context.packageName,R.layout.example_widget)
views.setRemoteAdapter(R.id.example_widget_stack_view,serviceIntent)
views.setEmptyView(R.id.example_widget_stack_view,R.id.example_widget_empty_view)
views.setPendingIntentTemplate(R.id.example_widget_stack_view,clickPendingIntent)
val appWidgetoptions = appWidgetManager.getAppWidgetoptions(appWidgetId)
resizeWidget(appWidgetoptions,views)
appWidgetManager.updateAppWidget(appWidgetId,views)
}
}
override fun onAppWidgetoptionsChanged(
context: Context,appWidgetId: Int,newOptions: Bundle
) {
val views = RemoteViews(context.packageName,R.layout.example_widget)
resizeWidget(newOptions,views)
appWidgetManager.updateAppWidget(appWidgetId,views)
}
private fun resizeWidget(appWidgetoptions: Bundle,views: RemoteViews) {
val minWidth = appWidgetoptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH)
val maxWidth = appWidgetoptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH)
val minHeight = appWidgetoptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT)
val maxHeight = appWidgetoptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT)
}
override fun onDeleted(context: Context?,appWidgetIds: IntArray?) {
Toast.makeText(context,"onDeleted",Toast.LENGTH_SHORT).show()
}
override fun onEnabled(context: Context?) {
Toast.makeText(context,"onEnabled",Toast.LENGTH_SHORT).show()
}
override fun ondisabled(context: Context?) {
Toast.makeText(context,"ondisabled",Toast.LENGTH_SHORT).show()
}
override fun onReceive(context: Context?,intent: Intent) {
if (ACTION_TOAST == intent.action) {
val clickedPosition = intent.getIntExtra(EXTRA_ITEM_POSITION,0)
Toast.makeText(context,"Clicked position: $clickedPosition",Toast.LENGTH_SHORT).show()
}
super.onReceive(context,intent)
}
}
**When I try getting size and element in `todayList`:**
Log.v("gal",todayList.size.toString())
Log.v("gal",todayList[0].title.toString())
**The logcat result:**
2021-04-15 11:57:41.554 8756-8756/com.giftech.taskmastertest V/gal: 4
2021-04-15 11:57:41.554 8756-8756/com.giftech.taskmastertest V/gal: vv
解决方法
为什么您认为您的项目应该显示在列表中?您正在从数据库中获取项目,在 todayList
中完成 forEach
和...仅此而已。你永远不会在任何地方返回这个 ArrayList
,尤其是它没有设置到某个附加到 ListView
的适配器。看起来您已经剥离了很多代码,发布了整个课程 - 我敢打赌您的问题与异步数据库读取有关,onDataChange
的调用晚于绘图适配器/ListView
,在此方法结束时,您应该可能调用 notifyDataSetChanged()
编辑:在发布整个类之后现在一切都清楚了:RemoteViewsFactory
正在根据传递给此类的数据生成视图,与适配器类似的工作。这不是从网络获取数据的时刻,因为这是异步操作,创建 RemoteViewsFactory
是一种同步方式,用于获取现有项目的视图。您应该在 extends AppWidgetProvider
类中(在 onUpdate()
方法中)获取数据,可能需要启动一些 Service
以进行异步数据获取并在存储整个数组刷新小部件 GUI 之后
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。