Without further ado, let’s start with the picture above. This function works when the user clicks “? Prompt dialog box will pop up after such a bubbles, when a user to click on any position, the bullet box will disappear, I thought this function usage scenario is very wide, in the future I may also want to receive such a demand, by the way, can consolidate a custom map a View and use of the rich text, so I decided to hand pulled this Demo, the source code has been submitted, The reader who needs it can pull by himself at the end of the article.

First, the basic implementation ideas

1. Implementation of the bubble box

First, you need to draw a rectangle, then draw a small triangle at the top of the rectangle to create a BubbleView, and then wrap the BubbleView in BubbleViewLayout (which is a custom class) to complete the bubble box custom View implementation.

2. The clickable “?” following the text The question mark to achieve

Here I use the rich text class SpannableStringBuilder, and I’ll briefly describe how to use it: Step 1: Initialize a SpannableStringBuilder

SpannableStringBuilder spanText = new SpannableStringBuilder spanText = new SpannableStringBuilder spanText = new SpannableStringBuilder spanText = new SpannableStringBuilder + "");Copy the code

Step 2: “?” Insert the icon from leng-2 to leng-1 in the text. Notice the devil detail in the first step. I added a string with two Spaces at the end. Because WHEN I was developing, I found that if I added the question mark icon directly at the end, and there was no space to fill it, then the blank area behind the question mark was all clickable, which felt like a stupid solution, if anyone has a better solution, please let me know in the comments.

spanText.setSpan(
        new ImageSpan(finalThis,R.drawable.help_black,DynamicDrawableSpan.ALIGN_CENTER),
        spanText.length() - 2 , spanText.length() - 1,
        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Copy the code

Step 3: Give “?” Add listening click events

SpanText. SetSpan (/ / on? Sign add click event, New ClickableSpan() {@override public void onClick(@nonnull View widget) { spanText.length() - 2 , spanText.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);Copy the code

Step 4: Add spanText to the TextView and activate the click event:

subtitle_text.setText(spanText); subtitle_text.setMovementMethod(LinkMovementMethod.getInstance()); // Activate the event, if the sentence code is missing, then the click event will not take effect, please noteCopy the code

All right. This is the basic use of rich text, such as the need for a detailed understanding of the reader can baidu, there are a lot of posts introduced in detail, but the use of rich text I stepped on a pit, let me solve for a long time, Because I set the TextView control to maxWidth and maxLine = 2, if your device has a low resolution and no text on one line, it will be wrapped, which is normal, but what’s not normal is that my “?” Added to the end of the text, but he can’t wrap!! ! So there is the following situation, this is really see the ghost, finally after consulting information and source code, rewrite the draw() method in ImageSpan, manually add the height of the newline to solve the problem, the source code will be put later.

3. Click on the “?” After pop-up bubble prompt implementation

I’m using window mode here, because this ensures that my popbox is on the top View, so it won’t be blocked by other views, and most importantly, it can block event distribution, so that when the popbox is there, the click events of other views won’t respond, which is critical. As for the use of Window, I put the code directly, and the viewer can see the comments in the code to understand:

mBubbleViewLayout = new BubbleViewLayout(context); mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Window service / / / / get a window layout parameters initialization WindowManager. LayoutParams params = new WindowManager. LayoutParams (WindowManager. LayoutParams. MATCH_PARENT, WindowManager. LayoutParams. MATCH_PARENT, 0, 0, PixelFormat.TRANSLUCENT); // Set the window flags. These parameters are used to set the window event distribution mechanism, lock screen display, etc. Specific can see baidu or Google document params. Flags = WindowManager. LayoutParams. FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DIM_BEHIND; // Note that this flag is used with the following params.dimAmount to set the window background mask. The window background is pure black by default. Now I give him a set to transparent / / Settings window type for dialog params. Type = WindowManager. LayoutParams. TYPE_APPLICATION_ATTACHED_DIALOG; Params. DimAmount = 0.0 f; Params. Alpha = 0.99 f; params.gravity = Gravity.LEFT | Gravity.TOP; // Add the View to the window mWindowManager.addView(mBubbleViewLayout, params);Copy the code

Two, step pits and details

Alpha = 0.99f = 0.99f = 0 alpha = 0.99f = 0 alpha = 0.99f = 0 alpha = 0 alpha = 0 alpha = 0.99 This is not for fun, but because when I set it to 1, the background mask setting code here params.dimamount = 0.0f will completely fail and the background will turn to pure black. I have also analyzed the source code, but I still don’t know why. According to the source logic, it is ok for me to set it to 0.99 and why it is not ok to set it to 1. I wish I could get some help.

Another detail of the project is that when adapting to different screens, “?” The position may be different, for example, some devices can display the complete text on one line, and some devices need to wrap, which leads to the bubble box triangle tip needs to be positioned at all times “? “Where is the “?” GetLocationOnScreen (Position) is not an actual View, so I can’t call view.getLocationOnScreen(Position) directly to position it. Instead, I use the method of rewriting draw to get its relative position in the TextView. Then getLocationOnScreen(Position) to obtain the absolute position of the TextView, and finally add to get, need detailed understanding of the viewer can go to see my demo source.

Ok, the last source address, welcome to comment exchange, like and star!