将headerView添加到widget上的listView中调整大小android

时间:2016-07-14 14:29:17

标签: android android-layout listview android-widget

我想使用ListView实现窗口小部件,当用户调整窗口小部件的大小时,我想在列表中添加标头。我希望实现这样的目标:

  1. 这是初始WidgetViewexpected result

  2. 我想在用户调整窗口小部件时实现: expected result on resizing

  3. 以下是布局的代码:

    这是行项目(list_row.xml)的布局:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:background="@android:color/black" >
        <TextView
            android:id="@+id/heading"
            android:layout_width="match_parent"
            android:layout_height="fill_parent"
            android:layout_alignParentLeft="true"
            android:textColor="@color/white"
            android:singleLine="true"
            android:textSize="14sp"
            android:textStyle="bold"
            android:text="Heading"/>
        <TextView
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="fill_parent"
            android:layout_alignParentLeft="true"
            android:layout_below="@id/heading"
            android:layout_marginTop="5dip"
            android:textSize="14sp"
            android:text="Content"/>
    </RelativeLayout>
    

    以下是窗口小部件初始布局的代码:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:background="@android:color/black" >
        <ListView
            android:id="@+id/listViewWidget"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            />
    </LinearLayout>
    

    以下是标题布局的代码:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/lay2">
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:text="Header List View"
        android:textColor="@color/pink"
        android:textAppearance="?android:attr/textAppearanceLarge"
        />
    </RelativeLayout>
    

    以下是窗口小部件的元数据代码:

    <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
        android:initialLayout="@layout/widget_layout"
        android:minHeight="40dip"
        android:minWidth="40dip"
        android:resizeMode="vertical|horizontal"
        android:updatePeriodMillis="1800000"
        >
    </appwidget-provider>
    

    以下是小部件提供程序的代码:

    public class WidgetProvider extends AppWidgetProvider {
    
    @Override
    public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) {
        //super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
    
        // See the dimensions and
        Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
    
        // Get min width and height.
        int minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
        int minHeight = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT);
    
        // Obtain appropriate widget and update it.
        appWidgetManager.updateAppWidget(appWidgetId, getRemoteViews(context, minWidth, minHeight));
        super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
    }
    
    private RemoteViews getRemoteViews(Context context, int minWidth, int minHeight) {
        // First find out rows and columns based on width provided.
        int rows = getCellsForSize(minHeight);
        int columns = getCellsForSize(minWidth);
        // Now you changing layout base on you column count
        // In this code from 1 column to 4
        // you can make code for more columns on your own.
        switch (rows) {
            case 1:  return new RemoteViews(context.getPackageName(), R.layout.widget_layout);
            case 2:
                //return new RemoteViews(context.getPackageName(), R.layout.activity_layout_widget_4column);
                RemoteViews update2 = new RemoteViews(context.getPackageName(), R.layout.text_view_layout);
                //for(int i = 0; i < 3; i++) {
                RemoteViews textView = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
                    //textView.setTextViewText(R.id.textView1, "TextView number " + String.valueOf(i));
                update2.addView(R.id.lay2, textView);
                //}
    
                return update2;
            case 3:
                //return new RemoteViews(context.getPackageName(), R.layout.activity_layout_widget_4column);
                RemoteViews update3 = new RemoteViews(context.getPackageName(), R.layout.text_view_layout);
                //for(int i = 0; i < 3; i++) {
                RemoteViews textView1 = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
                //textView.setTextViewText(R.id.textView1, "TextView number " + String.valueOf(i));
                update3.addView(R.id.lay2, textView1);
                //}
    
                return update3;
            case 4:
                //return new RemoteViews(context.getPackageName(), R.layout.activity_layout_widget_4column);
                RemoteViews update4 = new RemoteViews(context.getPackageName(), R.layout.text_view_layout);
                //for(int i = 0; i < 3; i++) {
                RemoteViews textView3 = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
                //textView.setTextViewText(R.id.textView1, "TextView number " + String.valueOf(i));
                update4.addView(R.id.lay2, textView3);
                //}
    
                return update4;
    
            default: return null;
        }
    }
    
    private static int getCellsForSize(int size) {
        int n = 2;
        while (70 * n - 30 < size) {
            ++n;
        }
        return n - 1;
    }
    
    
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        final int N = appWidgetIds.length;
        for (int i = 0; i < N; ++i) {
            RemoteViews remoteViews = updateWidgetListView(context,
                    appWidgetIds[i]);
            appWidgetManager.updateAppWidget(appWidgetIds[i],
                    remoteViews);
        }
        super.onUpdate(context, appWidgetManager, appWidgetIds);
    
    }
    
    private RemoteViews updateWidgetListView(Context context,
                                             int appWidgetId) {
    
        //which layout to show on widget
        RemoteViews remoteViews = new RemoteViews(
                context.getPackageName(),R.layout.widget_layout);
    
        //RemoteViews Service needed to provide adapter for ListView
        Intent svcIntent = new Intent(context, WidgetService.class);
        //passing app widget id to that RemoteViews Service
        svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        //setting a unique Uri to the intent
        //don't know its purpose to me right now
        svcIntent.setData(Uri.parse(
                svcIntent.toUri(Intent.URI_INTENT_SCHEME)));
        //setting adapter to listview of the widget
        remoteViews.setRemoteAdapter(appWidgetId, R.id.listViewWidget,
                svcIntent);
        return remoteViews;
    }
    }
    

    以下是WidgetService的代码:

    public class WidgetService extends RemoteViewsService{
    
        @Override
        public RemoteViewsFactory onGetViewFactory(Intent intent) {
            int appWidgetId = intent.getIntExtra(
                AppWidgetManager.EXTRA_APPWIDGET_ID,
                AppWidgetManager.INVALID_APPWIDGET_ID);
            return (new ListProvider(this.getApplicationContext(), intent));
        }
    }
    

    以下是ListProvider的代码:

    public class ListProvider implements RemoteViewsService.RemoteViewsFactory{
        private ArrayList listItemList = new ArrayList();
        private Context context = null;
        private int appWidgetId;
    
        public ListProvider(Context context, Intent intent) {
            this.context = context;
            appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                AppWidgetManager.INVALID_APPWIDGET_ID);
            populateListItem();
        }
    
        private void populateListItem() {
            for (int i = 0; i < 6; i++) {
                ListItem listItem = new ListItem();
                listItem.heading = "Heading" + i;
                listItem.content = i + " This is the content of the app widget listview.Nice content though";
                listItemList.add(listItem);
            }
        }
    
        @Override
        public int getCount() {
            return listItemList.size();
        }
    
        @Override
        public void onCreate() {
        }
    
        @Override
        public void onDataSetChanged() {
        }
    
        @Override
        public void onDestroy() {
        }
    
        @Override
        public RemoteViews getLoadingView() {
            return null;
        }
    
        @Override
        public int getViewTypeCount() {
            return 1;
        }
    
        @Override
        public boolean hasStableIds() {
            return false;
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        /*
        *Similar to getView of Adapter where instead of View
        *we return RemoteViews
        *
        */
        @Override
        public RemoteViews getViewAt(int position) {
            final RemoteViews remoteView = new RemoteViews(
                context.getPackageName(), R.layout.list_row);
            ListItem listItem = (ListItem)listItemList.get(position);
            remoteView.setTextViewText(R.id.heading, listItem.heading);
            remoteView.setTextViewText(R.id.content, listItem.content);
            return remoteView;
        }
    }
    

    以下是ListItem的代码:

    public class ListItem {
        public String heading,content;
    }
    

    然而,在调整大小时,我得到了这个结果:

    enter image description here

    ListView消失了。有谁知道为什么?

