새해가 다가오고 있으며 빨간 봉투는 끝이 없습니다. 빨간 봉투를 잡고있을 때, 나는 실수로 바이두의 행운의 가방 인터페이스가 꽤 좋다는 것을 발견했기 때문에 Baidu Red Envelope 인터페이스를 완성하기 위해 기사를 작성하는 데 시간이 걸렸습니다.
물론 이것은 실제로 잠금 해제 인터페이스의 진화 버전입니다. 그러나 그것은 많은 지식 포인트를 포함합니다. 블로그 게시물을 작성하여 기록하고 특정 기술 포인트가 무엇인지 확인하십시오. 바이두의 렌더링을 확인하십시오.
1. 프로그래밍 아이디어
인터페이스를 보면 9 장의 사진을 넣는 컨테이너라는 것을 찾기가 어렵지 않습니다. 드로잉은 실제로 다른 투명한 뷰를 만들 수 있으며 선과 원을 그리는 일을 담당합니다. 다음으로 구현 프로세스를 소개합니다.
1. 사용자 정의 뷰 그룹
Custom ViewGroup은 OnLayout () 메소드를 구현해야한다는 것을 알고 있습니다. 이 방법은 하위 뷰의 위치와 크기를 설정할 때 호출됩니다. 또한 뷰의 너비와 높이를 결정하기 위해보기와 내용을 측정하는 onmeasure () 메소드도 있습니다.
㈡ 지점과 원의 위치를 정리하고 매개 변수를 그리기
인터페이스로 돌아갈 때 마지막 드로잉 인터페이스의 내용은 저장되지 않습니다. 인터페이스에 그리기 위해 다시 그리기의 경우 저장해야합니다.
simple 줌 애니메이션
custom보기 구현 도면 인터페이스
drawing 드로잉이 완료되면 인터페이스 도면 내용을 지우고 중복 사진이 연결되지 않도록하십시오.
아래 단계를 완료 할 것입니다.
2. ViewGroup을 사용자 정의합니다
초기 작업은 9 개의 사진을 사진의 위치에 균등하게 배포하고 휴대폰 인터페이스에 표시하는 것입니다. 코드는 다음과 같습니다.
공개 클래스 lyjviewgroup은 viewGroup을 확장합니다. lyJgesturedRawline.onAnimationCallback {/*** 각 지점 영역의 너비*/private int childwidth;/**** 컨텍스트*/개인 컨텍스트 컨텍스트;/**** 이미지 포인트의 위치*/private list <lyjgesturepoint> 목록;/****보기 위에서보기 위반하십시오. */private lyjgestureview gearDrawline; private int basenum = 5; public lyjviewgroup (context context) {super (context); this.context = context; this.list = new arrayList <> (); displayMetrics metric = new displayMetrics (); (활동) context) .getWindowManager (). getDefaultDisplay (). getMetrics (metric); childwidth = metric.widthpixels / 3; // 스크린 너비 (픽셀) addChild (); // lines = new lyjgestureview (context, list); gesturedRawline.setAnimationCallback (} public void setParentView (viewGroup Parent) {// 새로운 디스플레이 메트릭의 Width를 얻는다. context) .getWindowManager (). getDefaultDisplay (). getMetrics (metric); int width = metric.widthpixels; layoutparams layoutparams = 새로운 LayoutParams (너비, width); this.setlayoutparams (layoutparams); gesturedRawline.setlayoutparams (layoutparams); parent.addview (this); parent.addview (gesturedRawline);}@reverideprotected void onlayout (boolean changed, int l, int t, int t, int b) {for (int i = 0; getChildCount (); i ++) {// row int rowspan = i /3; // hall int int int int in int column = i % 3; android.view.view v = getchildat (i); v.layout (childwidth + childwidth /rowspan * childwidth + childwidth /column * Basenum);}}@OverrideProtected void onmeasure (int widthmeasurespec, int heightmeasurespec) {super.onmeasure (widthmeasurespec, reightmeasurespec); // 트래버스는 각 자식의 크기를 설정합니다 (int i = 0; i <getchildcount (); i ++) {getchilat (i); v. 측정 (widthmeasurespec, heightmeasurespec);}} private void addChild () {for (int i = 0; i <9; i ++) {imageView image = new ImageView (context); image.setBackgroundResource (r.drawable.marker); this.addview (inmate); // who who who who who who who who whate intr rowsource (r.drawable.marker); int column = i % 3; // 지점의 왼쪽 및 하단 오른쪽 코너의 좌표를 정의합니다 int leftx = column * childwidth + childwidth / basenum; int topy = rowspan * childwidth + childwidth / basenum; int rightx = 컬럼 * childwidth + childwidth- childwidth - rowspan * rowspan * / basenum; lyjgesturepoint p = new lyjgesturepoint (왼쪽, topy, rightx, bottomy, i); this.list.add (p);}}@atriadepublic void startAnimationImage (int i) {animation animation = animationutils.loadAnimation (getContext (), r.anim.gridlayout_child_scale_anim); getchildat (i) .Startanimation (애니메이션);}}3. 포인트 클래스를 사용자 정의하십시오
이름에서 알 수 있듯이, 기본 속성 그림의 왼쪽 상단 모서리의 좌표와 그림의 오른쪽 하단 모서리의 좌표는 포인트의 관련 속성을 얻는 것입니다. 그림의 중심 위치를 계산하여 그림의 중심점을 얻습니다. 지점이 그림에 그려져 있는지 여부를 나타내는 상태 표시. 실제 수업은 다음과 같습니다.
공개 클래스 lyjgesturepoint {private point pointlefttop; // private 왼쪽 코너 좌표 private point pointrightbottom; // 오른쪽 코너 좌표 private int centerx; // 이미지 센터 포인트 x 좌표 private int centery; // 이미지 센터 포인트 y 이미지 int in int pointstate; // public int getn (public int getn) void setpointstate (int pointstate) {this.pointstate = pointstate;} public point getpointleftTop () {return pointleftTop;} public point getPoinTrightBottom () {return poinTrightBottom;} public lyjgesturepoint (int 왼쪽, int 상단, int int, int i) {this. this.wofftop = new. 포인트 (왼쪽, 상단); this.pointrightbottom = new Point (오른쪽, 하단); this.num = i;} public int getCenterx () {this.centerx = (this.pointlefttop.x+this.pointrightbottom.x)/2; public int getCenthery () {this.centery = (this.pointleftTop.y+this.pointrightbottom.y)/2; 반환 센터;}}}4. 커스텀 서클 클래스
이 클래스는 더 간단하며 세 가지 속성 (원의 중심 지점의 좌표 및 반경)이 있습니다. 코드는 다음과 같습니다.
공개 클래스 lyjcirclepoint {private int roundx; // circle center point x coordinate private int roundy; // circle center point y private int radiu; // circle radius public int getradiu () {return radiu;} public int getroundx () {return roundx;} public int getroundy () {return rounty;}, int rount. radiu) {this.roundx = roundx; this.roundy = roundy; this.radiu = radiu;}}5. 사용자 정의 도면 클래스보기를 구현하십시오
코드는 다음과 같습니다.
공개 클래스 lyjgestureview는 android.view.view {/**** 직선 브러시 선언*/개인 페인트 페인트;/**** 선언 서클 브러시*/개인 페인트 서클 팬*/개인 캔버스 캔버스;/**** 비트 맵*/private bitmap bitmap;/private bitmap bitmap;/**** 컬렉션의 컬렉션이 있는지 여부*/private lyspoint < 목록;/**** 그리기 라인을 녹음*/개인 목록 <lyjgesturepoint, lyjgesturepoint >> linelist;/**** 그리기 서클*/private list <lyjcirclepoint> circlepoints;/***는 현재*/private lyjgesturepoint currentpoint;/**** Press the AnanimationCallback Callback Callback Callback Callback Callback Callback Callback Callback Callback Callback Callback Callback; OnanimationCallback {public void startAnimationImage (int i);} public void setAnimationCallback (onanimationCallback AnimationCallback) {this.animationCallback = AnimationCallback;} public lyjgestureview (컨텍스트 컨텍스트, 목록 <lyjgesturepoint> list) {log.i (getclass ()). "gesturedRawline"); paint = new Paint (paint.dither_flag); // 브러시 circlePaint = new Paint (paint.dither_flag); displayMetrics metric = new DisplayMetrics (((활동) Context)) "widthPixels" + metric.widthPixels);Log.i(getClass().getName(), "heightPixels" + metric.heightPixels);bitmap = Bitmap.createBitmap(metric.widthPixels, metric.heightPixels, Bitmap.Config.ARGB_8888); // 비트 맵 캔버스의 너비와 높이를 설정하십시오. kanvas (); canvas.setbitmap (bitmap); Paint.SetStyle (Paint.Style.Stroke); // 설정 non-fill paint (20); // 펜 폭 20 픽셀 페인트 (245, 142, 33)); Paint.setantialias (true); // Jagged CirclePaint.SetStyle (Paint.Style.Fill); CirclePaint.SettrokeWidth (1); CirclePaint.Setantialias (True); CirclePaint.SetColor (Color.RGB (245, 142, 33)); this.list = NEW. LINERLIST = NEW. ArrayList <> (); this.circlePoints = new ArrayList <> ();}@atredgepublic boolean ontouchevent (motionEvent event) {switch (event.getAction ()) {case motionEvent.action_down : // 현재 클릭이 현재 포인트 = getPointat ((int) event.getx () null) {currentpoint.setpointstate (constants.point_state_select); this.animationCallback.StartAnimationImage (currentPoint.getNum ()); canvas.DrawCircle (currentPoint.getCenterx (), currentPoint.GetCentery (), 20, circlePaint); currentPoint.getCerclepoint () MotionEvent.action_move : clearscreenanddrawlist (); // 현재 이동 위치가 lyjgesturepoint pointat = getpointat ((int) event.getx (), (int) event.gety ())의 지점을 가져옵니다 (currentpoint == null && pointat == null) {// 스크린에서 손가락을 눌러 미끄러 져 들어갑니다. 종말점과 시작점이 그림이 아닌 경우 true;} else {// 사용자의 손가락이 지점으로 이동 함을 의미합니다. currentpoint.setpointstate (constants.point_state_selected);}} // // 이미지 영역이 아니거나 자신의 장소로 이동하지 않거나 이미지가 이미 선택된 경우 (pointat == null || currentpoint.equals (pointat) || constants.point_state_selected == 인 경우 직선을 그립니다. pointat.getPointState ()) {canvas.DrawCircle (currentPoint.getCenterx (), currentPoint.getCenceRy (), 20, CirclePaint); circlePoint.Add (new lyJcirclePoint (currentPoint.getCerx ()), currentsoint.getCentery ()) event.gety (), paint);} else {// 다른 상황에서 두 개의 직선을 그리고, 드로잉 원과 직선을 저장하고, 사진의 줌의 줌 애니메이션 (pointat.getCenterx (), pointat.getCentery (), 20, circlePoints.Adcld (pointAT.GetErccleppoint ()) 20)); this.animationCallback.StartAnimationImage (pointat.getnum ()); pointat.setpointstate (constants.point_state_selected); canvas.drawline (currentpoint.getCenterx (), currentPoint.getCentery (), pointat.getCenterx (), pointat.getTureTy (paint); pair <> (currentpoint, pointat); linelist.add (pair); currentpoint = pointat; // 선택한 지점을 현재 지점으로 설정합니다. } invalidate (); // Repaint break; case motionEvent.action_up : clareScreenAndDrawlist (); // 엔드 포인트가없는 추가 선 방지 새 핸들러 (). postDelayed (new ClearLinerUnnable (), 1000); // 1 초 안개 () 이후에 드로잉 인터페이스를 지우고있다. {public void run () {// 저장 포인트 및 원의 컬렉션을 지우고 linelist.clear (); circlePoints.clear (); // 인터페이스를 다시 드로 드로 이동하십시오. for (lyjgesturepoint p : list) {// 선택한 상태를 초기화하도록 설정하십시오. points*/private lyjgesturepoint getpointat (int x, int y) {for (lyjgesturepoint point : list) {// 먼저 포인트가 x 좌표의 x 좌표인지 결정 int leftx = point.getpointleftTop (). x; int rightx = point.getPoinTrightBottom (). 계속;} // 판단에서 판단에서 int topy = point.getpointleftTop (). return point;} return null;}/*** 화면의 모든 줄을 지우고 컬렉션에 선을 그립니다. for (pair <lyjgesturepoint, lyjgesturepoint> pair : linelist) {canvas.drawline (pair.first.getcenterx (), pair.first.getCencer (), second.getConcex (), pair.second.getCenceer (), Paint); // draw line} for (lyjcircleppoint) CirclePoints) {canvas.drawcircle (lyjcirclepoint.getroundx (), lyjcirclepoint.getroundy (), lyjcirclepoint.getradiu (), CirclePaint);}} // bitmap @overrideProt void ondraw (canvas) {canvas) {canvas. null);}}이렇게하면 다음과 같은 인터페이스 효과를 얻을 수 있습니다 (물론 바이두 지갑을 디 컴파일하면 바이두 지갑에는 사진이 없으므로 임의의 그림을 찾아야합니다).