模擬百度紅包福袋界面實例代碼。本站提示廣大學習愛好者:(模擬百度紅包福袋界面實例代碼)文章只能為提供參考,不一定能成為您想要的結果。以下是模擬百度紅包福袋界面實例代碼正文
新年到新年到,紅包搶一直。在我搶紅包的時刻不測的發明了百度的福袋界面挺不錯的,因而抽時光專門寫篇文章來完成百度紅包界面吧。
固然啦,這其實就是解鎖界面的退化版本。不外其包括的常識點照樣挺多的,寫篇博文記載一下看看詳細有哪些技巧點啦。看看百度的後果圖:
1.編程思緒
看看界面,不難發明,其就是一個放入九張圖片的容器,繪制其實可以在其下面另創立一個通明View擔任繪制線與圓圈。上面我們將引見一下完成進程。
㈠自界說ViewGroup
我們曉得,自界說ViewGroup必定須要完成其onLayout()辦法。該辦法是設置子View地位與尺寸的時刻挪用。還有一個onMeasure()辦法,該辦法是丈量view及其內容來肯定view的寬度和高度。
㈡存儲其點與圓的地位及繪制參數
當重回界面的時刻,是不會保留上一次繪制界面的內容,必需存儲以備重繪時刻繪制到界面
㈢簡略的縮放動畫
㈣自界說View完成繪制界面
㈤繪制完成時,消除界面繪制內容,而且包管不銜接反復圖片
上面我們將完成這些步調。
2.自界說ViewGroup
開端的義務就是將九張圖片均勻散布到圖片的地位,顯示在手機界面中。其代碼以下:
public class LYJViewGroup extends ViewGroup implements LYJGestureDrawline.OnAnimationCallback{ /** * 每一個點區域的寬度 */ private int childWidth; /*** * 高低文 */ private Context context; /*** * 保留圖片點的地位 */ private List<LYJGesturePoint> list; /*** * 創立view使其在ViewGroup之上。 */ private LYJGestureView gestureDrawline; private int baseNum = 5; public LYJViewGroup(Context context) { super(context); this.context = context; this.list = new ArrayList<>(); DisplayMetrics metric = new DisplayMetrics(); ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(metric); childWidth = metric.widthPixels / 3; // 屏幕寬度(像素) addChild(); // 初始化一個可以畫線的view gestureDrawline = new LYJGestureView(context, list); gestureDrawline.setAnimationCallback(this); } public void setParentView(ViewGroup parent){ // 獲得屏幕的寬度 DisplayMetrics metric = new DisplayMetrics(); ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(metric); int width = metric.widthPixels; LayoutParams layoutParams = new LayoutParams(width, width); this.setLayoutParams(layoutParams); gestureDrawline.setLayoutParams(layoutParams); parent.addView(this); parent.addView(gestureDrawline); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { for (int i = 0; i < getChildCount(); i++) { //第幾行 int rowspan = i / 3; //第幾列 int column = i % 3; android.view.View v = getChildAt(i); v.layout(column * childWidth + childWidth / baseNum, rowspan * childWidth + childWidth / baseNum, column * childWidth + childWidth - childWidth / baseNum, rowspan * childWidth + childWidth - childWidth / baseNum); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 遍歷設置每一個子view的年夜小 for (int i = 0; i < getChildCount(); i++) { View v = getChildAt(i); v.measure(widthMeasureSpec, heightMeasureSpec); } } private void addChild() { for (int i = 0; i < 9; i++) { ImageView image = new ImageView(context); image.setBackgroundResource(R.drawable.marker); this.addView(image); invalidate(); // 第幾行 int rowspan = i / 3; // 第幾列 int column = i % 3; // 界說點的左上角與右下角的坐標 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); } } @Override public void startAnimationImage(int i) { Animation animation= AnimationUtils.loadAnimation(getContext(), R.anim.gridlayout_child_scale_anim); getChildAt(i).startAnimation(animation); } }
3.自界說點類
望文生義,就是為了獲得點的相干的屬性,個中基本屬性圖片左上角坐標與右下角坐標,盤算圖片中間地位以便獲得圖片中間點。狀況標志,表現該點能否繪制到圖片。上面是其實體類:
public class LYJGesturePoint { private Point pointLeftTop;//左上角坐標 private Point pointRightBottom;//右下角坐標 private int centerX;//圖片中間點X坐標 private int centerY;//圖片中間點Y坐標 private int pointState;//能否點擊了該圖片 private int num; public int getNum() { return num; } public int getPointState() { return pointState; } public void setPointState(int pointState) { this.pointState = pointState; } public Point getPointLeftTop() { return pointLeftTop; } public Point getPointRightBottom() { return pointRightBottom; } public LYJGesturePoint(int left,int top,int right,int bottom,int i){ this.pointLeftTop=new Point(left,top); this.pointRightBottom=new Point(right,bottom); this.num=i; } public int getCenterX() { this.centerX=(this.pointLeftTop.x+this.pointRightBottom.x)/2; return centerX; } public int getCenterY() { this.centerY=(this.pointLeftTop.y+this.pointRightBottom.y)/2; return centerY; } }
4.自界說圓類
這個類較簡略就三個屬性罷了(圓中間點坐標及半徑),代碼以下:
public class LYJCirclePoint { private int roundX;//圓中間點X坐標 private int roundY;//圓中間點Y坐標 private int radiu;//圓半徑 public int getRadiu() { return radiu; } public int getRoundX() { return roundX; } public int getRoundY() { return roundY; } public LYJCirclePoint(int roundX,int roundY,int radiu){ this.roundX=roundX; this.roundY=roundY; this.radiu=radiu; } }
5.完成自界說繪制類View
代碼以下:
public class LYJGestureView extends android.view.View { /*** * 聲明直線畫筆 */ private Paint paint; /*** * 聲明圓圈畫筆 */ private Paint circlePaint; /*** * 畫布 */ private Canvas canvas; /*** * 位圖 */ private Bitmap bitmap; /*** * 裝有各個view坐標的聚集,用於斷定點能否在個中 */ private List<LYJGesturePoint> list; /*** * 記載畫過的線 */ private List<Pair<LYJGesturePoint, LYJGesturePoint>> lineList; /*** * 記載畫過的圓 */ private List<LYJCirclePoint> circlePoints; /** * 手指以後在哪一個Point內 */ private LYJGesturePoint currentPoint; /*** * 手指按下動畫 */ private OnAnimationCallback animationCallback; public interface OnAnimationCallback{ public void startAnimationImage(int i); } public void setAnimationCallback(OnAnimationCallback animationCallback) { this.animationCallback = animationCallback; } public LYJGestureView(Context context, List<LYJGesturePoint> list){ super(context); Log.i(getClass().getName(), "GestureDrawline"); paint = new Paint(Paint.DITHER_FLAG);// 創立一個畫筆 circlePaint=new Paint(Paint.DITHER_FLAG); DisplayMetrics metric = new DisplayMetrics(); ((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(metric); Log.i(getClass().getName(), "widthPixels" + metric.widthPixels); Log.i(getClass().getName(), "heightPixels" + metric.heightPixels); bitmap = Bitmap.createBitmap(metric.widthPixels, metric.heightPixels, Bitmap.Config.ARGB_8888); // 設置位圖的寬高 canvas = new Canvas(); canvas.setBitmap(bitmap); paint.setStyle(Paint.Style.STROKE);// 設置非填充 paint.setStrokeWidth(20);// 筆寬20像素 paint.setColor(Color.rgb(245, 142, 33));// 設置默許連線色彩 paint.setAntiAlias(true);// 不顯示鋸齒 circlePaint.setStyle(Paint.Style.FILL); circlePaint.setStrokeWidth(1); circlePaint.setAntiAlias(true); circlePaint.setColor(Color.rgb(245, 142, 33)); this.list = list; this.lineList = new ArrayList<>(); this.circlePoints=new ArrayList<>(); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: // 斷定以後點擊的地位是處於哪一個點以內 currentPoint = getPointAt((int) event.getX(), (int) event.getY()); if (currentPoint != 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(); // 獲得以後挪動地位是處於哪一個點內 LYJGesturePoint pointAt = getPointAt((int) event.getX(), (int) event.getY()); if (currentPoint == null && pointAt == null) {//你把手指按在屏幕滑動,假如起點與終點都不圖片那末前往 return true; } else {// 代表用戶的手指挪動到了點上 if (currentPoint == null) {// 先斷定以後的point是否是為null // 假如為空,那末把手指挪動到的點賦值給currentPoint currentPoint = pointAt; // 把currentPoint這個點設置選中狀況; currentPoint.setPointState(Constants.POINT_STATE_SELECTED); } } //假如挪動到的點不為圖片區域或許挪動到本身的處所,或許該圖片曾經為選中狀況,直接畫直線便可以了 if(pointAt == null || currentPoint.equals(pointAt) || Constants.POINT_STATE_SELECTED == pointAt.getPointState()){ canvas.drawCircle(currentPoint.getCenterX(), currentPoint.getCenterY(), 20, circlePaint); circlePoints.add(new LYJCirclePoint(currentPoint.getCenterX(), currentPoint.getCenterY(), 20)); canvas.drawLine(currentPoint.getCenterX(), currentPoint.getCenterY(), event.getX(), event.getY(), paint); }else{//其他情形畫兩點相連直線,而且保留繪制圓與直線,並挪用按下圖片的縮放動畫 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(), paint); Pair<LYJGesturePoint, LYJGesturePoint> pair = new Pair<>(currentPoint, pointAt); lineList.add(pair); currentPoint=pointAt;//設置選中點為以後點。 } invalidate();//重繪 break; case MotionEvent.ACTION_UP: clearScreenAndDrawList();//避免多出一條沒有起點的直線 new Handler().postDelayed(new clearLineRunnable(), 1000);//1秒後清空繪制界面 invalidate();//重繪 break; default: break; } return true; } class clearLineRunnable implements Runnable { public void run() { // 清空保留點與圓的聚集 lineList.clear(); circlePoints.clear(); // 從新繪制界面 clearScreenAndDrawList(); for (LYJGesturePoint p : list) { //設置其為初始化不選中狀況 p.setPointState(Constants.POINT_STATE_NORMAL); } invalidate(); } } /** * 經由過程點的地位去聚集外面查找這個點是包括在哪一個Point外面的 * * @param x * @param y * @return 假如沒有找到,則前往null,代表用戶以後挪動的處所屬於點與點之間 */ private LYJGesturePoint getPointAt(int x, int y) { for (LYJGesturePoint point : list) { // 先斷定點能否在圖片的X坐標內 int leftX = point.getPointLeftTop().x; int rightX = point.getPointRightBottom().x; if (!(x >= leftX && x < rightX)) { // 假如為假,則跳到下一個比較 continue; } //在斷定點能否在圖片的Y坐標內 int topY = point.getPointLeftTop().y; int bottomY = point.getPointRightBottom().y; if (!(y >= topY && y < bottomY)) { // 假如為假,則跳到下一個比較 continue; } // 假如履行到這,那末解釋以後點擊的點的地位在遍歷到點的地位這個處所 return point; } return null; } /** * 清失落屏幕上一切的線,然後畫出聚集外面的線 */ 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);// 畫線 } for(LYJCirclePoint lyjCirclePoint : circlePoints){ canvas.drawCircle(lyjCirclePoint.getRoundX(),lyjCirclePoint.getRoundY(), lyjCirclePoint.getRadiu(),circlePaint); } } //繪制用bitmap創立出來的畫布 @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(bitmap, 0, 0, null); } }
如許便可以獲得以下界面後果(固然反編譯百度錢包,並沒有百度錢包中的圖片,只好隨意找了一張圖片):