Android-based floating components can be used to display new functions in applications.

Source: Internet
Author: User

Preface
 
When developing Android applications, new functions are essential. We have added new functions. Some of them can be seen at the first glance, but some new functions are relatively hidden, that is, it is difficult for users to know that you have added this new function. At this time, users need to give some prompts when opening our application to explain where we have added the new function, click where to view the new feature. At this time, we may first think of Toast because it is easy to use and does not affect user operations. However, it has a disadvantage that it cannot explicitly indicate where new features are added, unless you describe it in text. Therefore, I wrote a small component FloatTextToast Based on Toast (the name mentioned below replaces the component I wrote). It is as simple as Toast and makes up for Toast's shortcomings, it also looks better.



 

 

 
You can learn

1. Basic Toast usage
2. How to Create a message queue in Android
3. How to obtain the width, height, top, left, and other attributes of a View when the Activity is started
Basic Ideas

1. First, you must have a processed 9. PNG Image for adaptive text display. For more information about 9. PNG Processing, see Android Doc.
2. to display the following View, you must know the location of the target View.
3. Place the text to be displayed in a TextView, and use the Toast setView method to set the View to be displayed in Toast.
4. Based on the obtained position, use the setGravity method of Toast to display the content in the correct position.
In general, you need to know the target View, calculate the location where the prompt is to be displayed based on targetView, and use Toast to display the text of the prompt. However, there are several difficulties to solve.
Obtain the width and position attributes of targetVIew when the Activity is loaded.

We added a new function prompt, which will be prompted when the user opens the interface, but when the UI is not rendered and bound to the inverted Window, the width, height, and position of the targetView cannot be obtained. How can we know these attributes of targetView? The onAttachedToWindow callback method of the Activity cannot be used. Besides, it is added to API 5, which is not in the previous API. However, there is another way to obtain the targetView attribute when the prompt is displayed. If the targetView attribute cannot be obtained (0), it will be obtained until it is obtained, this is actually a round robin. To achieve this goal, when the developer calls FloatTextToast. show (), he uses the Message mechanism of Android to poll and obtain a targetView attribute. If yes, the prompt text is displayed. Before that, let's take a look at the FloatTextToast constructor to have a rough understanding of it, to prevent the member variables that appear in the code below from being unknown.
[Java]
1. private FloatTextToast (Context context, View targetView ){
2. this. mTargetView = targetView;
3. this. mContext = context;
4. mToast = new Toast (mContext );
5. mContentView = new TextView (mContext );
6. mContentView. setBackgroundResource (R. drawable. float_text_toast_bg );
7. mContentView. setTextColor (Color. BLACK );
8. mContentView. setTextSize (TypedValue. COMPLEX_UNIT_DIP, 16 );
9. mToast. setView (mContentView );
10.
11. // initialize a Handler thread
12. mHandlerThread = new HandlerThread ("FloatTextToast ");
13. mHandlerThread. start ();
14. mHandler = new FloatTextToastHandler (mHandlerThread. getloler ());
15 .}
 
Customize your own message Loop Mechanism
To use the Message mechanism in a custom component, we must have our own logoff mechanism. We cannot use the logoff mechanism of Activity, because other messages may need to be processed in the main logoff, this will cause our show method to delay calling, so the effect is not good, so we need a dedicated logoff to process this Message. To declare your own logoff, You need to cooperate with the HandlerThread class. This is a good thing. using it, you can easily create your own thread to process your Message. The usage is simple. The Code is as follows:
[Java] view plaincopyprint?
1. // initialize a Handler thread
2. mHandlerThread = new HandlerThread ("FloatTextToast ");
3. mHandlerThread. start ();
4. mHandler = new FloatTextToastHandler (mHandlerThread. getloler ());
 
In this way, a HandlerThread is declared and run. After running the Thread, we can obtain a logoff belonging to the Thread, and then send the Message to the logoff, then this thread can process the messages you sent .. Let's look at our Custom Handler.
[Java]
1. private class FloatTextToastHandler extends Handler {
2.
3. public FloatTextToastHandler (low.logoff ){
4. super (logoff );
5 .}
6.
7. @ Override
8. public void handleMessage (Message msg ){
9. switch (msg. what ){
10. case WHAT_SHOW:
11. showInHandler ();
12 .}
13 .}
14.
15.
16 .}
 
