Tahun Baru akan datang, dan amplop merah tidak ada habisnya. Ketika saya meraih amplop merah, saya secara tidak sengaja menemukan bahwa antarmuka tas keberuntungan Baidu cukup baik, jadi saya meluangkan waktu untuk menulis artikel untuk menyelesaikan antarmuka amplop merah Baidu.
Tentu saja, ini sebenarnya adalah versi evolusi dari antarmuka buka kunci. Namun, ini mengandung cukup banyak poin pengetahuan. Tulis posting blog untuk merekamnya dan melihat poin teknis spesifik apa yang ada. Lihat rendering Baidu:
1. Ide Pemrograman
Melihat antarmuka, tidak sulit untuk menemukan bahwa itu adalah wadah yang menempatkan sembilan gambar. Menggambar sebenarnya dapat membuat tampilan transparan lain di atasnya dan bertanggung jawab untuk menggambar garis dan lingkaran. Selanjutnya kami akan memperkenalkan proses implementasi.
1. Kelompok View Kustom
Kami tahu bahwa ViewGroup khusus harus mengimplementasikan metode onlayout (). Metode ini dipanggil saat mengatur posisi dan ukuran subview. Ada juga metode onMeasure (), yang mengukur tampilan dan isinya untuk menentukan lebar dan tinggi tampilan.
㈡Storing posisi titik dan lingkarannya dan parameter menggambar
Saat kembali ke antarmuka, konten antarmuka gambar terakhir tidak akan disimpan. Itu harus disimpan dalam hal menggambar ulang untuk menarik ke antarmuka
Animasi zoom sederhana
㈣Mustom melihat antarmuka gambar implementasi
㈤ Ketika gambar selesai, hapus konten menggambar antarmuka dan pastikan bahwa gambar duplikat tidak terhubung.
Kami akan menyelesaikan langkah -langkah ini di bawah ini.
2. Kustomisasi viewgroup
Tugas awal adalah mendistribusikan sembilan gambar secara merata ke lokasi gambar dan menampilkannya di antarmuka ponsel. Kodenya adalah sebagai berikut:
public class LYJViewGroup extends ViewGroup implements LYJGestureDrawline.OnAnimationCallback{/*** Width of each point area*/private int childWidth;/**** Context*/private Context context;/**** Location of the image point*/private List<LYJGesturePoint> list;/**** Create a view to be above the ViewGroup. */private lyjgestureview geardrawline; private int basenum = 5; public lyjviewGroup (konteks konteks) {super (konteks); this.context = konteks; this.list = new arraylist <> (); displaymetrics metric = new displaymetrics (); (aktivitas) konteks) .getWindowManager (). getDefaultDisplay (). getMetrics (metric); childwidth = metric.widthpixels / 3; // Screen width (pixels) addChild();// Initialize a viewgestureDrawline that can draw lines = new LYJGestureView(context, list);gestureDrawline.setAnimationCallback(this);}public void setParentView(ViewGroup parent){// Get the width of the screen DisplayMetrics metric = new DisplayMetrics();((Activity) konteks) .getWindowManager (). getDefaultDisplay (). getMetrics (metric); int width = metric.widthpixels; layoutparams layoutparams = tata letak baru (lebar, lebar); this.setLayoutParams (layoutparams); gesturedrawline.setlayoutparams (layoutparams); parent.addview (this); parent.addview (gesturedrawline);}@overrideprotected void onlayout (boolean berubah, int l, int, int, r, roid {boolean diubah, int l, int, int, r, r, r) {boolean diubah, int l, int, int, r, int, int, int, int, int, int, int, int, int, int, int, int, int l, int, int, int l, int, int, int l, int, int, int l, int, int, int l, int, int, int l, int, int l, int, int, int l, int, int l, int, int, int l, int, int, int l, int, int l, int, int, getChildCount (); i ++) {// Baris apa rowspan = i /3; // kolom int kolom apa = i % 3; android.view.view v = getChildat (i); v.layout (colom * childwidth /childwidth /basenum, balap basenum);}}@overrideprotected void onMeasure (int widthMeasureSpec, int heightmeasureSpec) {super.onMeasure (widthMeaseSpec, heightmeasurespec); // set traversal ukuran setiap anak untuk (int i = 0; i <getchildcount (); getChildat (i); v.measure (widthmeasureSpec, heightmeasureSpec);}} private void addChild () {for (int i = 0; i <9; i ++) {imageview gambar = ImageView baru (konteks); gambar.mageBackroundReSource (r.drawable.marker); this. i / 3;// Which column int column = i % 3;// Define the coordinates of the upper left and lower right corners of the point int leftX = column * childWidth + childWidth / baseNum;int topY = rowspan * childWidth + childWidth / baseNum;int rightX = column * childWidth + childWidth - childWidth / baseNum;int bottomY = rowspan * childWidth + Childwidth - Childwidth / Basenum; lyjgesturePoint p = new lyjgesturePoint (leftx, topy, rightx, bottomy, i); this.list.add (p);}}@overridepublic startanimationimage (int i) {animation animation = animation.LoadAmation (animation.LoadEblic (animation-loadiMation (animationseAmation (animationseAmation (animationseAmation (animationseAmation (animationSeAmation (animationseAmation (animationSeAmation (animationseAmation (animationseAmation (animationseAmation (animationseAmation (animationseAmation (animation. R.anim.gridlayout_child_scale_anim); getchildat (i) .startanimation (animasi);}}3. Kustomisasi kelas titik
Seperti namanya, ini adalah untuk mendapatkan atribut yang relevan dari titik, di antaranya koordinat sudut kiri atas gambar atribut dasar dan koordinat sudut kanan bawah gambar, hitung posisi tengah gambar untuk mendapatkan titik tengah gambar. Tanda status menunjukkan apakah titik tersebut ditarik ke gambar. Inilah kelas fisiknya:
kelas publik lyjgesturePoint {point pointlefttop; // sudut kiri atas mengoordinasikan titik pribadi pointrightbottom; // sudut kanan bawah koordinat private int centerx; // poin pusat gambar x koordinat inter private int centery; // poin center y coordinate private int pointState;/apakah gambar diklik int private int num; public int getnum () {public POINTOPE () {POINTOP PUBLICE PUBLIC; pointState;} public void setPointState (int pointState) {this.pointState = pointState;} public point getPointlefttop () {return pointlefttop;} point point getPointtrightBottom () {return pointrighbottom;} public lyjgest esturePoint (int left, int top, intion, pointrighbottom;} public lyjgest esturePoint (int left, int top, intion, intion, intion, intion, intion, intion, int Top, int Top, int Top, Int Top, int Top, Int Top, Int Top, Int Top, Int Top, Int Top, Int Top, Int Top, Int Top, Int Top, Int Top, Int Top, int Point (kiri, atas); this.pointtrightbottom = titik baru (kanan, bawah); this.num = i;} int getCenterx publik () {this.centerx = (this.pointlefttop.x+this.pointrightbottom.x)/2; centerx return;} public int getConsery () {this.centery = (this.pointlefttop.y+this.pointrightbottom.y)/2; return centery;}}4. Kelas Lingkaran Kustom
Kelas ini lebih sederhana dan memiliki tiga properti (koordinat dan jari -jari titik tengah lingkaran). Kodenya adalah sebagai berikut:
kelas publik lyjcirclePoint {private int roundx; // circle center point x mengoordinasikan int roundy pribadi; // circle center point y mengoordinasikan radiu int private; // lingkaran radius publik getradiu () {return radiu;} public int getroundx () {return roundx;} public int getRoundy () {round roundy () {return roundx;} public int getRoundy () {return roundy; radiu) {this.roundx = roundx; this.roundy = roundy; this.radiu = radiu;}}5. Menerapkan tampilan kelas gambar khusus
Kodenya adalah sebagai berikut:
Kelas Publik Lyjgestureview memperluas android.view.view {/**** Deklarasikan kuas garis lurus*/cat cat pribadi;/**** Deklarasikan kuas lingkaran*/Private Paint CirclePaint;/**** Canvas*/Private Canvas Canvas;/**** Bitmap*/Private Bitmap BitMap;/**** Koleksi setiap koleksi Bitmap* Daftar <LyjgesturePoint> Daftar;/**** Catat garis yang ditarik*/Daftar pribadi <pasangan <lyjgesturepoint, lyjgesturepoint >> linelist;/**** Circle yang ditarik*/daftar pribadi <lyjcirclepoint> circlepoints;/*** Titik mana yang saat ini ada di*/private lyjgestlePoint> circlepoint; AnimationCallback; Antarmuka Publik OnAnimationCallback {public void startanimationImage (int i);} public void setanimationCallback (onanimationCallback animationCallback) {this.animationCallback = animationCallback;} public lyjgestureView (konteks konteks, daftar <lyjback <animationcallback; Daftar) {super (konteks); log.i (getClass (). getName (), "gesturedrawline"); cat = cat baru (cat.dither_flag); // Buat sikat lingkaran = cat baru (cat.dither_flag); DisplayMetrics metric = new DisplayMetrics (); ((aktivitas) konteks) .getWindowManager (). GetDefaultDisplay (). GetMetrics (metric); log.i (getClass (). GetName (), "widthpixels" + metric.widthpixels); log.i (getClass (). GetName (), "highelspixels); log.i (getClass (). GetName ()," highelspixels); log.i (getClass (). Bitmap.createBitMap (metric.widthpixels, metric.heightpixels, bitmap.config.argb_8888); // Atur lebar dan tinggi kanvas bitmap = canvas baru (); canvas.setBitmap (bitmap); cat.setstyle (cat.style.stroke); // atur cat non-pengisian.setstrokewidth (20); // pena width 20 piksel cat.setcolor (color.rgb (20);// pena lebar 20 piksel cat.setcolor (color.rgb (20);/ pikse piksel 20 piksel.setcolor (color.rgb (20); 14.2) PENTSTH 20 piksel cat.setColor (color.rgb (20); 14.2) PENTSTH 20 piksel cat.setColor (color.rgb (20); 14.2) PENTSTH 20 piksel cat.setColor (color.rgb (20); Paint.setantialias (true); // tidak ditampilkan Jagged CirclePaint.setstyle (cat ArrayList <> (); this.circlePoints = new arraylist <> ();}@overridepublic boolean ontouchevent (event motionEvent) {switch (event.getaction ()) {case motionEvent.action_down: // menentukan titik mana klik saat ini ada di current curer null) {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.getCenterY(),20));}invalidate();break;case MotionEvent.Action_move: clearscreenanddrawlist (); // dapatkan titik di mana posisi bergerak saat ini adalah lyjgesturepoint pointat = getpointat ((int) event.getx (), (int) event.gety ()); if (currentpoint == null && pointat == null) {// tekan jari Anda ke layar untuk itu. Jika titik akhir dan titik awal bukan gambar, kembalikan true;} else {// itu berarti bahwa jari pengguna dipindahkan ke titik jika (Currentpoint == null) {// Tentukan apakah titik saat ini adalah nol // jika kosong, maka tetapkan titik yang Anda pindahkan ke currentPointCurrentpoint = pointat; // Tetapkan titik saat ini untuk memilih negara; currentpoint.setPointState (constants.point_state_selected);}} // Jika titik yang Anda pindahkan bukanlah area gambar atau pindah ke tempat Anda sendiri, atau gambar sudah dipilih, cukup gambar garis lurus jika (pointat == null || currentpoint.equals (pointat) || constants.point_state_selected == pointAt.getPointState()){canvas.drawCircle(currentPoint.getCenterX(), currentPoint.getCenterY(), 20, circlePaint);circlePoint.add(new LYJCirclePoint(currentPoint.getCenterX(), currentPoint.getCenterY(), 20));canvas.drawLine(currentPoint.getCenterX(), currentPoint.getCenterY(), event.getX(), event.getY(), paint);}else{//Draw two straight lines in other situations, save the drawing circle and the straight line, and call the zoom animation of the picture pressed canvas.drawCircle(pointAt.getCenterX(), pointAt.getCenterY(), 20,circlePaint);circlePoints.add(new LYJCirclePoint(pointAt.getCenterX(), pointAt.getCenterY(), 20));this.animationCallback.startAnimationImage(pointAt.getNum());pointAt.setPointState(Constants.POINT_STATE_SELECTED);canvas.drawLine(currentPoint.getCenterX(), currentPoint.getCenterY(), pointAt.getCenterX(), pointAt.getCenterY(), cat); pair <lyjgesturePoint, lyjgesturePoint> pair = pasangan baru <> (titik saat ini, pointat); linelist.add (pair); currentpoint = pointat; // atur titik yang dipilih ke titik saat ini. } Invalidate (); // Catatan ulang break; case motionEvent.Action_up: clearscreenanddrawlist (); // mencegah garis tambahan tanpa titik akhir handler baru (). Postdelayed (clearlinernable baru; 1000); // clear interface setelah 1 detik dibatalkan (); // robekan ulang; {public void run () {// Hapus koleksi titik penyimpanan dan lingkaran linelist.clear (); circlePoints.clear (); // recute antarmuka clearscreenanddrawlist (); untuk (lyjgesturePoint p: list) {// atur untuk menginisialisasi status p.setPointState (constants.point_state_normal) yang tidak dipilih);} Invalidate ();}}/*** Melalui posisi titik ke titik yang tidak ada poin yang tidak ada yang termasuk dalam hal ini, yang tidak termasuk dalam hal ini, yang tidak termasuk dalam hal ini, yang tidak termasuk noal, yang tidak termasuk dalam hal ini, tidak ada poin, yang tidak termasuk dalam poin mana yang tidak termasuk dalam poin mana yang tidak termasuk dalam poin mana yang tidak termasuk dalam poin mana yang tidak ada di poin ini. Poin*/private lyjgesturePoint getPointat (int x, int y) {for (lyjgesturePoint point: list) {// Tentukan pertama apakah titik tersebut dalam koordinat x gambar int leftx = point.getPointlefttop (). x; int rightx = point.getpointrightbottom (). Untuk perbandingan berikutnya, lanjutkan;} // dalam penilaian apakah titik tersebut dalam koordinat y gambar int topy = point.getPointlefttop (). melintasi ke intinya. Point point;} return null;}/*** Hapus semua baris di layar, lalu gambarkan garis dalam koleksi*/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);}} // menggambar kanvas yang dibuat dengan bitmap @overrideProtected ondrawrawor ondrawrawien ondrawenicted ondrawrawor ondrawien ondrawien ondrawen {canvas.drawbitmap (bitmap, 0, 0, null);}}Dengan cara ini Anda bisa mendapatkan efek antarmuka berikut (tentu saja, mendekompilasi dompet Baidu, tidak ada gambar di dompet Baidu, jadi Anda harus menemukan gambar acak):