ปีใหม่กำลังจะมาถึงและซองจดหมายสีแดงไม่มีที่สิ้นสุด เมื่อฉันคว้าซองจดหมายสีแดงฉันบังเอิญค้นพบว่าอินเทอร์เฟซถุงโชคดีของ Baidu นั้นค่อนข้างดีดังนั้นฉันจึงใช้เวลาในการเขียนบทความเพื่อทำอินเทอร์เฟซซองจดหมายสีแดง Baidu
แน่นอนว่านี่เป็นเวอร์ชันวิวัฒนาการของอินเทอร์เฟซปลดล็อค อย่างไรก็ตามมันมีจุดความรู้ค่อนข้างมาก เขียนโพสต์บล็อกเพื่อบันทึกและดูว่ามีประเด็นทางเทคนิคที่เฉพาะเจาะจงใดบ้าง ตรวจสอบการเรนเดอร์ของ Baidu:
1. แนวคิดการเขียนโปรแกรม
เมื่อมองไปที่อินเทอร์เฟซมันไม่ยากที่จะพบว่ามันเป็นภาชนะที่วางภาพเก้าภาพ การวาดภาพสามารถสร้างมุมมองที่โปร่งใสอื่นได้และรับผิดชอบการวาดเส้นและวงกลม ต่อไปเราจะแนะนำกระบวนการดำเนินการ
1. ViewGroup ที่กำหนดเอง
เรารู้ว่า ViewGroup ที่กำหนดเองจะต้องใช้วิธี onlayout () วิธีนี้เรียกว่าเมื่อตั้งค่าตำแหน่งและขนาดของมุมมองย่อย นอกจากนี้ยังมีวิธีการ onmeasure () ซึ่งวัดมุมมองและเนื้อหาเพื่อกำหนดความกว้างและความสูงของมุมมอง
㈡จัดตำแหน่งตำแหน่งของจุดและวงกลมและพารามิเตอร์การวาดภาพ
เมื่อกลับไปที่อินเทอร์เฟซเนื้อหาของอินเทอร์เฟซการวาดภาพสุดท้ายจะไม่ถูกบันทึก จะต้องเก็บไว้ในกรณีที่มีการวาดซ้ำไปยังอินเทอร์เฟซ
animation ซูมซูม
㈣การกำหนดมุมมองการใช้งานอินเทอร์เฟซการใช้งาน
㈤เมื่อการวาดเสร็จสมบูรณ์ให้ล้างเนื้อหาการวาดอินเทอร์เฟซและตรวจสอบให้แน่ใจว่าไม่ได้เชื่อมต่อรูปภาพที่ซ้ำกัน
เราจะทำตามขั้นตอนเหล่านี้ด้านล่าง
2. ปรับแต่ง ViewGroup
งานเริ่มต้นคือการแจกจ่ายภาพเก้าภาพให้กับตำแหน่งของรูปภาพอย่างสม่ำเสมอและแสดงในอินเทอร์เฟซโทรศัพท์มือถือ รหัสมีดังนี้:
ชั้นเรียนสาธารณะ LyjviewGroup ขยาย ViewGroup ดำเนินการ lyjesturedrawline.onanimationCallback {/*** ความกว้างของแต่ละจุด*/ส่วนตัว int childwidth;/**** บริบท*/บริบทส่วนตัว;/**** ที่ตั้งของจุดภาพ*/รายการส่วนตัว <lyjgesturepoint> */Private Lyjestureview GearDrawline ส่วนตัว int basenum = 5; lyjviewgroup สาธารณะ (บริบทบริบท) {super (บริบท); this.context = บริบท; this.list = new ArrayList <> (); บริบท) .getWindowManager (). getDefaultDisplay (). getMetrics (เมตริก); childWidth = metric.widthPixels / 3; // ความกว้างของหน้าจอ (พิกเซล) addChild (); // เริ่มต้นการดู avyeredrawline ที่สามารถวาดเส้น = ใหม่ lyjgestureview (บริบท, รายการ); gesturedrawline.setanimationcallback (นี่);} โมฆะสาธารณะ setParentView (ViewGroup Parent) บริบท) .getWindowManager (). getDefaultDisplay (). getMetrics (เมตริก); int width = metric.widthPixels; layoutparams layoutparams = layoutparams ใหม่ (ความกว้าง, ความกว้าง); this.setlayoutparams (layoutparams); gesturedrawline.setlayoutparams (layoutparams); parent.addview (นี่); parent.addview GetChildCount (); basenum);}}@overrideprotected void onmeasure (int widthmeasurespec, ความสูง int) {super.onmeasure (widthmeasurespec, heightmeasurespec); // traversal ตั้งค่าขนาดของเด็กแต่ละคนสำหรับ (int i = 0; v. การวัด (WidthMeasuresPec, ความสูงความเป็นไปได้);}} โมฆะส่วนตัว addchild () {สำหรับ (int i = 0; i <9; i ++) {imageView image = imageView ใหม่ (บริบท); image.setBackgroundresource คอลัมน์ = i % 3; // กำหนดพิกัดของมุมบนซ้ายและมุมขวาล่างของจุด int leftx = คอลัมน์ * childwidth + childwidth / basenum; int topy = rowspan * childwidth + childwidth / basenum; / basenum; lyjgesturepoint p = ใหม่ lyjgesturepoint (ซ้าย, topy, rightx, bottomy, i); this.list.add (p);}}@overridepublic startanimationimage (int i) {อนิเมชั่นอนิเมชั่น = แอนิเมชั่น r.anim.gridlayout_child_scale_anim); getchildat (i). startanimation (ภาพเคลื่อนไหว);}}3. ปรับแต่งคลาสคะแนน
ตามชื่อที่แนะนำมันคือการได้รับแอตทริบิวต์ที่เกี่ยวข้องของจุดซึ่งพิกัดของมุมบนซ้ายของภาพแอตทริบิวต์พื้นฐานและพิกัดของมุมล่างขวาของภาพคำนวณตำแหน่งกึ่งกลางของภาพเพื่อให้ได้จุดกึ่งกลางของภาพ เครื่องหมายสถานะระบุว่าจุดนั้นถูกดึงไปยังรูปภาพหรือไม่ นี่คือชั้นเรียนทางกายภาพ:
ชั้นเรียนสาธารณะ lyjgesturepoint {point point pointlefttop; // มุมบนซ้ายพิกัดจุดส่วนตัว pointrightbottom; // มุมล่างขวาพิกัดส่วนตัว int centerx; // จุดศูนย์ภาพ x จุดประสานงานส่วนตัว PointState;} โมฆะสาธารณะ setPointState (int pointState) {this.pointState = pointState;} จุดสาธารณะ getPointLeftTop () {return pointlefttop;} จุดสาธารณะ getPoinTrightBottom () {กลับ pointrightbottom; จุด (ซ้าย, บน); this.pointrightbottom = จุดใหม่ (ขวา, ล่าง); this.num = i;} public int getCenterx () {this.centerx = (this.pointlefttop.x+this.pointrightbottom.x)/2; return centerx; {this.centery = (this.pointlefttop.y+this.pointrightbottom.y)/2; return centery;}}4. ชั้นเรียนวงกลมที่กำหนดเอง
คลาสนี้ง่ายกว่าและมีสามคุณสมบัติ (พิกัดและรัศมีของจุดกึ่งกลางของวงกลม) รหัสมีดังนี้:
ชั้นเรียนสาธารณะ lyjcirclepoint {private int roundx; // วงกลมศูนย์จุด x ประสานงานส่วนตัว int roundy; // วงกลมศูนย์จุด y ประสานงานส่วนตัว int radiu; // รัศมีวงกลมสาธารณะ int public int getradiu () {return radiu;} public int getRoundx () {return roundx; radiu) {this.roundx = roundx; this.roundy = roundy; this.radiu = radiu;}}5. ใช้มุมมองคลาสการวาดแบบกำหนดเอง
รหัสมีดังนี้:
ชั้นเรียนสาธารณะ Lyjestureview ขยาย Android.view.View {/**** ประกาศเส้นตรงแปรง*/สีส่วนตัว/สีส่วนตัว;/**** ประกาศแปรงวงกลม*/Circlepaint สีส่วนตัว;/**** Canvas*/Private Canvas Canvas;/**** บิต รายการ <lyjgesturepoint> รายการ;/**** บันทึกบรรทัดที่วาด*/รายการส่วนตัว <pair <lyjgesturepoint, lyjesturepoint >> linelist;/**** บันทึกวงกลมที่วาด*/รายการส่วนตัว <lyjcirclepoint> circlepoints;/*** AnimationCallback; อินเทอร์เฟซสาธารณะ onAnimationCallback {โมฆะสาธารณะ startanimationImage (int i);} โมฆะสาธารณะ setAnimationCallback (onAnimationCallback animationCallback) {this.AnimationCallback = AnimationCallback;} Lyjestureview สาธารณะ รายการ) {super (บริบท); log.i (getClass (). getName (), "gesturedRawline"); สี = สีใหม่ (สี (paint.dither_flag); // สร้าง brush circlePaint = สีใหม่ displaymetrics (); (บริบท) (กิจกรรม)) .getWindowManager (). getDefaultDisplay (). getMetrics (เมตริก); log.i (getClass (). getName (), "WidthPixels" + Metric.widthPixels); log.i (getClass () Bitmap.CreateBitMap (Metric.widthPixels, Metric.HeightPixels, Bitmap.config.argb_8888); // ตั้งค่าความกว้างและความสูงของ Bitmap Canvas = New Canvas (); Canvas.SetBitMap (บิตแมป); paint.setStyle (paint.style.stroke); // ตั้งค่าสีที่ไม่ใช่การเติมสี Paint.setantialias (true); // ไม่แสดง jagged circlepaint.setstyle (paint.style.fill); Circlepaint.setstrokewidth (1); circlepaint.setantialias (จริง); circlepaint.setcolor (color.rgb (245, 142, 33); arrayList <> (); this.circlepoints = new ArrayList <> ();}@overridepublic Boolean OnTouchEvent (เหตุการณ์ MotionEvent) {switch (event.get.getAction ()) {case motionEvent.Action_down: // กำหนดจุดคลิกปัจจุบัน NULL) {CurrentPoint.SetPointState (ค่าคงที่ POINT_STATE_SELECTED); this.animationCallback.startanimationImage (currentpoint.getNum ()); canvas.drawcircle (currentpoint.getcenterx (), currentpoint.getcentery (), 20, circlepaint); circlepoints.add (ใหม่ lyjcirclepoint MotionEvent.Action_Move: ClearScreenandDrawlist (); // รับจุดที่ตำแหน่งการเคลื่อนที่ในปัจจุบันคือ lyjgesturepoint pointat = getPointat ((int) event.getx (), (int) event.gety ()); ถ้า (currentboint == null && pointat == null) {// กดนิ้วบนหน้าจอ หากจุดสิ้นสุดและจุดเริ่มต้นไม่ใช่รูปภาพให้ส่งคืนจริง}} else {// หมายความว่านิ้วของผู้ใช้ถูกย้ายไปยังจุดถ้า (currentpoint == null) {// ก่อนกำหนดว่าจุดปัจจุบันเป็น null // ถ้ามันว่างเปล่าแล้วกำหนดจุดที่คุณย้ายไปยังจุดปัจจุบัน CurrentPoint.SetPointState (ค่าคงที่. propte_state_selected);}} // ถ้าจุดที่คุณย้ายไปไม่ใช่พื้นที่ภาพหรือย้ายไปยังสถานที่ของคุณเองหรือภาพถูกเลือกแล้วเพียงวาดเส้นตรงถ้า (pointat == null || currentpoint.equals (pointat) pointat.getPointState ()) {canvas.drawcircle (currentpoint.getCenterx (), currentpoint.getCentery (), 20, circlepaint); circlepoint.add (ใหม่ lyjcirclepoint Event.getx (), event.gety (), สี);} else {// วาดเส้นตรงสองเส้นในสถานการณ์อื่น ๆ บันทึกวงกลมวาดและเส้นตรงและเรียกภาพเคลื่อนไหวซูมของภาพที่กด Canvas.drawcircle (Pointat.getCenterx () Pointat.getCentery (), 20)); this.AnimationCallback.StartanimationImage (pointat.getNum ()); pointat.set.setPointState (ค่าคงที่. point_state_selected); Canvas.Drawline lyjgesturepoint> pair = คู่ใหม่ <> (currentpoint, pointat); linelist.add (pair); currentpoint = pointat; // ตั้งค่าจุดที่เลือกไปยังจุดปัจจุบัน } unvalidate (); // repaint break; case motionEvent.Action_up: ClearScreenandDrawlist (); // ป้องกันเส้นพิเศษที่ไม่มีจุดสิ้นสุดใหม่ตัวจัดการใหม่ (). postdelayed (ใหม่ Clearlinerunnable (), 1000); // ล้างการวาดภาพ เป็นโมฆะ Run () {// ล้างคอลเลกชันของจุดบันทึกและวงกลม linelist.clear (); circlePoints.clear (); // re-draw the interface clearscreenanddrawlist (); สำหรับ (lyjgesturepoint p: list) {// ตั้งค่าให้เริ่มต้นสถานะที่ไม่ได้เลือก p.setpointstate (ค่าคงที่ propte_state_normal);} impoalidate ();}}/*** ผ่านตำแหน่งจุดไปที่คอลเลกชันเพื่อค้นหาจุดนี้ คะแนน*/ส่วนตัว lyjesturepoint getpointat (int x, int y) {สำหรับ (lyjgesturepoint point: รายการ) {// ก่อนกำหนดว่าจุดนั้นอยู่ในพิกัด x ของภาพ intletx = point.get.getLeftTop () x> x> x> ในการเปรียบเทียบครั้งต่อไปดำเนินการต่อ;} // ในการตัดสินว่าจุดอยู่ในพิกัด y ของรูปภาพ int topy = point.getpointlefttop (). y; int ottrogy = point.get.getPoinTrightBottom () y; ถ้า (y> = topy && y <จุดต่ำสุด) กำลังเดินทางไปยังจุด จุดส่งคืน;} ส่งคืน null;}/*** ล้างบรรทัดทั้งหมดบนหน้าจอจากนั้นวาดเส้นในคอลเลกชัน*/โมฆะส่วนตัว ClearscreenandDrawlist () {canvas.drawcolor (color.transparent, porterduff.mode.clear); สำหรับ (คู่ <lyjgesturepoint, lyjgesturepoint> pair: linelist) {canvas.drawline (pair.first.getcenterx (), pair.first.getcentery (), pair.second.getcenterx () CirclePoints) {canvas.drawcircle (lyjcirclepoint.getRoundx (), lyjcirclepoint.getRoundy (), lyjcirclepoint.getradiu (), circlepaint); {canvas.drawbitmap (bitmap, 0, 0, null);}}วิธีนี้คุณจะได้รับเอฟเฟกต์อินเทอร์เฟซต่อไปนี้ (แน่นอนว่าการถอดรหัสกระเป๋าเงิน Baidu ไม่มีภาพในกระเป๋าเงิน Baidu ดังนั้นคุณต้องหาภาพสุ่ม):