Android Imitation micro-letter, QQ near friends radar scanning effect _android

Source: Internet
Author: User
Tags float max getcolor radar

1. Overview

Recently, until in the band interns, because more people, so a long time did not update the blog, today updated a radar scan close friend effect, and then try to update one every week, first look at the effect:

2. Realize 

1, Effect analysis

The effect is divided into two parts, one is the first half of the custom Radarview, there is the lower part of the Viewpager, as to how to do scaling and the effect of the virtual background you can go to see lazyviewpager here is not detailed, here the main implementation of the scanning effect.

2, the scanning effect realization

2.1 Custom Radarview in the OnDraw () method to draw six circles, as for the radius of the circle is how much we need to pass onmeasure (int widthmeasurespec, int heightmeasurespec) The measurement method obtains the width of the control to determine the radius of the circle, the radius of each circle is the width of the 1/13f, 2/13f, 3/13f, 4/13f, 5/13f, 6/13f, this is only the test itself to feel more comfortable effect, see the code below:

The proportions of each circle private static float[] Circleproportion = {1/13f, 2/13f, 3/13f, 4/13f, 5/13f, 6/13f}; Private Paint mpaintcircle;//The Paint public class Radarview the extends View {public radarview to be used for the drawing circle {thi
 s (context, NULL);
 Public Radarview (context, AttributeSet attrs) {This (context, attrs, 0);
 Public Radarview (context, AttributeSet attrs, int defstyleattr) {Super (context, attrs, defstyleattr);
 Init ();
 private void Init () {mpaintcircle = new Paint ();
 Mpaintcircle.setcolor (Color.White);
 Mpaintcircle.setantialias (TRUE); @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {//Get control's width high setmeasureddimension (m
 Easuresize (Widthmeasurespec), Measuresize (Widthmeasurespec));
 Mwidth = Getmeasuredwidth ();
 Mheight = Getmeasuredheight ();
 Mwidth = Mheight = Math.min (Mwidth, mheight);
 @Override protected void OnDraw (Canvas Canvas) {//Draw six white circles drawcircle (Canvas); /** * Draw Round coil * *PARAM Canvas * * private void drawcircle (canvas canvas) {canvas.drawcircle (MWIDTH/2, MHEIGHT/2, Mwidth * circleprop ORTION[1], mpaintline); Draw the smallest circle Canvas.drawcircle (MWIDTH/2, MHEIGHT/2, Mwidth * circleproportion[1), mpaintline); Draw small round canvas.drawcircle (MWIDTH/2, MHEIGHT/2, Mwidth * circleproportion[2), mpaintline); Draw Middle Circle canvas.drawcircle (MWIDTH/2, MHEIGHT/2, Mwidth * circleproportion[3), mpaintline); Draw Central Circle Canvas.drawcircle (MWIDTH/2, MHEIGHT/2, Mwidth * circleproportion[4), mpaintline); Draw Great Circle Canvas.drawcircle (MWIDTH/2, MHEIGHT/2, Mwidth * circleproportion[5), mpaintline);

 Draw large Round}}

2.2 Below need to draw the middle of the user image, you can run to see if the middle of the six circle has no effect, here is not seen directly in the OnDraw () method to draw the middle image:

 Private Bitmap centerbitmap;//Most intermediate icon

 private void init () {
 //Bitmap Centerbitmap The user image through the Bitmap factory area
 = Bitmapfactory.decoderesource (Getresources (), R.drawable.circle_photo);
 }

 @Override
 protected void OnDraw (Canvas Canvas) {
 Drawcentericon (Canvas);
 }

 /**
 * Draw the most middle icon
 *
 * @param canvas * *
 private void Drawcentericon (canvas canvas) {
 int Iconwidth = Mwidth * Circleproportion[0];
 Canvas.drawbitmap (Centerbitmap, 0,0,iconwidth, iconwidth, null);
 

2.3 Finally only need to implement the effect of this scan the control is basically complete, the first need to open the thread constantly call invalidate () to update the OnDraw () method, the second need to be familiar with the scan rendering sweepgradient This class, if these two are no problem that the success:

 mpaintscan;//private matrix matrix = new Matrix () that is needed for the scan of private Paint Paint private int mrotedegree;//scan rotation angle private Shader scanshader;//scan render Shader public Runnable run = new Runnable () {@Overrid
  e public void Run () {Mrotedegree +=2;
  Mrotematrix.postrotate (Mrotedegree,cx,cy);
  Invalidate ();
 Postdelayed (run,60);

}
 }; @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {//Set scan rendering Shader Scanshader = new Swee
 Pgradient (MWIDTH/2, MHEIGHT/2, New int[]{color.transparent, Color.parsecolor ("#84B5CA")}, NULL);
 } @Override protected void OnDraw (Canvas Canvas) {Drawscan (Canvas);
 /** * Draw Scan * * @param canvas * * * private void Drawscan (canvas canvas) {canvas.save ();
 Mpaintscan.setshader (Scanshader);
 Canvas.concat (matrix);
 Canvas.drawcircle (MWIDTH/2, MHEIGHT/2, Mwidth * circleproportion[4), mpaintscan);
 Canvas.restore (); }


2.4. Here, let's take a look at the effect of scanning radarview.

3. Implementation add data Effect Radarviewgroup, our image near the point need to join viewgroup here again need to customize, here simple to say the custom ViewGroup:
1. Onmeasure () method of measurement here's the word.
2. As long as you know what the OnLayout () method is doing, the ok,viewgroup inside of the child view are shown in what position is written in this method, in other words, some close to the distance are separated by child.layout (int l, int t, int r, int b), let's look at the code below:

 public class Radarviewgroup extends ViewGroup implements Radarview.iscanninglistener {private int mwidth, MHEIGHT;//VI Ewgroup's wide-high private sparsearray<float> scananglelist = new sparsearray<> ()//The scan position of the item where the record is displayed private Sparsearray<info> mdatas;//Data source private int datalength;//data source length private int minitemposition;//minimum distance of item in the data source position p Rivate Circleview currentshowchild;//currently displayed item private Circleview minshowchild;//minimum distance item private Iradarclicklistener iradarclicklistener;//Radar Map click on monitor circleview dot callback interface public void Setiradarclicklistener (
 Iradarclicklistener iradarclicklistener) {this.iradarclicklistener = Iradarclicklistener;
 The public Radarviewgroup {This (context, NULL);
 Public Radarviewgroup (context, AttributeSet attrs) {This (context, attrs, 0);
 Public Radarviewgroup (context, AttributeSet attrs, int defstyleattr) {Super (context, attrs, defstyleattr); } @Override protected void onmeasure (int widthmeasurespEC, int heightmeasurespec) {setmeasureddimension (Measuresize (Widthmeasurespec), Measuresize (HeightMeasureSpec));
 Mwidth = Getmeasuredwidth ();
 Mheight = Getmeasuredheight ();
 Mwidth = Mheight = Math.min (Mwidth, mheight);
 Measure each children Measurechildren (Widthmeasurespec, Heightmeasurespec);
  for (int i = 0; i < Getchildcount (); i++) {View child = Getchildat (i);
  if (child.getid () = = r.id.id_scan_circle) {//The required attributes ((Radarview) child) are set for the radar scan map. Setscanninglistener (this); Consider that the scan is scanned before the data is added, but will not start with the Circleview layout if (mdatas!= null && mdatas.size () > 0) {(radarview) child). Setm
   Axscanitemcount (Mdatas.size ());
  ((Radarview) child). Startscan ();
  } continue; }} @Override protected void OnLayout (Boolean changed, int l, int t, int r, int b) {int childcount = Getchildcoun
 T ();
 First place the radar scanning map view view = Findviewbyid (r.id.id_scan_circle);
 if (view!= null) {view.layout (0, 0, view.getmeasuredwidth (), View.getmeasuredheight ()); }//Place the item dot to be displayed in the radar map
 for (int i = 0; i < ChildCount; i++) {final int j = i;
  Final View child = Getchildat (i);
  if (child.getid () = = r.id.id_scan_circle) {//If not circleview skip continue; //Set the coordinates of Circleview small dots/coordinates = rotation angle * RADIUS * The proportion of the radius ((circleview) child) to be calculated based on the difference between the distance. Setdisx ((float) Math.Cos (Mat
  H.toradians (Scananglelist.get (i-1)-5)) * ((Circleview) child). Getproportion () * MWIDTH/2); ((Circleview) child). Setdisy ((float) Math.sin (Math.toradians (Scananglelist.get (i-1)-5)) * ((Circleview) child). Getp
  Roportion () * MWIDTH/2); If the value of the corresponding item in the scan angle record Sparsearray is 0,//description has not yet been scanned to the item, skipping layout//(scananglelist setting the data all value=0 when Onscann
  When ING, the value set is always not 0, which can be seen in the onscanning (scananglelist.get) if (i-1) = = 0) {continue;  }//Place Circle dot child.layout ((int) (Circleview) child). GETDISX () + MWIDTH/2, (int) ((Circleview) baby). Getdisy () + MHEIGHT/2, (int) (Circleview) child). GETDISX () + child.getmeasuredwidth () + MWIDTH/2, (int) (CiRcleview). Getdisy () + child.getmeasuredheight () + MHEIGHT/2); Set Click event Child.setonclicklistener (New Onclicklistener () {@Override public void OnClick (View v) {Resetanim (Curre
   Ntshowchild);
   Currentshowchild = (circleview) child;
   Since radar is Childat (0), it is necessary to make-1 is the correct circle Startanim (Currentshowchild, j-1);

   if (Iradarclicklistener!= null) {Iradarclicklistener.onradaritemclick (j-1);
 }
  }
  });
 } private int measuresize (int measurespec) {int result = 0;
 int specmode = Measurespec.getmode (Measurespec);
 int specsize = measurespec.getsize (Measurespec);
 if (Specmode = = measurespec.exactly) {result = Specsize;
  else {result = 300;
  if (Specmode = = measurespec.at_most) {result = Math.min (result, specsize);

 } return result;
 /** * Set Data * * @param mdatas/public void Setdatas (sparsearray<info> mdatas) {this.mdatas = Mdatas;
 Datalength = Mdatas.size ();
 float min = float.max_value; float max = Float.min_vaLUE;
  Find the maximum distance, the minimum corresponding to the minitemposition for (int j = 0; J < Datalength; J + +) {Info item = Mdatas.get (j);
  if (Item.getdistance () < min) {min = Item.getdistance ();
  Minitemposition = j;
  } if (Item.getdistance () > Max) {max = Item.getdistance ();
 } scananglelist.put (J, 0f); Circleview for (int i = 0; i < datalength i++) {Circleview Circleview = new Circleview (GetContext (
  ));
  if (Mdatas.get (i). Getsex ()) {Circleview.setpaintcolor (Getresources (). GetColor (R.color.bg_color_pink));
  else {Circleview.setpaintcolor (Getresources (). GetColor (R.color.bg_color_blue));
  0.312-0.832 circleview.setproportion (Mdatas.get (i) getdistance ()/Max + 0.6f) * 0.52f) based on the difference of distance between distances.
  if (minitemposition = = i) {minshowchild = Circleview;
 } addview (Circleview); }/** * A callback * @param position * @param scanangle/@Override public void onscanning (int position) when the radar map is not finished scanning Float scanangle) {if (Scanangle = 0) {SCAnanglelist.put (position, 1f);
 else {scananglelist.put (position, scanangle);
 } requestlayout ();
 /** * When the scan of the radar map is completed, the callback/@Override public void onscansuccess () {LOGUTIL.M ("complete callback");
 Resetanim (Currentshowchild);
 Currentshowchild = Minshowchild;
 Startanim (Currentshowchild, minitemposition);
  /** * Restore Circleview Small dot Original Size * * @param object */private void Resetanim (Circleview object) {if (object!= null) {
  Object.clearportaiticon ();
  Objectanimator.offloat (Object, "ScaleX", 1f). Setduration (). Start ();
 Objectanimator.offloat (Object, "ScaleY", 1f). Setduration (). Start ();  }/** * Zoom Circleview Small dot Size * * @param object * @param position/private void Startanim (Circleview object, int
  Position) {if (object!= null) {Object.setportraiticon (Mdatas.get (position). Getportraitid ());
  Objectanimator.offloat (Object, "ScaleX", 2f). Setduration (). Start ();
 Objectanimator.offloat (Object, "ScaleY", 2f). Setduration (). Start (); Click on the/** * radar map to monitor circleView small DOT Callback interface */public interface Iradarclicklistener {void Onradaritemclick (int position); /** * According to position, enlarge the specified circleview dot * * @param position * * public void Setcurrentshowitem (int position) {Circle
 View child = (Circleview) getchildat (position + 1);
 Resetanim (Currentshowchild);
 Currentshowchild = child;
 Startanim (currentshowchild, position);
 }
}

SOURCE Download: Http://xiazai.jb51.net/201611/yuanma/AndroidRadarScan (jb51.net). rar

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.