天天看點

Android_Widget中Listview的用法

環境:win10

編譯軟體 : AS

這裡隻講listview的基礎用法,建議先查詢widget相關知識後再來

先利用AS建立一個ListWidget,系統會自動幫你生成一個AppWidgetProvider,以及布局檔案 /xml中的list_widget_info.xml和/layout中的list_widget.xml這裡就不具體介紹了。開始我們的小例子叭

list_widget.xml中添加listview控件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#603BA3"
    android:padding="@dimen/widget_margin"
    android:orientation="vertical"
    android:theme="@style/ThemeOverlay.WidgetListTest.AppWidgetContainer">
  <TextView
        android:id="@+id/testText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="20sp"
        android:text="課表"/>
<ListView
    android:id="@+id/listTest"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

</LinearLayout>
           

建立listview的子view :list_widget_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="horizontal"
    android:layout_margin="5dp"

    >
<LinearLayout
    android:layout_width="0dp"
    android:layout_weight="2"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <TextView
        android:id="@+id/class_mc"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_marginBottom="5dp"
        android:textSize="18dp"
        />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">
<ImageView
    android:layout_width="15dp"
    android:layout_height="15dp"
    android:src="@drawable/teacher"
    android:layout_marginRight="5dp"/>

        <TextView
            android:id="@+id/class_js"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="15dp"
            android:text="***"/>
        <ImageView
            android:layout_width="15dp"
            android:layout_height="15dp"
            android:src="@drawable/place"
            android:layout_marginRight="5dp"/>
        <TextView
            android:id="@+id/class_dd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="10dp"
            android:text="***512"/>

    </LinearLayout>
</LinearLayout>
    <TextView
        android:id="@+id/class_sj"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent"
        android:text="17:00-18:40"
        android:textColor="@color/cardview_light_background"
        android:gravity="center"
   />
</LinearLayout>
           

建立一個list的服務擴充卡ListviewService

class ListViewService : RemoteViewsService() {
    override fun onGetViewFactory(intent: Intent?): RemoteViewsFactory? {
        return ListRemoteViewsFactory(this.applicationContext, intent)
    }
private class ListRemoteViewsFactory (context: Context, intent: Intent?): RemoteViewsFactory{
    private var mContext: Context? = context
    var appWidgetId = Integer.valueOf(intent?.getData()?.getSchemeSpecificPart())- ListWidget().m //得到原來的widgetId

    private val mList = ArrayList<String>()


    override fun onCreate() {
        mList.add(Date().toString())//擷取系統的時間 相當于檢測該擴充卡是否正常運作
        mList.add("計算機作業系統")
        mList.add("計算機作業系統")
        mList.add("計算機作業系統")
       mList.add("計算機作業系統")


    }
    override fun onDataSetChanged() {
        mList.clear()
        mList.add(Date().toString())//擷取系統的時間 相當于檢測該擴充卡是否正常運作
        mList.add("計算機作業系統")
        mList.add("計算機作業系統")
        mList.add("計算機作業系統")
        mList.add("計算機作業系統")
    }
    override fun onDestroy() {
        mList.clear()
    }

    override fun getCount(): Int {
        return mList.size
    }

    override fun getViewAt(position: Int): RemoteViews? {
        val views = RemoteViews(mContext!!.packageName, R.layout.list_widget_item)
views.setTextViewText(R.id.class_mc,mList[position])
        Log.d("momo",mList[position])
        return views
    }

    /* 在更新界面的時候如果耗時就會顯示 正在加載... 的預設字樣,但是你可以更改這個界面
         * 如果傳回null 顯示預設界面
         * 否則 加載自定義的,傳回RemoteViews
         */
    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 false
    }
}



}
           
  • RemoteViewsService : 是一個遠端的服務擴充卡 可以請求RemoteViews,管理RemoteViews的服務.
  • RemoteViewsFactory : 提供了RemoteViewsFactory用于填充遠端集合視圖。
  • onDataSetChanged():是用于更新listview中的資料的
  • getViewAt(position: Int):用于填充子view

在AppWidgetProvider的update()中設定adapter

class ListWidget : AppWidgetProvider() {
    var m=(0..1000).random() //随機數
    override fun onUpdate(
        context: Context,
        appWidgetManager: AppWidgetManager,
        appWidgetIds: IntArray
    ) {
        for (i in appWidgetIds){


        // There may be multiple widgets active, so update all of them
        val views = RemoteViews(context.packageName, R.layout.list_widget)
        views.setTextViewText(R.id.testText, "課表")
        val adapter = Intent(context, ListViewService::class.java)//建立擴充卡
        adapter.setData(Uri.fromParts("content",i.toString()+m.toString(),null))//加上一個随機數讓RemoteViewsFactory認為是一個新的widgetid而重新建立新工廠RemoteViewsFactory
        views.setRemoteAdapter(R.id.listTest, adapter) //為list綁定adapter
        views.setEmptyView(R.id.listTest,android.R.id.empty)
        val mComponentName = ComponentName(context, ListWidget::class.java)
        appWidgetManager.updateAppWidget(mComponentName, views)
        }
    }

    override fun onEnabled(context: Context) {
        // Enter relevant functionality for when the first widget is created
    }

    override fun onDisabled(context: Context) {
        // Enter relevant functionality for when the last widget is disabled
    }
}

internal fun updateAppWidget(
    context: Context,
    appWidgetManager: AppWidgetManager,
    appWidgetId: Int
) {
    val widgetText = context.getString(R.string.appwidget_text)
    // Construct the RemoteViews object
    val views = RemoteViews(context.packageName, R.layout.list_widget)


    // Instruct the widget manager to update the widget
    appWidgetManager.updateAppWidget(appWidgetId, views)
}
           

為什麼需要重新建立工廠: 是因為遠端服務擴充卡會緩存所有widgetid的工廠,是以當你需要更新listview内容而發送請求時,服務擴充卡并不會為你重新建立工廠進而更新内容。這裡還有一種方案:就是調用notifyAppWidgetViewDataChanged()方法,但是有時會沒有效果,我也不知道為什麼。

m是一個公開的随機數

效果圖(内容有删減)大概差不多,懶得再運作一次了

Android_Widget中Listview的用法