العام الجديد قادم ، والأظرف الحمراء لا حصر لها. عندما كنت أمسك الأظرف الحمراء ، اكتشفت بطريق الخطأ أن واجهة Baidu Lucky Bag جيدة جدًا ، لذلك أخذت الوقت الكافي لكتابة مقال لإكمال واجهة Baidu Red Envelope.
بالطبع ، هذا هو في الواقع نسخة تطورية من واجهة فتح. ومع ذلك ، فإنه يحتوي على الكثير من نقاط المعرفة. اكتب منشور مدونة لتسجيله ومعرفة النقاط الفنية المحددة الموجودة. تحقق من عروض بايدو:
1. أفكار البرمجة
بالنظر إلى الواجهة ، ليس من الصعب العثور على أنها حاوية تضع تسع صور. يمكن للرسم في الواقع إنشاء طريقة عرض شفافة أخرى عليها وهي مسؤولة عن رسم الخطوط والدوائر. بعد ذلك سنقدم عملية التنفيذ.
1
نحن نعلم أن مجموعة ViewGroup المخصصة يجب أن تنفذ طريقة OnLayout (). يتم استدعاء هذه الطريقة عند تعيين موضع وحجم الرؤية الفرعية. هناك أيضًا طريقة onMeasure () ، والتي تقيس العرض ومحتوياتها لتحديد عرض وارتفاع العرض.
㈡ تخزين مواقف نقاطها ودوائرها ومعلمات الرسم
عند العودة إلى الواجهة ، لن يتم حفظ محتوى واجهة الرسم الأخيرة. يجب تخزينها في حالة إعادة رسمها للرسوم إلى الواجهة
㈢simple Zoom الرسوم المتحركة
㈣ واجهة رسم تنفيذ العرض
㈤ عند اكتمال الرسم ، قم بمسح محتوى رسم الواجهة والتأكد من عدم توصيل الصور المكررة.
سنكمل هذه الخطوات أدناه.
2. تخصيص ViewGroup
تتمثل المهمة الأولية في توزيع الصور التسع بالتساوي على موقع الصور وعرضها في واجهة الهاتف المحمول. الرمز كما يلي:
الطبقة العامة LyjViewGroup يمتد عرض ViewGroup الأدوات lyjgesuredRawline.OnanimationCallback {/*** عرض كل منطقة نقطة*/private int childwidth ؛/**** سياق*/سياق السياق الخاص ؛/**** موقع نقطة الصورة*/قائمة خاصة <LyJgenpoint> قائمة ؛ قم بإنشاء عرض أعلاه. */private lyjgestureview geardrawline ؛ private int basenum = 5 ؛ public lyjviewgroup (سياق السياق) {super (context) ؛ this.context = context ؛ this.list = new ArrayList <> () Context) .getWindowManager (). // عرض الشاشة (وحدات البكسل) AddChild () ؛ // تهيئة lievegesturedrawline التي يمكن أن ترسم الخطوط = new lyjgestureview (السياق ، القائمة) Context) .getWindowManager (). العرض) ؛ this.setlayoutparams (layoutparams) ؛ gesturedrawline.setLayoutParams (layoutparams) ؛ parent.addview (this) ؛ parent.addview (gesturedRawline) ؛}@overrideprotected void onlayout ، int l ، int r ، i ++) {// ما هو الصف int rowspan = i /3 ؛ // ما هو عمود عمود int int = i ٪ 3 ؛ android.view.view v = getChildat (i) ؛ Basenum) ؛}}@@overrideprotected void onMeasure (int widthmeasurespec ، int QuiseMeasurespec) {super.onmeasure (widthmeasurespec ، heightmeasurespec) ؛ // traversal يحدد حجم كل طفل (int i = 0 ؛ getChildat (i) ؛ v.measure (widthmeasurespec ، heightmeasurespec) ؛}} private void addchild () {for (int i = 0 ؛ i <9 ؛ i ++) {imageView image = new ImageView (context) ؛ / 3 ؛ // أي عمود عمود int = i ٪ 3 ؛ // تحديد إحداثيات الزوايا اليمنى العلوية اليسرى والسفلية للنقطة int intx = العمود * childwidth + childwidth / basenum ؛ int topy = rowspan * childwidth + childwidth / baseNum ؛ int ildledth + ilderwidth + ilfildth - ilingwidth ؛ childwidth - childwidth / basenum ؛ lyjgesturepoint p = new lyjgesturepoint (Leftx ، topy ، rightx ، bottomy ، i) ؛ this.list.add (p) ؛}}@overridepublic void strendanimation (int i) r.anim.gridlayout_child_scale_anim) ؛ getchildat (i) .startanimation (الرسوم المتحركة) ؛}}3. تخصيص فئات النقطة
كما يوحي الاسم ، هو الحصول على السمات ذات الصلة للنقطة ، من بينها إحداثيات الزاوية اليسرى العليا من صورة السمة الأساسية وإحداثيات الزاوية اليمنى السفلى من الصورة ، وحساب الموضع المركزي للصورة للحصول على نقطة الوسط للصورة. علامة الحالة التي تشير إلى ما إذا كانت النقطة مرفوعة إلى الصورة. فيما يلي الطبقات المادية:
الطبقة العامة lyjgesturepoint {private point pointlefttop ؛ // الزاوية العلوية اليسرى تنسيق نقطة خاصة pointrightbottom ؛ // تنسيق الزاوية اليمنى السفلى centerx int centerx ؛ void setPointState (int pointState) {this.pointState = pointState ؛} public point getPointlefttop () {return pointlefttop ؛} public point getPoinTrightBottom () {return pointrightbottom ؛ نقطة (يسار ، أعلى) ؛ this.pointrightbottom = نقطة جديدة (يمين ، أسفل) ؛ this.num = i ؛} public int getCenterx () {this.centerx = (this.pointlefttop.x+this.pointrightbottom.x)/2 ؛ {this.centery = (this.pointlefttop.y+this.pointrightbottom.y)/2 ؛ return Centery ؛}}4. فئة الدائرة المخصصة
هذه الفئة أبسط ولها ثلاث خصائص (إحداثيات ونصف قطر النقطة المركزية للدائرة). الرمز كما يلي:
الطبقة العامة lyjcirclepoint {private int roundx ؛ // circle center point x تنسيق private int ratery ؛ // Circle Center Point y تنسيق private int radiu ؛ radiu) {this.RoundX = RoundX ؛ this.roundy = Roundy ؛ this.radiu = radiu ؛}}5. تنفيذ عرض فئة الرسم المخصص
الرمز كما يلي:
الطبقة العامة lyjgestureview يمتد Android.view.view {/**** إعلان فرشاة خط مستقيم*/Private Paint Paint ؛/**** Denare Circle Brush*/Private Paint CirclePaint ؛/**** canvas*/private canvas canvas ؛/**** نقطعة نقطعة النقطات ؛ قائمة <LyjgesturePoint> قائمة ؛/**** سجل الخطوط المرسومة*/القائمة الخاصة <pair <lyjgesturepoint ، lyjgesturepoint >> linelist ؛/**** سجل الدائرة المرسومة*/القائمة الخاصة <lyjcirclepoint> دائرة ؛ الرسوم المتحركة callback ؛ الواجهة العامة onAnimationCallback {public void startAnimationImage (int i) ؛} public void setAnimationCallback (onanimationCallback animationCallback) {this.animationCallback = AnimationCallback ؛} public lyjgestureview (سياق السياق ، list <lyjesture قائمة) {super (context) ؛ log.i (getClass (). DisplayMetrics () ؛ ((نشاط) سياق) .getWindowManager (). bitmap.createBitMap (metric.widthpixels ، metric.heightpixels ، bitmap.config.argb_8888) ؛ // قم بتعيين عرض وارتفاع قماش النقطة النقطية = canvas () ؛ canvas.setbitmap (bitmap) ؛ paint.setStyle (paint.style.stroke) ؛ // قم بتعيين paint. paint.setantialias (صواب) ؛ // لم يتم عرض دائرة circlepaint.setStyle (paint.style.fill) ؛ circlepaint.setstrokewidth (1) ؛ circlepaint.setantialias (true) ؛ circlepaint.setColor (color.rgb (245 ، 142 ، 33)) ؛ ArrayList <> () ؛ this.circlepoints = new ArrayList <> () ؛}@overridepublic boolean ontouchevent (حدث motionevent) {switch (event.getAction ()) {case motionevent.action_down: {currentPoint.setPointState (Constants.Point_State_Selected) ؛ this.animationCallback.StartAnimationImage (currentpoint.getnum ()) ؛ canvas.drawcircle (currentpoint.getCenterx () ، currentpoint.getCentery () ، 20 ، circlepaint) ؛ circlepoints.add (new lyjcirclepoint (currentpoint.getCenterx () ، currentpoint.getentery () ، 20) ؛ motionevent.action_move: clearscreenanddrawlist () ؛ // الحصول على النقطة التي يكون فيها الموضع المتحرك الحالي هو lyjgesturepoint pointat = getPointat ((int) event.getx () ، (int) event.gety ()) ؛ if (currentpoint == null && pointat == null) {// اضغط على إصبعك على الشاشة. إذا لم تكن نقطة النهاية ونقطة البداية هي الصورة ، فاحرص على ذلك ، currentPoint.setPointState (constants.point_state_selected) ؛}} // إذا كانت النقطة التي انتقلت إليها ليست منطقة الصورة أو تنتقل إلى مكانك الخاص ، أو تم تحديد الصورة بالفعل ، فقط ارسم خطًا مستقيمًا إذا (pointat == null || currentpoint.equals (pointat) pointat.getPointState ()) {canvas.drawcircle (currentpoint.getCenterx () ، currentpoint.getCentery () ، 20 ، circlepaint) ؛ circlepoint.add (new lyjcirclepoint event.getx () ، event.gety () ، paint) ؛} آخر {// ارسم خطين مستقيمين في حالات أخرى ، حفظ دائرة الرسم والخط المستقيم ، واستدعاء الرسوم المتحركة للتكبير للصورة canvas.drawcircle (pointat.getCenterx () ، pointat.getCentery () ، 20 ، circlepoint.add pointat.getCentery () ، 20)) ؛ this.animationCallback.StartAnimationImage (pointat.getnum ()) ؛ pointat.setPointState (constants.point_state_selected) ؛ canvas.drawline (currentpoint.getCenterx () ، pressuppoint.getCentery () pointat.getCenterx () lyjgesturepoint> pair = new pair <> (CurrentPoint ، pointat) ؛ linelist.add (pair) ؛ currentPoint = pointat ؛ // قم بتعيين النقطة المحددة إلى النقطة الحالية. } إبطال () ؛ // استراحة إعادة الطلاء ؛ case motionevent.action_up: clearscreenanddrawlist () ؛ // منع خطًا إضافيًا بدون نقطة نهاية معالج جديد. void run () {// مسح مجموعة نقاط حفظ ودوائر linelist.clear () ؛ circlepoints.clear () ؛ // إعادة سحب الواجهة clearscreenanddrawlist () ؛ لـ (lyjgesturepoint p: list) {// قم بتعيينه لتهيئة الحالة p.setPointState غير المنقولة (constants.point_state_normal) ؛} تبطل () ؛}}/*** من خلال موضع النقطة ، انتقل إلى المجموعة التي تابعها في مكان ما يتم تضمينه في المكان الذي يتم تضمينه في مكان ما في وضعه الحالي. النقاط*/private lyjgesturepoint getPointat (int x ، int y) {for (lyjgesturepoint point: list) {// أولاً حدد ما إذا كانت النقطة في إحداثيات x من الصورة int laydx = point.getPointlefttop (). تستمر المقارنة التالية ؛} // في الحكم ما إذا كانت النقطة في إحداثي y للصورة int topy = point.getPointleftTop (). اجتياز إلى هذه النقطة. return point ؛} return null ؛}/*** قم بمسح جميع الخطوط الموجودة على الشاشة ، ثم ارسم الخطوط الموجودة في المجموعة*/private clearscreenanddrawlist () {canvas.drawcolor (color.transparent ، porterduff.mode.clear) ؛ لـ (pair <lyjgesturepoint ، lyjgesturepoint> الزوج: linelist) {canvas.drawline (pair.first.getCenterx () ، pair.first.getCentery () ، pair.second.getCenterx () ، pair.second.getCentery () ، paint) ؛ CirclePoints) {canvas.drawcircle (lyjcirclepoint.getRoundX () ، lyjcirclepoint.getRoundy () ، lyjcirclepoint.getradiu () ، circlepaint) ؛ {canvas.drawbitmap (bitmap ، 0 ، 0 ، null) ؛}}وبهذه الطريقة ، يمكنك الحصول على تأثير الواجهة التالي (بالطبع ، إزالة محفظة Baidu ، لا توجد صورة في محفظة Baidu ، لذلك عليك العثور على صورة عشوائية):