Http://www.cnblogs.com/TerryBlog/archive/2010/07/29/1788319.html
I was planning to continue the API demos series in the evening, but this afternoon I was bored with playing a desktop component app widget. I am very interested in it, I encountered a lot of problems and had been solving the problem until PM. I can only blame myself for not understanding deeply, but I finally solved the problem. I can write some insights and give them an explanation. The outline of this article is as follows:
- 1. appwidget framework class
- 2. How to Use widgets in Android
- 3. Main Types of appwidget framework
- 4. Demo
1. appwidget framework class
- 1. appwidgetprovider: inherits from broadcastrecevier and receives notifications when appwidget applies update, enable, disable, and delete. Onupdate and onreceive are the most common methods. They receive update notifications.
- 2. appwidgetprovderinfo: Describes the appwidget size, update frequency, initial interface, and other information. It is stored in the Res/XML/directory of the application as an XML file.
- 3. appwidgetmanger: Manages appwidgets and sends notifications to appwidgetprovider.
- 4. remoteviews: a class that can be run in other application processes. It sends notifications to appwidgetprovider.
2. How to Use widgets in Android
- 1. Long-pressed Main Interface
- 2. A dialog box is displayed, which contains some built-in Android desktop components.
3. Main Types of appwidget framework
1)AppwidgetmangerClass
- Bindappwidgetid (INT appwidgetid, componentname provider)
Bind appwidgetid with the given componentname
- Getappwidgetids (componentname provider)
Obtain appwidgetid using the given componentname
- Getappwidgetinfo (INT appwidgetid)
Obtain appwidget information through appwidgetid
- Getinstalledproviders ()
Returns the information of a list <appwidgetproviderinfo>.
- Getinstance (context)
Obtains the context object used by the appwidgetmanger instance.
- Updateappwidget (INT [] appwidgetids, remoteviews views)
Use appwidgetid to modify the passed remoteview and refresh the appwidget component.
- Updateappwidget (componentname provider, remoteviews views)
Modify the passed remoeteview using componentname, and refresh the appwidget component.
- Updateappwidget (INT appwidgetid, remoteviews views)
Use appwidgetid to modify the passed remoteview and refresh the appwidget component.
2) The methods inherited from appwidgetprovider can be implemented as follows:
- 1. ondeleted (context, int [] appwidgetids)
- 2. ondisabled (context)
- 3. onenabled (context)
- 4. onreceive (context, intent)
Tip: Because appwidgetprovider inherits from broadcastreceiver, You can override the onrecevie method. Of course, you must register the receiver in the background.
- 5. onupdate (context, appwidgetmanager, int [] appwidgetids)
4. Demo
The following is an example of my practice today. It provides reference for everyone. The effect is as follows: Put A textview in the layout for desktop components, set the clickable = "true" function of textview to enable the click function. Then, when we click it, we change its font and click it to return. The detailed procedure is as follows:
- 1. Create appwidgetprovderinfo
- 2. Write a class inherited from appwidgetprovider
- 3. Register a receiver in the background
- 4. Enable the appwidget component to support click events
- 5. How to Make textview jump back and forth between the two types of Text
The problem is thrown out, So solve it together.
1. Create appwidgetprovderinfo
The Code is as follows:
<? 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/main">
</Appwidget-provider>
Tip: As mentioned aboveAppwidgetprovderinfoIt exists in the Res/XML file format. It is difficult to understand the parameters. Here, Android: initiallayout = "@ layout/main" is the layout file of the specified Desktop component.
2. Write a class inherited from appwidgetprovider
The main code is as follows:
Public class widgetprovider extends appwidgetprovider
And rewrite the two methods.
@ Override
Public void onupdate (context, appwidgetmanager,
Int [] appwidgetids ){}
@ Override
Public void onreceive (context, intent ){}
Tip: onupdate is called when the component is generated on the desktop and updates the component UI. onreceiver calls the update UI when receiving the broadcast. Generally, these two methods are commonly used.
3. Register a receiver in the background
The background configuration file code is as follows:
<Cycler Android: Name = ". widgetprovider">
<Meta-data Android: Name = "android. appwidget. provider"
Android: Resource = "@ XML/appwidget_provider"> </meta-data>
<Intent-filter>
<Action Android: Name = "com. Terry. Action. widget. Click"> </Action>
<Action Android: Name = "android. appwidget. Action. appwidget_update"/>
</Intent-filter>
</Cycler>
Tip: because it is a desktop component, you do not need to use the activity interface for the time being. Of course, you may need to jump to the activity application for operations when you click it during project implementation, A typical case is the music player provided by Android. <Meta-data Android: Name = "android. appwidget. provider "Android: Resource =" @ XML/appwidget_provider "> </meta-data> indicatesAppwidgetprovderinfoFile to manage files.
4. Enable the appwidget component to support click events
First look at the Code:
Public static void updateappwidget (context,
Appwidgetmanager appwidgemanger, int appwidgetid ){
Rv = new remoteviews (context. getpackagename (), R. layout. Main );
Intent intentclick = new intent (click_name_action );
Pendingintent = pendingintent. getbroadcast (context, 0,
Intentclick, 0 );
RV. setonclickpendingintent (R. Id. textview01, pendingintent );
Appwidgemanger. updateappwidget (appwidgetid, RV );
}
This method is used to update the UI called by onupdate when a component is created. In the code, use remoteview to find the layout file of the component, at the same time, set the broadcast receiver click_name_action for it and locate the textview for which I want to trigger the event through the setonclickpendingintent method of remoteview. Next
@ Override
Public void onreceive (context, intent ){
// Todo auto-generated method stub
Super. onreceive (context, intent );
If (Rv = NULL ){
Rv = new remoteviews (context. getpackagename (), R. layout. Main );
}
If (intent. getaction (). Equals (click_name_action )){
If (uitil. ischange ){
RV. settextviewtext (R. Id. textview01, context. getresources ()
. Getstring (R. String. Load ));
} Else {
RV. settextviewtext (R. Id. textview01, context. getresources ()
. Getstring (R. String. Change ));
}
Toast. maketext (context, Boolean. tostring (uitil. ischange ),
Toast. length_long). Show ();
Uitil. ischange =! Uitil. ischange;
}
Appwidgetmanager appwidgetmanger = appwidgetmanager
. Getinstance (context );
Int [] appids = appwidgetmanger. getappwidgetids (New componentname (
Context, widgetprovider. Class ));
Appwidgetmanger. updateappwidget (appids, RV );
}
In oncycler, the broadcast is judged to trigger the action.
5. How to Make textview jump back and forth between the two types of Text
How can textview return in two states? This is also one of the longest debugging difficulties. The problem lies in the lack of in-depth understanding of appwidget. If my idea is correct, the life cycle of appwidget should end with a life cycle after each broadcast execution is received. That is to say, you declare the global variable in the rewritten appwidgetprovider class for status judgment, every time the status changes, appwidgetprovider reinitializes the app for you when it receives the second broadcast, that is, the table is reinstantiated for you once again. Today, because I put a Boolean value in it and initialized it to "true", we can see that each entry is true. Therefore, when you set the Desktop component, the global variable declares it in another entity class to determine whether it is OK. Do not place it in this class. For the code, refer to the onreceiver method.
As follows:
Code:
Code
Package com. Terry;
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;
Import Android. widget. Toast;
Public class widgetprovider extends appwidgetprovider {
Private Static final string click_name_action = "com. Terry. Action. widget. Click ";
Private Static remoteviews RV;
@ Override
Public void onupdate (context, appwidgetmanager,
Int [] appwidgetids ){
// Todo auto-generated method stub
Final int n = appwidgetids. length;
For (INT I = 0; I <n; I ++ ){
Int appwidgetid = appwidgetids [I];
Updateappwidget (context, appwidgetmanager, appwidgetid );
}
}
@ Override
Public void onreceive (context, intent ){
// Todo auto-generated method stub
Super. onreceive (context, intent );
If (Rv = NULL ){
Rv = new remoteviews (context. getpackagename (), R. layout. Main );
}
If (intent. getaction (). Equals (click_name_action )){
If (uitil. ischange ){
RV. settextviewtext (R. Id. textview01, context. getresources ()
. Getstring (R. String. Load ));
} Else {
RV. settextviewtext (R. Id. textview01, context. getresources ()
. Getstring (R. String. Change ));
}
Toast. maketext (context, Boolean. tostring (uitil. ischange ),
Toast. length_long). Show ();
Uitil. ischange =! Uitil. ischange;
}
Appwidgetmanager appwidgetmanger = appwidgetmanager
. Getinstance (context );
Int [] appids = appwidgetmanger. getappwidgetids (New componentname (
Context, widgetprovider. Class ));
Appwidgetmanger. updateappwidget (appids, RV );
}
Public static void updateappwidget (context,
Appwidgetmanager appwidgemanger, int appwidgetid ){
Rv = new remoteviews (context. getpackagename (), R. layout. Main );
Intent intentclick = new intent (click_name_action );
Pendingintent = pendingintent. getbroadcast (context, 0,
Intentclick, 0 );
RV. setonclickpendingintent (R. Id. textview01, pendingintent );
Appwidgemanger. updateappwidget (appwidgetid, RV );
}
}In addition, the above content has been tested, and the annotations are as follows:Void updateappwidget (context, appwidgetmanager, int appwidgetid) {remoteviews views = new remoteviews (context. getpackagename (), R. layout. appwidget_provider); intent it = new intent (context, xxxx. class); pendingintent Pit = pendingintent. getactivity (context, 0, IT, 0); views. setonclickpendingintent (R. id. appwidget_image, pit); appwidgetmanager. updateappwidget (appwidgetid, vi EWS);} XXXX activity can be started by modifying updateappwidget as above. Note: appwidgetmanager. updateappwidget (appwidgetid, views); the last line should be used; otherwise, the result will be invalid.
For more information, see the widget in the android music routine.