Widget的开发: 一个最简单的例子

首先,我们来说说基本概念。通常来说, 一个widget具备以下3个基本要素:
1. 一个AppWidgetProviderInfo对象
这个对象通常是在 res/xml目录里设置的

2. 一个AppWidgetProvider类的实现
通常是需要创建一个AppWidgetProvider类的子类,来实现自定义小应用update, enabled, disabled和删除时触发的方法。

3. 一个布局
这个布局是widget初始启动时出现的布局。

举一个最最简单的例子:
1. 先在AndroidManifest.xml中定义桌面小应用
       <receiver
            android:name=".android.widget.NoteWidgetProvider"
            android:label="@string/app_widget_notes" >

            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/widget_note_info" />
        </receiver>
      

2. 在 res / xml 目录下设置应用的基本信息
xml/widget_note_info.xml
<?xml version="1.0" encoding="utf-8"?>

<appwidget-provider
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/widget_note"
    android:minWidth="294dip"
    android:minHeight="294dip">
</appwidget-provider>


3. 在 res / layout 目录下设置应用启动的初始布局
layout/widget_note.xml
<?xml version="1.0" encoding="utf-8"?>

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="294dip"
    android:layout_height="294dip">

    <ImageView
        android:id="@+id/widget_bg_image"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

    <TextView
        android:id="@+id/widget_text"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:paddingTop="40dip"
        android:paddingLeft="15dip"
        android:paddingRight="15dip"
        android:textSize="14sp"
        android:textColor="#FF663300"
        android:maxLines="12"
        android:lineSpacingMultiplier="1.2" />
</FrameLayout>


4. java源码实现AppWidgetProvider类中的自定义update, enable, disable, delete方法
public class NoteWidgetProvider extends AppWidgetProvider {
	
    private static final String TAG = NoteWidgetProvider.class.getSimpleName();

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		  
		ComponentName thisWidget = new ComponentName(context, NoteWidgetProvider.class);
		int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
		    
		for (int i = 0; i < allWidgetIds.length; i++) {
			
			int widgetId = allWidgetIds[i];
			
	    
			RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_note);
			remoteViews.setImageViewResource(R.id.widget_bg_image, R.drawable.empty_sketchy);
			
			Intent intent = new Intent(context, NoteWidgetProvider.class);

			intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
			intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);

			appWidgetManager.updateAppWidget(widgetId, remoteViews);
		
		}
	}

}


5. 如果要点击 widget 启动一个 activity, 需要修改4中的代码如下:
@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		  
		ComponentName thisWidget = new ComponentName(context, NoteWidgetProvider.class);
		int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
		    
		for (int i = 0; i < allWidgetIds.length; i++) {
			
			int widgetId = allWidgetIds[i];
			
	    	Intent intent = new Intent(context, NoteEditActivity.class);
                intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
            
                PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

                RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_note);
	    	remoteViews.setImageViewResource(R.id.widget_bg_image, R.drawable.empty_sketchy);
	    	
	    	remoteViews.setOnClickPendingIntent(R.id.widget_text, pendingIntent);

	  	    appWidgetManager.updateAppWidget(widgetId, remoteViews);
	  	    
	
		}
	
	}



6. NoteEditActivity的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	android:id="@+id/widget83"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
	android:orientation="vertical"
	xmlns:android="http://schemas.android.com/apk/res/android">
	<LinearLayout
		android:id="@+id/layout_notes"
		android:layout_width="fill_parent"
		android:layout_height="388dp"
		android:orientation="vertical">
		<EditText
			android:id="@+id/edit_notes"
			android:layout_width="fill_parent"
			android:layout_height="fill_parent"
			android:hint="Please input!"
			android:textSize="18sp" />
	</LinearLayout>
	<Button
		android:id="@+id/button_save"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:text="Save"
		android:gravity="center"
		android:layout_gravity="right" />
	
</LinearLayout>


7. 点击 NoteEditActivity 的按钮,返回widget页面的方法
public class NoteNote extends Activity {
	
	private static final String TAG = NoteNote.class.getSimpleName();
	
	private int mAppWidgetId;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.note_edit);
		
		Intent t = getIntent();
        mAppWidgetId = t.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
        
        Log.i(TAG,"mAppWidgetId=" + mAppWidgetId);
        
        Button b = (Button) this.findViewById(R.id.button_save);
        
        b.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				
			    RemoteViews views = new RemoteViews(getApplicationContext().getPackageName(), R.layout.widget_note);
			    views.setImageViewResource(R.id.widget_bg_image, R.drawable.empty_sketchy);

	            
	            //设置完成后需要获取AppWidgetManager,对指定的widget进行更新,才能使设置生效。
	            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
	            appWidgetManager.updateAppWidget(mAppWidgetId, views);
	            
	            finish();

				
			}
        	
        });
	}


8. 在WIDGET里输入点内容,使用最简单的方法保存起来,然后更新WIDGET时显示被修改的内容。
public class NoteWidgetProvider extends AppWidgetProvider {

     public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {

         for (int i = 0; i < allWidgetIds.length; i++) {
			
	   		int widgetId = allWidgetIds[i];
	                // 显示保存的输入内容		
			SharedPreferences settings = context.getSharedPreferences("MyPrefsFile", Context.MODE_PRIVATE);
		    String notes = settings.getString("my_abcdefg", "");
		    Log.i(TAG,"NOTES=" + notes);
            
			Intent intent = new Intent(context, NoteNote.class);
	    	
	    	intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
            
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

            RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_note);
	    	remoteViews.setImageViewResource(R.id.widget_bg_image, R.drawable.empty_sketchy);
                 // 将保存的输入内容显示在WIDGET的TEXTVIEW里。
	    	remoteViews.setTextViewText(R.id.widget_text, notes);
	    	
	    	remoteViews.setOnClickPendingIntent(R.id.widget_text, pendingIntent);

	  	    appWidgetManager.updateAppWidget(widgetId, remoteViews);
	  	    
	
		}


     }
  
}
// 将输入的信息保存起来
public class NoteNote extends Activity {
   .......
   @Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		this.setContentView(R.layout.note_edit);
		
		Intent t = getIntent();
        mAppWidgetId = t.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
        // 将保存的信息显示在输入框内
        SharedPreferences settings = getSharedPreferences("MyPrefsFile", Context.MODE_PRIVATE);
	    notes = settings.getString("my_abcdefg", "");
	    Log.i(TAG,"NOTES=" + notes);
        
        et = (EditText) findViewById(R.id.edit_notes);
        et.setText(notes);
        
        Button b = (Button) this.findViewById(R.id.button_save);
        
        b.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
		
				if(et!=null) notes = et.getText().toString();
				Log.i(TAG,"after onclick, text is =" + notes);
				
                                // 将修改后的输入信息保存起来
				SharedPreferences.Editor editor = getSharedPreferences("MyPrefsFile", Context.MODE_PRIVATE).edit();
			    editor.putString("my_abcdefg", notes);
			    editor.commit();
				
                            // 调用widget页面,并将修改后的内容显示在widget内。
			    RemoteViews views = new RemoteViews(getApplicationContext().getPackageName(), R.layout.widget_note);
			    views.setImageViewResource(R.id.widget_bg_image, R.drawable.empty_sketchy);
			    views.setTextViewText(R.id.widget_text, notes);

	            
	            //设置完成后需要获取AppWidgetManager,对指定的widget进行更新,才能使设置生效。
	            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
	            appWidgetManager.updateAppWidget(mAppWidgetId, views);
	            
	            finish();

				
			}
        	
        });
	}


}

猜你喜欢

转载自jean7155.iteye.com/blog/1884419