It needs to pass a logoff as the construction parameter declaration, which means to use this logoff to process the Message sent by me. The above code
[Java]
1. mHandler = new FloatTextToastHandler (mHandlerThread. getLooper ());
 
It is exactly what we mean to use a self-opened thread to process our Message. Next, let's take a look at how our showInHandler () method works.
[Java]
1./** the show method called by Handler is mainly used to wait for the location of {@ link # mTargetView */
2. private void showInHandler (){
3. int [] targetPos = getTargetViewPos ();
4. if (targetPos [0] = 0 & targetPos [1] = 0 ){
5. mHandler. sendEmptyMessageDelayed (WHAT_SHOW, 100 );
6.} else {
7. final Rect contentPos = getContentViewPos (targetPos );
8. mToast. setGravity (Gravity. LEFT | Gravity. TOP, contentPos. left, contentPos. top );
9. mToast. show ();
10 .}
11 .}
 
This method is actually at the location where the targetVIew is obtained. If no value is obtained, a Message is sent to the custom logoff to call the function again. If the location is obtained, call the setGravity method of Toast to set the position of the text to be displayed.
Obtain the location of the text to be displayed.
To obtain the display position, you must know the position of the targetVIew and its width and height, so that you can calculate the position of the text to be displayed. The View component has a function that converts the coordinates in the Window into an array.
[Java]
1. private int [] getTargetViewPos (){
2. final int [] targetPos = new int [2];
3. mTargetView. getLocationInWindow (targetPos );
4. return targetPos;
5 .}
In this way, the xy coordinates of targetView are returned. The coordinates of targetView are not enough, and the final position of contentView is required.
[Java]
1 ./**
2. * calculate the position where the floating text is displayed and place the floating text in the center of targetView.
3. * @ return a Rect containing top and left
4 .*/
5. private Rect getContentViewPos (int [] targetPos ){
6. final Rect windowVisibleRect = new Rect ();
7. final View targetView = mTargetView;
8. final TextView contentView = mContentView;
9. // Status Bar Height
10. targetView. getWindowVisibleDisplayFrame (windowVisibleRect );
11. int statusBarHeight = windowVisibleRect. top;
12.
13. // The Position of the triangle arrow in the background image
14. final TextPaint textPaint = contentView. getPaint ();
15. int contentW = (int) textPaint. measureText (String) contentView. getText ());
16. int arrowPos = (int) (contentW * (30.0/160 ));
17.
18. final Rect rect = new Rect ();
19. rect. left = targetPos [0] + targetView. getWidth ()/2-arrowPos;
20. rect. top = targetPos [1]-statusBarHeight + targetView. getHeight ();
21. return rect;
22 .}
 
This function allows the text to be displayed in the horizontal center of the targetView, that is, the background triangle of the text points to the position in the middle of the targetView landscape. To do this, you need to use Paint to measure the width of the text. Therefore, this component is also a defect and cannot display characters other than the String format, such as SpannableString.

Complete component code

