Android to achieve bubble layout/window effect bubble tip angle direction and offset controllable _android

Source: Internet
Author: User

The Android custom layout realizes the Bubble window, which can control the angle direction and the offset of the bubble.

Effect chart

Realize

First customize a bubble layout.

/** * Bubble Layout/public class Bubblerelativelayout extends Relativelayout {/** * bubble angle direction/public enum Bubblelegor
 ientation {top, left, right, BOTTOM, NONE} public static int PADDING = 30;
 public static int leg_half_base = 30;
 public static float stroke_width = 2.0f;
 public static float Corner_radius = 8.0f;
 public static int shadow_color = COLOR.ARGB (100, 0, 0, 0);

 public static Float min_leg_distance = PADDING + leg_half_base;
 Private Paint mfillpaint = null;
 Private final Path MPath = new Path ();
 Private final Path Mbubblelegprototype = new Path ();

 Private final Paint mpaint = new Paint (Paint.dither_flag);
 private float mbubblelegoffset = 0.75f;

 Private Bubblelegorientation mbubbleorientation = Bubblelegorientation.left;
 Public Bubblerelativelayout {This (context, NULL);
 Public Bubblerelativelayout (context, AttributeSet attrs) {This (context, attrs, 0); Public Bubblerelativelayout, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle);
 Init (context, attrs);

  } private void Init (final context, final AttributeSet attrs) {//setgravity (gravity.center); Viewgroup.layoutparams params = new Viewgroup.layoutparams (ViewGroup.LayoutParams.MATCH_PARENT,
  ViewGroup.LayoutParams.MATCH_PARENT);

  Setlayoutparams (params);

   if (attrs!= null) {TypedArray a = Context.obtainstyledattributes (Attrs, r.styleable.bubble);
    try {PADDING = a.getdimensionpixelsize (r.styleable.bubble_padding, PADDING);
    Shadow_color = A.getint (R.styleable.bubble_shadowcolor, Shadow_color);
    Leg_half_base = A.getdimensionpixelsize (R.styleable.bubble_halfbaseofleg, leg_half_base);
    Min_leg_distance = PADDING + leg_half_base;
    Stroke_width = A.getfloat (R.styleable.bubble_strokewidth, stroke_width);
   Corner_radius = A.getfloat (R.styleable.bubble_cornerradius, Corner_radius);
    Finally {if (a!= null) {a.recycle (); }} mpaint.setcolor (SHAdow_color);
  Mpaint.setstyle (Style.fill);
  Mpaint.setstrokecap (Cap.butt);
  Mpaint.setantialias (TRUE);
  Mpaint.setstrokewidth (Stroke_width);
  Mpaint.setstrokejoin (Paint.Join.MITER);

  Mpaint.setpatheffect (New Cornerpatheffect (Corner_radius));
  if (Build.VERSION.SDK_INT >=) {setlayertype (Layer_type_software, mpaint);
  } mfillpaint = new Paint (mpaint);
  Mfillpaint.setcolor (Color.White);

  Mfillpaint.setshader (New LinearGradient (100f, 0f, 100f, 200f, Color.White, Color.White, Tilemode.clamp));
  if (Build.VERSION.SDK_INT >=) {setlayertype (Layer_type_software, mfillpaint);

  } mpaint.setshadowlayer (2f, 2F, 5F, Shadow_color);

  Renderbubblelegprototype ();

 Setpadding (PADDING, PADDING, PADDING, PADDING); 
 } @Override protected void onconfigurationchanged (Configuration newconfig) {super.onconfigurationchanged (newconfig);
  /** * Sharp point path/private void Renderbubblelegprototype () {mbubblelegprototype.moveto (0, 0); Mbubblelegprototype.linETo (PADDING * 1.5f,-padding/1.5f);
  Mbubblelegprototype.lineto (PADDING * 1.5f, padding/1.5f);
 Mbubblelegprototype.close (); } public void Setbubbleparams (final bubblelegorientation bubbleorientation, final float bubbleoffset) {mbubblelegoffs
  ET = Bubbleoffset;
 Mbubbleorientation = bubbleorientation; /** * According to the display direction, get the sharp angle position Matrix * @param width * @param height * @return/private matrix Renderbubblelegmatrix (FINA

  L float width, final float height) {final float offset = Math.max (Mbubblelegoffset, min_leg_distance);
  float DSTX = 0;
  float dsty = math.min (offset, height-min_leg_distance);

  Final Matrix matrix = new Matrix ();
    Switch (mbubbleorientation) {Case TOP:DSTX = math.min (offset, width-min_leg_distance);
    dsty = 0;
    Matrix.postrotate (90);

   Break
    Case right:dstx = width;
    Dsty = Math.min (offset, height-min_leg_distance);
    Matrix.postrotate (180);

   Break Case BOTTOM:DSTX = math.min (offset, Width-miN_leg_distance);
    Dsty = height;
    Matrix.postrotate (270);

  Break
  } matrix.posttranslate (Dstx, dsty);
 return matrix;
  } @Override protected void OnDraw (Canvas Canvas) {final float width = canvas.getwidth ();

  Final float height = canvas.getheight ();
  Mpath.rewind (); Mpath.addroundrect (New RECTF (PADDING, PADDING, width-padding, height-padding), Corner_radius, Corner_radius, Directio
  N.CW);

  Mpath.addpath (Mbubblelegprototype, Renderbubblelegmatrix (width, height));
  Canvas.drawpath (MPath, mpaint);

  Canvas.scale (width-stroke_width)/width, (height-stroke_width)/height, width/2f, height/2f);
 Canvas.drawpath (MPath, mfillpaint);

 }
}

Style Attrs.xml

<?xml version= "1.0" encoding= "Utf-8"?>
<resources>

 <declare-styleable name= "bubble" >
  <attr name= "shadowcolor" format= "color"/> <attr name=
  "padding" format= "Dimension"/>
  < attr name= "strokewidth" format= "float"/> <attr name=
  "Cornerradius" format= "float"/>
  <attr "Halfbaseofleg" format= "Dimension"/>
 </declare-styleable>

</resources>

Then customize a popupwindow to display the bubbles.

public class Bubblepopupwindow extends Popupwindow {private bubblerelativelayout bubbleview;

 private context;
  Public Bubblepopupwindow {this.context = context;
  SetWidth (ViewGroup.LayoutParams.WRAP_CONTENT);

  SetHeight (ViewGroup.LayoutParams.WRAP_CONTENT);
  Setfocusable (TRUE);
  Setoutsidetouchable (FALSE);

  Setclippingenabled (FALSE);
  Colordrawable DW = new colordrawable (0);
 Setbackgrounddrawable (DW);
  public void Setbubbleview (view view) {Bubbleview = new bubblerelativelayout (context);
  Bubbleview.setbackgroundcolor (color.transparent);
  Bubbleview.addview (view);
 Setcontentview (Bubbleview);
  public void SetParam (int width, int height) {setwidth (width);
 SetHeight (height);
 public void Show (View parent) {Show (parent, Gravity.top, Getmeasuredwidth ()/2);
 public void Show (View parent, int gravity) {Show (parent, Gravity, Getmeasuredwidth ()/2); /** * Show Window * * @param parent * @param gravity * @parAm Bubbleoffset The bubble tip angle position offset. Default is in center/public void Show (View parent, int gravity, float bubbleoffset) {bubblerelativelayout.bubblelegorientation
  orientation = BubbleRelativeLayout.BubbleLegOrientation.LEFT; if (!this.isshowing ()) {switch (Gravity) {Case Gravity.BOTTOM:orientation = Bubblerelativelayout.bubblelego Rientation.
     Top;
    Break
     Case Gravity.TOP:orientation = BubbleRelativeLayout.BubbleLegOrientation.BOTTOM;
    Break
     Case Gravity.RIGHT:orientation = BubbleRelativeLayout.BubbleLegOrientation.LEFT;
    Break
     Case Gravity.LEFT:orientation = BubbleRelativeLayout.BubbleLegOrientation.RIGHT;
    Break
   Default:break; } bubbleview.setbubbleparams (orientation, bubbleoffset);
   Set the bubble layout direction and sharp angle offset int[] location = new INT[2];

   Parent.getlocationonscreen (location);
     Switch (Gravity) {case Gravity.BOTTOM:showAsDropDown (parent);
    Break Case Gravity.TOP:showAtLocation (Parent, Gravity.no_Gravity, location[0], location[1]-getmeasureheight ());
    Break Case Gravity.RIGHT:showAtLocation (parent, gravity.no_gravity, Location[0] + parent.getwidth (), Location[1]-(parent
     . GetHeight ()/2));
    Break Case Gravity.LEFT:showAtLocation (parent, gravity.no_gravity, Location[0]-getmeasuredwidth (), Location[1]-(parent
     . GetHeight ()/2));
    Break
   Default:break;
  } else {This.dismiss (); }/** * Measuring height * * @return/public int getmeasureheight () {Getcontentview (). Measure (View.MeasureSpec.UNS
  Pecified, View.MeasureSpec.UNSPECIFIED);
  int popheight = Getcontentview (). Getmeasuredheight ();
 return popheight; /** * Measuring Width * * @return/public int getmeasuredwidth () {Getcontentview (). Measure (View.MeasureSpec.UNSPEC
  Ified, View.MeasureSpec.UNSPECIFIED);
  int popwidth = Getcontentview (). Getmeasuredwidth ();
 return popwidth;

 }
}

View_popup_window.xml

<?xml version= "1.0" encoding= "Utf-8"?> <com.yuyh.library.bubblerelativelayout xmlns:android=
 " Http://schemas.android.com/apk/res/android "
 xmlns:app=" Http://schemas.android.com/apk/res-auto
 " Android:id= "@+id/brlbackground"
 android:layout_width= "wrap_content"
 android:layout_height= "WRAP_" Content "
 android:background=" @android: color/transparent "
 app:cornerradius=" "
 app:halfbaseofleg=" 18DP "
 app:padding=" 18DP "
 app:shadowcolor=" #64000000 "
 app:strokewidth=" 5 ">

</ Com.yuyh.library.bubblerelativelayout>

Call

Bubblepopupwindow Lefttopwindow = new Bubblepopupwindow (mainactivity.this);
View Bubbleview = inflater.inflate (R.layout.layout_popup_view, null);
TextView tvcontent = (TextView) Bubbleview.findviewbyid (r.id.tvcontent);
Tvcontent.settext ("HelloWorld");
Lefttopwindow.setbubbleview (Bubbleview); Set the bubble content
lefttopwindow.show (view, Gravity.bottom, 0);//Show the Bounce window

Depend on

dependencies {
 compile ' com.yuyh.bubble:library:1.0.0 '
}

Project Address: Https://github.com/smuyyh/BubblePopupWindow

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Related Article

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.