Наступает Новый год, а красные конверты бесконечны. Когда я захватывал красные конверты, я случайно обнаружил, что интерфейс счастливой сумки Baidu довольно хорош, поэтому я потратил время, чтобы написать статью, чтобы завершить интерфейс Baidu Red Envelope.
Конечно, это на самом деле эволюционная версия интерфейса разблокировки. Тем не менее, он содержит довольно много знаний. Напишите сообщение в блоге, чтобы записать его и посмотреть, какие конкретные технические моменты есть. Проверьте визуализации Baidu:
1. Идеи программирования
Глядя на интерфейс, нетрудно обнаружить, что это контейнер, который размещает девять фотографий. Рисунок может на самом деле создать еще один прозрачный вид на него и отвечает за линии рисования и круги. Далее мы представим процесс реализации.
1. Пользовательская группа просмотра
Мы знаем, что пользовательская группа View Group должна реализовать свой метод onlayout (). Этот метод вызывается при установлении позиции и размера подвеса. Существует также метод Onmeasure (), который измеряет представление и его содержимое для определения ширины и высоты представления.
㈡ Установление позиций его точек и кругов и параметров рисования
При возврате к интерфейсу содержание последнего интерфейса чертежа не будет сохранено. Он должен храниться в случае перераспределения, чтобы привлечь к интерфейсу
Animation анимация Zoom Zoom
㈣custom View interface interface реализации чертежа
㈤ Когда чертеж завершен, очистите содержимое чертежа интерфейса и убедитесь, что дубликаты изображений не подключены.
Мы выполним эти шаги ниже.
2. Настроить группу View
Первоначальная задача состоит в том, чтобы равномерно распределить девять изображений в местоположение изображений и отобразить их в интерфейсе мобильного телефона. Код заключается в следующем:
Общедоступный класс LyjViewGroup Extends ViewGroup реализует lyjgestureudRawline.onamationCallback {/*** Ширина каждой точки*/private int childwidth;/**** контекст*/контекст частного контекста;/**** Местоположение изображения. */private lyjgestureview geardrawline; private int basenum = 5; public lyjviewgroup (контекст контекста) {super (context); this.context = context; this.list = new Arraylist <> (); Displaymetrics metric = new DisplayMetrics (); (Activity). GetDiNdowmanager (). getDefaultDisplay (); metric.widthpixels / 3; // ширина экрана (Pixels) addChild (); // Инициализировать viewSgeSgesureDRawline, который может рисовать Lines = new LyjGestureView (контекст, список); GestreadRawline.setAnimationCallback (это);} public void setParentView (viewgroup parent) {// Получить ширину экрана Metrics = new Displymetrics (); контекст) .getWindowManager (). getDefaultDisplay (). getMetrics (metric); int width = metric.widthpixels; layoutparams layoutparams = new Layoutparams (ширина, ширина); this.SetLayoutParams (LayoutParams); GestreadRawline.SetLayoutParams (LayoutParams); Parent.Addview (this); parent.addview (GestreadRawline);}@переопределенные заплаточные getChildCount (); basenum);}}@overrideproted void onmeasure (int widthmeaspecpec, int heightmeaspecpec) {super.onmeasure (widthmeaspec, heightmeaspecpec); // Traversal устанавливает размер вида ребенка для (int i = 0; i <getChildCount (); i ++) getChildat (i); v.measure (widthMeasUrespec, heightmeaspecpec);}} private void addChild () {for (int i = 0; i <9; i ++) {ImageView Image = new ImageView (context); Image.SetbackgroundResource (r.drawable.marker); = i / 3; // какой столбец int column = i % 3; // Определить координаты верхних левых и нижних углов правой точки int int leftx = column * childwidth + childwidth / basenum; int topy = rowsspan * Childwidth + Childwidth / basenum; int rightx = columnth * childwidth - Childwidth - Childwidth / basenum; int rightx = columnth * childwidth - Childwidth / basenum; childwidth - childwidth / basenum; lyjgesturepoint p = new lyjgesturepoint (левый, топ, правый, нижний, i); this.list.add (p);}}@overridepublic void startanimationImation (int i) {animation animation = animationlis.load (getContext () R.anim.gridlayout_child_scale_anim); getchildat (i) .startanimation (анимация);}}3. Настройка точечных классов
Как следует из названия, оно должно получить соответствующие атрибуты точки, среди которых координаты верхнего левого угла изображения базового атрибута и координат нижнего правого угла изображения, рассчитайте центральное положение изображения, чтобы получить центральную точку изображения. Марка состояния, указывающая, привлечена ли точка на картинке. Вот физические занятия:
открытый класс lyjgesturepoint {private point pointlefttop; // координат верхнего левого углу частной точки pointrightbottom; // Координата правого нижнего угла PointState;} public void setPointState (int pointState) {this.pointState = pointState;} public point getPointlefttop () {return pointtlefttop;} public point getPointrightBottom () {return pointrightbottom;} public lyjSturePoint (int int, int, int, int, int -ntempt {intptope {int protectom; Точка (слева, верх); this.pointrightbottom = new Point (справа, внизу); this.num = i;} public int getCenterx () {this.centerx = (this.pointlefttop.x+this.pointrightbottom.x)/2; return centrex;} public int getCenery () {this.centerery = (this.pointlefttop.y+this.pointrightbottom.y)/2; return Centery;}}4. Custom Circle Class
Этот класс проще и имеет три свойства (координаты и радиус центральной точки круга). Код заключается в следующем:
открытый класс LyjCirclePoint {private int int Roundx; // Circle Center Point x Координата private int int roundy; // Circle Center Point y Координата Private int radiu; // ruck radius public int getradiu () {return radiu;} public int getroundx () {return outrx;} public getRoundy () {return roundy;} public lyjcr radiu) {this.roundx = Roundx; this.roundy = roundy; this.radiu = radiu;}}5. Реализация пользовательского просмотра класса рисования.
Код заключается в следующем:
Общедоступный класс LyjStureView Extends Android.View.View {/**** Declate Pright Line Crash*/Private Paint Pait Список <lyjSturePoint> List;/**** Запишите линии Drawn*/Private List <pair <lyjgesturePoint, lyjesturePoint >> Linelist;/**** Запишите нарисованный кружок*/private <lyjcirclepoint> Circlepoints;/***, какой точка находится в данный момент в*/Private lyjesture currentPoint;/*** OnanimationCallback AnimationCallback; public interface onanimationCallback {public void startAnimationImation (int i);} public void setAnimationCallback (onAnimationCallback AnimationCallback) {this.AnimationCallback = animationCallback;} public lyjestureView (контекст, listJesturePaint;} public lyjestureView (контекст, listJesturePaint. Список) {super (context); log.i (getClass (). getName (), "gestreadRawline"); Paint = New Paint (paint.dither_flag); // Создать щетку Circlepaint = новая краска (Paint.dither_flag); Displaymetrics metric = new DisplayMetrics (); ((Activity) Context) .getWindowManager (). GetDefaultDisplay (). GetMetrics (metric); log.i (getClass (). GetName (), "widthpixels" + metric.widthpixels); log.i (getClass (). GetName () "hiestpixels" + metricLe.he -metricle. Bitmap.createbitmap (metric.widthpixels, metric.heightpixels, bitmap.config.argb_8888); // Установите ширину и высоту растрового карты Canvas = new Canvas (); Canvas.setbitmap (Bitmap); Paint.setStyle (Paint.Style.Stroke); // Установить не заполненную краску. Paint.setantialias (true); // не отображается jagged 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 (event motionevent) {switch (event.getAction ()) {case motionEvent.action_down: // определяет, какая точка текущего клика находится в текущей точке = getPointat (int) event.getx (), () vatury. null) {currentPoint.setPointState (constants.point_state_selected); this.animationCallback.StartAnimationImage (currentPoint.getNum ()); canvas.drawcircle (currentPoint.getCenterx (), currentPoint.getCentery (), 20, Circlepaint); Circlepoints.Add (новый Lyjcirclepoint (currentpoint.getCenterx (), currentPoint.getCentery (), 20));} Invalidate (); Break; Case motionEvent.action_move: clearScreenandDrawlist (); // Получить точку, где текущая движущаяся позиция является LyjSturePoint PointAt = getPointat (int) event.getX (), int). == null && pointat == null) {// Нажмите пальцем на экран, чтобы скользить его. Если конечная точка и начальная точка не являются изображением, верните true;} else {// это означает, что палец пользователя перемещается в точку, если (currentpoint == null) {// сначала определить, является ли текущая точка нулевой //, если она пуста, тогда назначьте точку, которую вы перенесли в CurrentPointCurrentPoint = pointat; // SET точка точки точки, чтобы выбирать состояние; currentPoint.SetPointState (constants.point_state_selected);}} // Если точка, в которую вы переехали, не является области изображения или перемещаться в свое место, или изображение уже выбрано, просто нарисуйте прямую линию if (pointat == null || currentpoint.equals (pointat) || pointat.getPointState ()) {canvas.drawcircle (currentPoint.getCenterx (), CurrentPoint.getCentery (), 20, Circlepaint); CirclePoint.Add (new LyjCirclePoint (currentPoint.getCenterx (), currentPoint.getCentery (), 20); canVas.drawne.DraWline (currentPoint.getCentery (), 20); currentPoint.getCenterery (), event.getx (), event.gety (), paint);} else {// нарисовать две прямые линии в других ситуациях, сохранить круг рисования и прямую линию и назовите анимацию Zoom нажатого изображения. Lyjcirclepoint (pointat.getCenterx (), pointat.getCentery (), 20)); this.animationCallback.StartAnimationImage (pointat.getNum ()); pointAt.setPointState (constants.point_State_Selected); canvas.drawline (currentPoint.getCenterx (), canccurePoint pointat.getCenterx (), pointat.getCentery (), paint); pair <lyjgesturepoint, lyjgesturepoint> pare = new pare <> (currentpoint, pointat); linelist.add (pare); currentpoint = pointat; // Установить выбранную точку в текущую точку. } Invalidate (); // Repaint Break; Case motionEvent.action_up: clearScreenandDrawlist (); // Предотвратить дополнительную строку без конечной точки New Handler (). Postdelayed (new clearlinerunnable (), 1000); // Очистить интерфейс рисования после 1 -й второй Invalidate (); // Repaint Break; Default: reformable; {public void run () {// Очистить сбор точек сохранения и кругов linelist.clear ();; circlepoints.clear (); // re-draw интерфейс clearscreenanddrawlist (); for (lyjgesturepoint p: list) {// Установить его для инициализации невыбранного состояния p.setpointstate (constants.point_state_normal);} Invalidate ();}}/*** через позицию точки, перейдите к коллекции, чтобы найти точку, что эта точка включена в ** @param x @param y* @return, который не нашел, что наоборот, который не нашел, что наоборот. Между точками*/private lyjgesturepoint getPointat (int x, int y) {for (lyjgesturepoint point: list) {// сначала определить, находится ли точка в координате x изображения int leftx = point.getpointlefttop (). x; int rightx = point.getPointright () x; x; Неверно, перейдите к следующему сравнению продолжить;} // в суждении, находится ли точка в координате y in picture int topy = point.getpointlefttop (). y; int bottomy = point.getpointrightbottom (). y; if (! (y> = topy && y <bottomy)) {// если неверно, скип к следующему сравнению; Нажатая точка проходит до точки зрения. Вернуть точку;} return null;}/*** Очистить все линии на экране, а затем нарисуйте линии в коллекции*/private void clearScreenDdrawlist () {canvas.drawcolor (color.transparent, porterduff.mode.clear); Для (pair <lyjgesturepoint, lyjgesturepoint> Пара: Linelist) {canvas.drawline (pair.first.getCenterx (), pair.first.getCentery (), pair.second.getCenterx (), pair.second.getCence (), paint); Sirclepoints) {canvas.drawcircle (lyjcirclepoint.getroundx (), lyjcirclepoint.getroundy (), lyjcirclepoint.getradiu (), Circlepaint);} // Нарисуйте канвас, созданный с битмапа {canvas.drawbitmap (растровый карта, 0, 0, null);}}Таким образом, вы можете получить следующий эффект интерфейса (конечно, декомпирование кошелька Baidu, в кошельке Baidu нет изображения, поэтому вам нужно найти случайную картину):