The above section describes how to split the component code to illustrate the ideas and steps for implementing this component. The code is listed as a whole for a clear look.
[Java]
1 ./**
2. * floating text display. Based on a provided View, the text can be displayed below the View.
3. * You can set the display time. After this time is reached, it will automatically disappear. Currently, only display of the plain text {@ link String} type is supported.
4. * calculate the width of the displayed text.
5. * @ author michael_li (snow is heartless)
6. * @ since 2011-12-10 04:57:36 pm
7 .*/
8. public class FloatTextToast {
9. public static final int LENGTH_LONG = Toast. LENGTH_LONG;
10. public static final int LENGTH_SHORT = Toast. LENGTH_SHORT;
11. private static final int WHAT_SHOW = 1;
12.
13. private Context mContext;
14. private View mTargetView;
15. private Toast mToast;
16. private TextView mContentView;
17.
18. private HandlerThread mHandlerThread;
19. private FloatTextToastHandler mHandler;
20. private FloatTextToast (Context context, View targetView ){
21. this. mTargetView = targetView;
22. this. mContext = context;
23. mToast = new Toast (mContext );
24. mContentView = new TextView (mContext );
25. mContentView. setBackgroundResource (R. drawable. float_text_toast_bg );
26. mContentView. setTextColor (Color. BLACK );
27. mContentView. setTextSize (TypedValue. COMPLEX_UNIT_DIP, 16 );
28. mToast. setView (mContentView );
29.
30. // initialize a Handler thread
31. mHandlerThread = new HandlerThread ("FloatTextToast ");
32. mHandlerThread. start ();
33. mHandler = new FloatTextToastHandler (mHandlerThread. getloler ());
34 .}
35 ./**
36. * generate a FloatTextToast
37. * @ param context Activity context
38. * @ param targetView: The target View under which the floating text is to be displayed
39. * @ param text the text to be displayed
40. * @ param duration floating text display time {@ link # LENGTH_LONG} {@ link # LENGTH_SHORT}
41. * @ return a FloatTextToast, which can be displayed by calling {@ link # show ()}
42 .*/
43. public static FloatTextToast makeText (Context context, View targetView, String text, int duration ){
44. final FloatTextToast floatToast = new FloatTextToast (context, targetView );
45. final TextView contentView = floatToast. mContentView;
46. contentView. setText (text );
47. floatToast. mToast. setDuration (duration );
48. return floatToast;
49 .}
50 ./**
51. * display floating text
52 .*/
53. public void show (){
54. mHandler. sendEmptyMessage (WHAT_SHOW );
55 .}
56./** the show method called by Handler is mainly used to wait for the location of {@ link # mTargetView */
57. private void showInHandler (){
58. int [] targetPos = getTargetViewPos ();
59. if (targetPos [0] = 0 & targetPos [1] = 0 ){
60. mHandler. sendEmptyMessageDelayed (WHAT_SHOW, 100 );
61.} else {
62. final Rect contentPos = getContentViewPos (targetPos );
63. mToast. setGravity (Gravity. LEFT | Gravity. TOP, contentPos. left, contentPos. top );
64. mToast. show ();
65 .}
66 .}
67. private int [] getTargetViewPos (){
68. final int [] targetPos = new int [2];
69. mTargetView. getLocationInWindow (targetPos );
70. return targetPos;
71 .}
72 ./**
73. * calculate the position where the floating text is displayed and place the floating text in the center of targetView.
74. * @ return a Rect containing top and left
75 .*/
76. private Rect getContentViewPos (int [] targetPos ){
77. final Rect windowVisibleRect = new Rect ();
78. final View targetView = mTargetView;
79. final TextView contentView = mContentView;
80. // Status Bar Height
81. targetView. getWindowVisibleDisplayFrame (windowVisibleRect );
82. int statusBarHeight = windowVisibleRect. top;
83.
84. // The Position of the triangle arrow in the background image
85. final TextPaint textPaint = contentView. getPaint ();
86. int contentW = (int) textPaint. measureText (String) contentView. getText ());
87. int arrowPos = (int) (contentW * (30.0/160 ));
88.
89. final Rect rect = new Rect ();
90. rect. left = targetPos [0] + targetView. getWidth ()/2-arrowPos;
91. rect. top = targetPos [1]-statusBarHeight + targetView. getHeight ();
92. return rect;
93 .}
94. private class FloatTextToastHandler extends Handler {
95.
96. public FloatTextToastHandler (low.logoff ){
97. super (logoff );
98 .}
99.
100. @ Override
101. public void handleMessage (Message msg ){
102. switch (msg. what ){
103. case WHAT_SHOW:
104. showInHandler ();
105 .}
106 .}
107.
108.
109 .}
110 .}
 
This component is the same as the Toast implementation method, so it is not difficult to get started. You only need to use the makeText static method to generate one.
[Java]
1. FloatTextToast. makeText (Context context, View targetView, String text, int duration). show ()
In this simple way, just input several parameters and show them out, which is as easy as Toast.

Summary

Here, we mainly compile one FloatTextToast component by combining classes to facilitate the prompting of some information in the application, not only the prompts of new functions, but also other clicks to view personal information, just like above. The main difficulty here is that the Activity starts to obtain the targetView status. a custom message mechanism that is not affected is used to obtain the targetView status in a timely manner. The Toast queue mechanism is also used here, so that you can better display the messages one by one, so that the user can view the other one and not all at once, and the user has no time to view the messages. Here we also use Paint to measure the true width of the text, so we also have some defects. If anyone has a better method, I can leave a message to inform me. I am very grateful.
 

Attachment component source code and Demo download http://www.bkjia.com/uploadfile/2012/0317/20120317094437418.zip
 

From Yeju dongli
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.