zoukankan      html  css  js  c++  java
  • Android app 实现AppWidget 窗口部件开发

    一,描述

      在很多情况下,我们都需要自己的APP具有像,天气预报,微博,或者播放器这样的。在主屏幕里嵌入自己的窗口小部件的需求。

    下面就是俺研究部件时的一个写的一个小DEMO。

    二,开发准备

       1,在res/目录下创建 XML 文件夹 下建立一个 appwidget-provider.xml 文件。

       2,在res/layout/目录下建立一个widget.xml

     

    三,配置文件代码解释

    1,appwidget-provider.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
        android:minWidth="60dp"
        android:minHeight="30dp"
        android:updatePeriodMillis="86400000"
        android:initialLayout="@layout/widget">
    </appwidget-provider>
    <!--这里就是定义 窗口部件的宽,高,和指定布局文件 等待属性的。(详细的属性设置百度一大把)  -->

    2,widget.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="150dp"
        android:layout_height="120dp"
        android:orientation="vertical">
        <Button 
            android:id="@+id/btn_prve_widget"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="上一条" />
        <TextView
            android:id="@+id/textview_info_widget"
            android:layout_width="fill_parent"
            android:layout_height="30dp"
            android:text="笑话载入中..."
            android:gravity="center" />
            <Button 
            android:id="@+id/btn_next_widget"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="下一条" />
        </LinearLayout>
    <!--这里就是定义 窗口部件的界面布局文件(具体应用具体布局)  -->

    3,AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.yeqw.android"
          android:versionCode="1"
          android:versionName="1.0">
        <uses-sdk android:minSdkVersion="7" />
    
        <application android:icon="@drawable/icon" android:label="@string/app_name">
            <activity android:name="com.yeqw.android.mainActivity"
                      android:label="@string/app_name">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <!--窗口部件配置begin-->
            <receiver android:name="com.yeqw.android.sample.AppWidgetProviderSample">
                <meta-data android:name="android.appwidget.provider"
                    android:resource="@xml/appwidget_provider"></meta-data>
                <intent-filter>
                    <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                    <action android:name="PREV"></action>
                    <action android:name="NEXT"></action> 
                </intent-filter>
            </receiver>
            <!--窗口部件配置end-->
        </application>
    </manifest>

    以下两个action 是具体应用具体定义了。主要就是做一些Action的判断。

    <action android:name="PREV"></action>
    <action android:name="NEXT"></action> 

     4,部件Widget 实现的 java代码

    package com.yeqw.android.sample;
    
    import com.yeqw.android.R;
    
    import android.app.PendingIntent;
    import android.appwidget.AppWidgetManager;
    import android.appwidget.AppWidgetProvider;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.widget.RemoteViews;
    
    
    public class AppWidgetProviderSample extends  AppWidgetProvider{
        
        //这个是部件传递数据和操作部件里的控件的一个通道(个人理解)
        private static RemoteViews rv;
        
        //部件更新的时候触发
        @Override
        public void onUpdate(Context context, AppWidgetManager appWidgetManager,
                int[] appWidgetIds) {
            // TODO Auto-generated method stub
            
            for (int i = 0; i < appWidgetIds.length; i++) {
                int appWidgetId = appWidgetIds[i];
                updateAppWidget(context, appWidgetManager, appWidgetId);
            }
        }
        //布局被通知的时候触发
        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
            super.onReceive(context, intent);
            String info="无数据";
            if (rv == null) {
                return;
            }
            //通过Action 来判断是否是自己需要触发业务的Action,(这里Action 值必须和AndroidManifest.xml保持一致)
            if (intent.getAction().equals("PREV")) {
                info="获得上一条新数据了";
                rv.setTextViewText(R.id.textview_info_widget, info);
            }
            else if (intent.getAction().equals("NEXT"))
            {
                info="获得下一条新数据了";
                rv.setTextViewText(R.id.textview_info_widget, info);
            }
            
            AppWidgetManager appWidgetManger = AppWidgetManager.getInstance(context);
            int[] appIds = appWidgetManger.getAppWidgetIds(new ComponentName(context, AppWidgetProviderSample.class));
            //更新部件
            appWidgetManger.updateAppWidget(appIds, rv);
            }
        
        
        
        public static void updateAppWidget(Context context,
                AppWidgetManager appWidgeManger, int appWidgetId) {
            if(rv!=null)return;
            //这里就是初始化 部件里的各个控件。包括事件绑定。
            rv = new RemoteViews(context.getPackageName(), R.layout.widget);
        
            String info="获得新数据了";
            rv.setTextViewText(R.id.textview_info_widget, info);
            
            Intent prevIntent = new Intent("PREV");
            PendingIntent prevPendingIntent = PendingIntent.getBroadcast(context,0,prevIntent,0);
            rv.setOnClickPendingIntent(R.id.btn_prve_widget,prevPendingIntent);
            
            Intent nextIntent = new Intent("NEXT");
            PendingIntent nextPendingIntent = PendingIntent.getBroadcast(context,0,nextIntent,0);
            rv.setOnClickPendingIntent(R.id.btn_next_widget, nextPendingIntent);
            
            appWidgeManger.updateAppWidget(appWidgetId, rv);
        }
        
        
    }

    四,总结

      这个DEMO 里只用到了 onUpdate onReceive 事件(AppWidgetProvider 其他事件有想了解的百度一大把。)

    主要 PendingIntent 用这个做按钮事件绑定的处理 和RemoteViews 这个部件里用的最多的一个类的操作。

    还是那句话 具体应用具体对待,但路就是这样走的。根据业务我们可以从 数据的获取到 事件的处理都可以多样化的。

    (俺属于实用主义者,但任何技术在运用到实际开发中一定要 知其然,更要知其所以然。)Demo只是一个方向一条路

    但业务是千变万化的。所以还是那句 具体应用具体对待。呵呵(这个是过完年的第一篇blog 有点啰嗦。)

    新浪微博 http://www.weibo.com/yeqw 腾讯微博 http://t.qq.com/xingji_yxx 热烈欢迎大家一起交流讨论并提出宝贵意见,多多指导。
  • 相关阅读:
    提高编程能力的7条建议(转载)
    1.2、Mybatis二级缓存测试
    1.1、Mybatis一级缓存测试
    外键约束
    【转】MyBatis学习总结(四)——解决字段名与实体类属性名不相同的冲突
    【转】MyBatis学习总结(三)——优化MyBatis配置文件中的配置
    【转】The content of element type "configuration" must match "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?...
    【转】MyBatis学习总结(二)——使用MyBatis对表执行CRUD操作
    【转】MyBatis学习总结(一)——MyBatis快速入门
    java面板
  • 原文地址:https://www.cnblogs.com/yeqw1985/p/2960150.html
Copyright © 2011-2022 走看看