Neues Jahr kommt und rote Umschläge sind endlos. Als ich rote Umschläge packte, stellte ich versehentlich fest, dass Baidus Lucky Bag -Schnittstelle ziemlich gut ist. Deshalb nahm ich mir die Zeit, einen Artikel zu schreiben, um die Schnittstelle von Baidu Red Envelope zu vervollständigen.
Dies ist natürlich tatsächlich eine evolutionäre Version der Entsperr -Schnittstelle. Es enthält jedoch eine Menge Wissenspunkte. Schreiben Sie einen Blog -Beitrag, um ihn aufzuzeichnen und zu sehen, welche spezifischen technischen Punkte vorhanden sind. Schauen Sie sich Baidus Renderings an:
1. Programmierideen
Wenn man die Benutzeroberfläche betrachtet, ist es nicht schwer zu finden, dass es sich um einen Container handelt, der neun Bilder aufstellt. Das Zeichnen kann tatsächlich eine weitere transparente Ansicht darauf erzeugen und ist dafür verantwortlich, Linien und Kreise zu zeichnen. Als nächstes werden wir den Implementierungsprozess vorstellen.
1. Benutzerdefinierte Ansichtsgruppe
Wir wissen, dass benutzerdefinierte ViewGroup ihre OnLayout () -Methode implementieren muss. Diese Methode wird aufgerufen, wenn die Position und Größe der Unteransicht festgelegt wird. Es gibt auch eine OnMeasure () -Methode, die die Ansicht und ihren Inhalt misst, um die Breite und Höhe der Ansicht zu bestimmen.
㈡Storieren Sie die Positionen seiner Punkte und Kreise und Zeichnenparameter
Bei der Rückkehr zur Schnittstelle wird der Inhalt der letzten Zeichnungsschnittstelle nicht gespeichert. Es muss im Falle eines erneuten Schreises gespeichert werden, um an die Schnittstelle zu zeichnen
㈢Simple Zoom Animation
㈣Custom View Implementierungszeichnung Zeichnungsschnittstelle
㈤Wenn die Zeichnung abgeschlossen ist, löschen Sie den Interface -Zeichnungsinhalt und stellen Sie sicher, dass doppelte Bilder nicht verbunden sind.
Wir werden diese folgenden Schritte ausführen.
2. Passen Sie die ViewGroup an
Die erste Aufgabe besteht darin, die neun Bilder gleichmäßig an den Ort der Bilder zu verteilen und sie in der Handy -Schnittstelle anzuzeigen. Der Code ist wie folgt:
Public Class LyjviewGroup erweitert die ViewGroup implementiert lyjusturedrawline. */private lyjUngerview Geardrawline; private int basenum = 5; public lyjViewGroup (Kontextkontext) {Super (Kontext); this.context = context; this.list = new ArrayList <> (); DisplayMetrics metric = new displayMetrics (); (Aktivität) (Aktivität) (Aktivität) Kontext) .GetWindowManager (). getDefaultDisplay (). getMetrics (metric); childwidth = metric.widthpixel / 3; // Bildschirmbreite (Pixel) addChild (); // eine viewgestudedRawline initialisieren, die Linien zeichnen kann = Neue Lyjregieview (Kontext, Liste); GesteuredRawline.SetanimationCallback (this);} Public Void SetParentView (ViewGroup übergeordnet) {// Achtion. Kontext) .GetWindowManager (). getDefaultDisplay (). getMetrics (metric); int width = metric.widthpixel; layoutParams layoutParams = neue LayoutParams (Breite, width);this.setLayoutParams(layoutParams);gestureDrawline.setLayoutParams(layoutParams);parent.addView(this);parent.addView(gestureDrawline);}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {for (int i = 0; i < getChildCount (); Basisum);}}@Override formtected void on measure (int widthThomeSureSpec, int heightmeasurespec) {Super.onMeasure (widttheSeurespec, HeightmeasureSpec); // Traversal -Sets der Größe jeder Kinderansicht für (int i = 0; GetChildat (i); v.Measure (widthMeasurespec, heightmeasurespec);}} private void addChild () {für (int i = 0; i <9; i ++) {ImageView Image = new ImageView (Kontext); = i / 3; // Welche Spalte int Spalte = i % 3; // Definieren Sie die Koordinaten der oberen linken und unteren rechten Ecken des Punktes intx = Säule * Kinderbreite + Kinderbreite / Basis; int toppy = rowspan * Childwidth + childwidth / basenum; int rechts. Childwidth - Childwidth / Basisum; R.Anim.GridLayout_Child_Scale_anim); getChildat (i) .Startanimation (Animation);}}3.. Punktklassen anpassen
Wie der Name schon sagt, wird die relevanten Attribute des Punktes erhalten, darunter die Koordinaten der oberen linken Ecke des Grundattributbildes und die Koordinaten der unteren rechten Ecke des Bildes, berechnen Sie die mittlere Position des Bildes, um den Mittelpunkt des Bildes zu erhalten. Statusmarkierung angibt, ob der Punkt auf das Bild gezogen wird. Hier sind die physischen Klassen:
public class lyjUngerpoint {private pointlefttop; // obere linke Ecke Koordinate Private Point PoinTrightbottom; // RECHE RECHTE ECERORTINATE Private int Centerx; // Image Center Point X Koordinate privater Int -Zentren; // Image Center Point Y -Koordinate private Int Pointstate; // Ob das Bild klickte privat intum; void setPointState(int pointState) {this.pointState = pointState;}public Point getPointLeftTop() {return pointLeftTop;}public Point getPointRightBottom() {return pointRightBottom;}public LYJGesturePoint(int left,int top,int right,int bottom,int i){this.pointLeftTop=new Point(left,top);this.pointRightBottom=new Point(right,bottom);this.num=i;}public int getCenterX() {this.centerX=(this.pointLeftTop.x+this.pointRightBottom.x)/2;return centerX;}public int getCenterY() {this.centery = (this.pointlefttop.y+this.poinTrightBottom.y)/2; Rückkehrzentrum;}}4. Custom Circle Class
Diese Klasse ist einfacher und verfügt über drei Eigenschaften (Koordinaten und Radius des Mittelpunkts des Kreises). Der Code ist wie folgt:
public class lyjcirclepoint {private int Roundx; // Circle Center Punkt X Koordinate private int rundy; // Circle Center Point Y Koordinate private int radiu; // circle radius public int get GetRadiu () {return radiu;} public int get rroundx () {return RoundX; radiu) {this.roundX = RoundX; this.roundy = Roundy; this.radiu = radiu;}}5. Implementieren Sie benutzerdefinierte Zeichnungsklassenansicht
Der Code ist wie folgt:
Public Class LyjregeView erweitert Android.view.view {/**** DECLARE DECRARE -Pinsel*/Private Paint;/**** Kreispinsel*/private Farbkreis;/**** Canvas*/Private Canvas Canvas;/**** Bitmap*/privat Bitmap. Liste <lyjUngerpoint> list;/**** zeichnen Sie die gezeichneten Linien auf*/private Liste <pair <lyjrepurePoint, lyjgestePoint >> Linelist;/**** zeichnen Sie den gezeichneten Kreis auf*/private Liste <lyjcirclepoint> circlepoints;/***, der die Finger derzeit in*/private lyjverpointpoint current; AnimationCallback; öffentliche Schnittstelle OnanimationCallback {public void startanimationImage (int i);} public void setanimationCallback (OnanimationCallback AnimationCallback) {this.AnimationCallback = AnimationCallback; Liste) {Super (Kontext); log.i (getClass (). getName (), "GesteuredRawline"); Paint = new Paint (Paint.dither_flag); // Erstellen Sie einen Pinsel circlepaint = new Paint (Paint.dither_flag); DisplayMetrics metric = new DisplayMetrics (); ((Aktivität) Kontext) .GetWindowManager (). GetDefaultDisplay (). Bitmap.createbitmap (metric.widthpixels, metric.heightpixels, bitmap.config.argb_8888); // Setzen Sie die Breite und Höhe der Bitmap-Canvas = new canvas (); canvas.setbitmap (bitmap); paint.setStyle (Paint.Style.Stroke); // Nicht-Fill-Farbe einstellen. paint.setantialias (true); // nicht gezeigt zackig Circlepaint.setStyle (Paint.Style.Fill); Circlepaint.SetStrokewidth (1); Circlepaint.Setantialias (true); Circlepaint.setColor (color.rgb (245, 142, 33)); ArrayList <> (); this.circlePoints = new ArrayList <> ();}@oversidepublic boolean OnTouchEvent (motionEvent Ereignis) {Switch (Ereignis.GetAction ()) {case motionEvent.Action_down: // bestimmt, welcher Klick auf aktuelle Punkte ist. {CurrentPoint.SetPointState (constants.point_state_selected); this.AnimationCallback.StartanimationImage (currentPoint.getNum ()); canvas.drawcircle (currentPoint.getCenterx (), currentPoint.getCentery (), 20, Circlepaint); MotionEvent.action_move: clearscreenandDrawlist (); // Erhalten Sie den Punkt, an dem die aktuelle Bewegungsposition lyjgestePoint pointat = getPointat ((int) event.getX (), (int) event.gety ()); if (currentPoint == null && pointat == null) {// Drücken Sie Ihr Finger auf dem Bildschirm auf den Bildschirm auf, um es zu schieben. Wenn der Endpunkt und der Ausgangspunkt nicht das Bild sind, geben Sie True zurück;} else {// Dies bedeutet, dass der Finger des Benutzers auf den Punkt verschoben wird, wenn (currentPoint == null) {// zuerst bestimmen, ob der aktuelle Punkt null ist //, wenn es leer ist, dann weisen Sie den Punkt zu, an den Sie zu aktuellen Punkte -Punkte -Punkten wechseln. CurrentPoint.SetPointState (Constants.Point_State_Selected);}} // Wenn der Punkt, an den Sie sich verschoben haben, nicht der Bildbereich ist oder zu Ihrem eigenen Ort verschieben ist, oder das Bild bereits ausgewählt ist, zeichnen Sie einfach eine geradlinige Linie, wenn (pointat == null || currentPoint.equals (Pointat) || constants.point_State_Sected == == == == == == == == pointat.getPointState ()) {canvas.drawcircle (currentPoint.getCenterx (), currentPoint.getCentery (), 20, CirclePaint); CirclePoint.Add (neuer lyjcirclePoint (currentPoint.getCenterx (), currentCointCentery (), 20); Event.getX (), Event.gety (), Paint);} else {// Zeichnen Sie zwei gerade Linien in anderen Situationen, speichern Sie den Zeichnungskreis und die geraden Linie und rufen Sie die Zoomanimation des bildgedrückten Canvas.Drawcircle (pointat.getCenterx (), Pointatat.getCentery (), 20, 20, 20, circlepaint); pointat.getCentery (), 20)); this.AnimationCallback.StartanimationImage (pointat.getNum ()); pointat.SetPointState (constants.point_state_selected); canvas.drawline (currentPoint.getCenterx (), currentCointCentCentCentiony (), pointaT.GetRex (), pointcenter (), pointaT. Lyjreverpoint> pair = neues pair <> (currentPoint, pointat); linelist.add (pair); currentPoint = pointat; // Setzen Sie den ausgewählten Punkt auf den aktuellen Punkt. } Invalidate (); // Repaint Break; case motionEvent.action_Up: ClearscreenandDrawlist (); // eine zusätzliche Linie ohne Endpunkt neuer Handler (). run () {// die Sammlung von Save-Punkten und Kreisen löschen. Für (lyjregpoint p: list) {// Setzen Sie es, um den nicht ausgewählten Zustand P.SetPointState (Constants.Point_State_Normal) zu initialisieren;} Invalidate ();}}/*** Über die Punktposition gehen Punkte*/private lyjUngerpoint getPointat (int x, int y) {für (lyjUngerpoint point: list) {// Bestimmen Sie zuerst, ob sich der Punkt in der x -Koordinate des Bildes intL Leftx = point.getPointeftTop (). x; Nächster Vergleich weiter;} // im Urteil, ob der Punkt in der y -Koordinate des Bildes int topy = point.getPointlefttop (). Auf den Punkt gehen. Rückgabepunkt;} return null;}/*** Löschen Sie alle Zeilen auf dem Bildschirm und zeichnen Sie dann die Zeilen in der Sammlung*/private void clearscreenandDrawlist () {canvas.drawcolor (color.transparent, porterduff.mode.clear); for (Pair<LYJGesturePoint, LYJGesturePoint> pair : lineList) {canvas.drawLine(pair.first.getCenterX(), pair.first.getCenterY(), pair.second.getCenterX(), pair.second.getCenterY(), paint);// Draw Line}for(LYJCirclePoint lyjCirclePoint : CirclePoints) {canvas.drawcircle (lyjcirclepoint.getRoundx (), lyjcirclepoint.getRoundy (), lyjcirclepoint.getRadiu (), Circlepaint);}} // Zeichnen Sie die mit Bitmap @Overridepridected aufzeichneten Canvas -Canvas -Canvas -Canvas -Canvas) {canvas.drawbitmap (bitmap, 0, 0, null);}}Auf diese Weise können Sie den folgenden Schnittstelleneffekt erzielen (natürlich gibt es in Baidu -Brieftasche kein Bild in Baidu -Brieftasche, sodass Sie ein zufälliges Bild finden müssen):