1 个答案:

答案 0 :(得分:0)

我的列表视图为空,因为在方法getRemoteViews中我创建了新的RemoteViews,但我根本没有填充它。所以我对上面的代码做了一些更改:

private RemoteViews getRemoteViews(Context context, int minWidth, int minHeight, int appWidgetId) {
    int rows = getCellsForSize(minHeight);
    int columns = getCellsForSize(minWidth);
    switch (rows) {
        case 1:  return new RemoteViews(context.getPackageName(), R.layout.widget_layout);
        case 2:
            RemoteViews update2 = new RemoteViews(context.getPackageName(), R.layout.text_view_layout);
            RemoteViews textView = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
            update2.addView(R.id.lay2, textView); 
            Intent svcIntent = new Intent(context, WidgetService.class);
            svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
            svcIntent.setData(Uri.parse(
                    svcIntent.toUri(Intent.URI_INTENT_SCHEME)));
            update2.setRemoteAdapter(appWidgetId, R.id.listViewWidget,
                    svcIntent);
            return update2;
        case 3:
            RemoteViews update3 = new RemoteViews(context.getPackageName(), R.layout.text_view_layout);
            RemoteViews textView1 = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
            update3.addView(R.id.lay2, textView1);
            Intent svcIntent1 = new Intent(context, WidgetService.class);
            svcIntent1.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
            svcIntent1.setData(Uri.parse(
                    svcIntent1.toUri(Intent.URI_INTENT_SCHEME)));
            update3.setRemoteAdapter(appWidgetId, R.id.listViewWidget,
                    svcIntent1);
            return update3;
        case 4:
            RemoteViews update4 = new RemoteViews(context.getPackageName(), R.layout.text_view_layout);
            RemoteViews textView3 = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
            update4.addView(R.id.lay2, textView3);
            Intent svcIntent2 = new Intent(context, WidgetService.class);
            svcIntent2.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
            svcIntent2.setData(Uri.parse(
            svcIntent2.toUri(Intent.URI_INTENT_SCHEME)));
            update4.setRemoteAdapter(appWidgetId, R.id.listViewWidget,
                    svcIntent2);
            return update4;

        default: return null;
    }
}