最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android仿百度福袋紅包界面

 更新時(shí)間:2016年02月03日 11:44:49   作者:Git_Android  
過(guò)年了,紅包來(lái)襲,紅包是怎么來(lái)的大家知道嗎?這篇文章主要介紹了Android仿百度福袋紅包界面,感興趣的小伙伴們可以參考一下

首先來(lái)看一下效果圖:

1.編程思路

看看界面,不難發(fā)現(xiàn),其就是一個(gè)放入九張圖片的容器,繪制其實(shí)可以在其上面另創(chuàng)建一個(gè)透明View負(fù)責(zé)繪制線與圓圈。下面我們將介紹一下實(shí)現(xiàn)過(guò)程。

㈠自定義ViewGroup

我們知道,自定義ViewGroup一定需要實(shí)現(xiàn)其onLayout()方法。該方法是設(shè)置子View位置與尺寸的時(shí)候調(diào)用。還有一個(gè)onMeasure()方法,該方法是測(cè)量view及其內(nèi)容來(lái)確定view的寬度和高度。

㈡存儲(chǔ)其點(diǎn)與圓的位置及繪制參數(shù)

當(dāng)重回界面的時(shí)候,是不會(huì)保存上一次繪制界面的內(nèi)容,必須存儲(chǔ)以備重繪時(shí)候繪制到界面

㈢簡(jiǎn)單的縮放動(dòng)畫

㈣自定義View實(shí)現(xiàn)繪制界面

㈤繪制完成時(shí),清除界面繪制內(nèi)容,并且保證不連接重復(fù)圖片

下面我們將完成這些步驟。

2.自定義ViewGroup

開始的任務(wù)就是將九張圖片平均分布到圖片的位置,顯示在手機(jī)界面中。其代碼如下:

public class LYJViewGroup extends ViewGroup implements LYJGestureDrawline.OnAnimationCallback{
  /**
   * 每個(gè)點(diǎn)區(qū)域的寬度
   */
  private int childWidth;
  /***
   * 上下文
   */
  private Context context;
  /***
   * 保存圖片點(diǎn)的位置
   */
  private List<LYJGesturePoint> list;
  /***
   * 創(chuàng)建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();
    // 初始化一個(gè)可以畫線的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);
    // 遍歷設(shè)置每個(gè)子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;
      // 定義點(diǎn)的左上角與右下角的坐標(biāo)
      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.自定義點(diǎn)類

顧名思義,就是為了獲取點(diǎn)的相關(guān)的屬性,其中基礎(chǔ)屬性圖片左上角坐標(biāo)與右下角坐標(biāo),計(jì)算圖片中心位置以便獲取圖片中心點(diǎn)。狀態(tài)標(biāo)記,表示該點(diǎn)是否繪制到圖片。下面是其實(shí)體類:

public class LYJGesturePoint {
  private Point pointLeftTop;//左上角坐標(biāo)
  private Point pointRightBottom;//右下角坐標(biāo)
  private int centerX;//圖片中心點(diǎn)X坐標(biāo)
  private int centerY;//圖片中心點(diǎn)Y坐標(biāo)
  private int pointState;//是否點(diǎn)擊了該圖片

  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.自定義圓類

這個(gè)類較簡(jiǎn)單就三個(gè)屬性而已(圓中心點(diǎn)坐標(biāo)及半徑),代碼如下:

public class LYJCirclePoint {
  private int roundX;//圓中心點(diǎn)X坐標(biāo)
  private int roundY;//圓中心點(diǎn)Y坐標(biāo)
  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.實(shí)現(xiàn)自定義繪制類View

代碼如下:

public class LYJGestureView extends android.view.View {
  /***
   * 聲明直線畫筆
   */
  private Paint paint;
  /***
   * 聲明圓圈畫筆
   */
  private Paint circlePaint;
  /***
   * 畫布
   */
  private Canvas canvas;
  /***
   * 位圖
   */
  private Bitmap bitmap;
  /***
   * 裝有各個(gè)view坐標(biāo)的集合,用于判斷點(diǎn)是否在其中
   */
  private List<LYJGesturePoint> list;
  /***
   * 記錄畫過(guò)的線
   */
  private List<Pair<LYJGesturePoint, LYJGesturePoint>> lineList;
  /***
   * 記錄畫過(guò)的圓
   */
  private List<LYJCirclePoint> circlePoints;
  /**
   * 手指當(dāng)前在哪個(gè)Point內(nèi)
   */
  private LYJGesturePoint currentPoint;
  /***
   * 手指按下動(dòng)畫
   */
  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);// 創(chuàng)建一個(gè)畫筆
    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); // 設(shè)置位圖的寬高
    canvas = new Canvas();
    canvas.setBitmap(bitmap);
    paint.setStyle(Paint.Style.STROKE);// 設(shè)置非填充
    paint.setStrokeWidth(20);// 筆寬20像素
    paint.setColor(Color.rgb(245, 142, 33));// 設(shè)置默認(rèn)連線顏色
    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:
        // 判斷當(dāng)前點(diǎn)擊的位置是處于哪個(gè)點(diǎn)之內(nèi)
        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();
        // 得到當(dāng)前移動(dòng)位置是處于哪個(gè)點(diǎn)內(nèi)
        LYJGesturePoint pointAt = getPointAt((int) event.getX(), (int) event.getY());
        if (currentPoint == null && pointAt == null) {//你把手指按在屏幕滑動(dòng),如果終點(diǎn)與起點(diǎn)都不圖片那么返回
          return true;
        } else {// 代表用戶的手指移動(dòng)到了點(diǎn)上
          if (currentPoint == null) {// 先判斷當(dāng)前的point是不是為null
            // 如果為空,那么把手指移動(dòng)到的點(diǎn)賦值給currentPoint
            currentPoint = pointAt;
            // 把currentPoint這個(gè)點(diǎn)設(shè)置選中狀態(tài);
            currentPoint.setPointState(Constants.POINT_STATE_SELECTED);
          }
        }
        //如果移動(dòng)到的點(diǎn)不為圖片區(qū)域或者移動(dòng)到自己的地方,或者該圖片已經(jīng)為選中狀態(tài),直接畫直線就可以了
        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{//其他情況畫兩點(diǎn)相連直線,并且保存繪制圓與直線,并調(diào)用按下圖片的縮放動(dòng)畫
          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;//設(shè)置選中點(diǎn)為當(dāng)前點(diǎn)。
        }
        invalidate();//重繪
        break;
      case MotionEvent.ACTION_UP:
        clearScreenAndDrawList();//防止多出一條沒有終點(diǎn)的直線
        new Handler().postDelayed(new clearLineRunnable(), 1000);//1秒后清空繪制界面
        invalidate();//重繪
        break;
      default:
        break;
    }
    return true;
  }

  class clearLineRunnable implements Runnable {
    public void run() {
      // 清空保存點(diǎn)與圓的集合
      lineList.clear();
      circlePoints.clear();
      // 重新繪制界面
      clearScreenAndDrawList();
      for (LYJGesturePoint p : list) {
        //設(shè)置其為初始化不選中狀態(tài)
        p.setPointState(Constants.POINT_STATE_NORMAL);
      }
      invalidate();
    }
  }

  /**
   * 通過(guò)點(diǎn)的位置去集合里面查找這個(gè)點(diǎn)是包含在哪個(gè)Point里面的
   *
   * @param x
   * @param y
   * @return 如果沒有找到,則返回null,代表用戶當(dāng)前移動(dòng)的地方屬于點(diǎn)與點(diǎn)之間
   */
  private LYJGesturePoint getPointAt(int x, int y) {

    for (LYJGesturePoint point : list) {
      // 先判斷點(diǎn)是否在圖片的X坐標(biāo)內(nèi)
      int leftX = point.getPointLeftTop().x;
      int rightX = point.getPointRightBottom().x;
      if (!(x >= leftX && x < rightX)) {
        // 如果為假,則跳到下一個(gè)對(duì)比
        continue;
      }
      //在判斷點(diǎn)是否在圖片的Y坐標(biāo)內(nèi)
      int topY = point.getPointLeftTop().y;
      int bottomY = point.getPointRightBottom().y;
      if (!(y >= topY && y < bottomY)) {
        // 如果為假,則跳到下一個(gè)對(duì)比
        continue;
      }

      // 如果執(zhí)行到這,那么說(shuō)明當(dāng)前點(diǎn)擊的點(diǎn)的位置在遍歷到點(diǎn)的位置這個(gè)地方
      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創(chuàng)建出來(lái)的畫布
  @Override
  protected void onDraw(Canvas canvas) {
    canvas.drawBitmap(bitmap, 0, 0, null);
  }
}

這樣就可以得到如下界面效果(當(dāng)然反編譯百度錢包,并沒有百度錢包中的圖片,只好隨便找了一張圖片):

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家學(xué)習(xí)Android有所幫助。

相關(guān)文章

  • Android仿google now效果的呼吸按鈕

    Android仿google now效果的呼吸按鈕

    這篇文章主要為大家詳細(xì)介紹了Android仿google now效果的呼吸按鈕簡(jiǎn)單實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • Android 自定義圖片地圖坐標(biāo)功能的實(shí)現(xiàn)

    Android 自定義圖片地圖坐標(biāo)功能的實(shí)現(xiàn)

    最近項(xiàng)目要求實(shí)現(xiàn)一個(gè)在自定義地圖圖片上添加坐標(biāo)信息的功能,類似于在圖片做標(biāo)注的功能,這種功能糾結(jié)該如何實(shí)現(xiàn)呢?下面小編通過(guò)實(shí)例代碼給大家介紹Android 自定義地圖的實(shí)現(xiàn),需要的朋友參考下吧
    2021-07-07
  • Android ShareSDK快速實(shí)現(xiàn)分享功能

    Android ShareSDK快速實(shí)現(xiàn)分享功能

    這篇文章主要介紹了Android ShareSDK快速實(shí)現(xiàn)分享功能的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • Android Studio去除界面默認(rèn)標(biāo)題欄的方法

    Android Studio去除界面默認(rèn)標(biāo)題欄的方法

    這篇文章主要介紹了Android Studio去除界面默認(rèn)標(biāo)題欄的方法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2007-09-09
  • Android style的繼承方式 點(diǎn)(.)和parent詳解及實(shí)例

    Android style的繼承方式 點(diǎn)(.)和parent詳解及實(shí)例

    這篇文章主要介紹了Android style的繼承方式 點(diǎn)(.)和parent詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • Android入門教程之創(chuàng)建樣式與主題

    Android入門教程之創(chuàng)建樣式與主題

    通過(guò)這篇文章你將學(xué)到如何創(chuàng)建自定義的樣式和主題,并且你還能學(xué)到如何使用Android Studio的工具和快捷方式來(lái)加快樣式的創(chuàng)建。下面來(lái)一起看看吧。
    2016-08-08
  • Android的簡(jiǎn)單前后端交互(okHttp+springboot+mysql)

    Android的簡(jiǎn)單前后端交互(okHttp+springboot+mysql)

    這篇文章主要介紹了Android的簡(jiǎn)單前后端交互(okHttp+springboot+mysql),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 2013年 移動(dòng)App設(shè)計(jì)13項(xiàng)注意細(xì)節(jié)總結(jié)

    2013年 移動(dòng)App設(shè)計(jì)13項(xiàng)注意細(xì)節(jié)總結(jié)

    在過(guò)去的一年里,移動(dòng)成主流也讓眾多的移動(dòng)應(yīng)用如雨后春筍般層出不窮,在眾多開發(fā)者從中獲利的同時(shí)競(jìng)爭(zhēng)也愈演愈烈,如何才能保證自己立于不敗之地接下來(lái)介紹移動(dòng)App設(shè)計(jì)的13大精髓感興趣的朋友可以了解下啊
    2013-01-01
  • Android SQLite數(shù)據(jù)庫(kù)增刪改查操作的使用詳解

    Android SQLite數(shù)據(jù)庫(kù)增刪改查操作的使用詳解

    本篇文章介紹了,在Android中SQLite數(shù)據(jù)庫(kù)增刪改查操作的使用詳解。需要的朋友參考下
    2013-04-04
  • Android自定義控件實(shí)現(xiàn)方向盤效果

    Android自定義控件實(shí)現(xiàn)方向盤效果

    這篇文章主要為大家詳細(xì)介紹了Android自定義控件實(shí)現(xiàn)方向盤效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04

最新評(píng)論

嘉定区| 静海县| 砚山县| 淳安县| 福鼎市| 虞城县| 桂平市| 同江市| 历史| 腾冲县| 虞城县| 晋城| 米林县| 象州县| 苍南县| 曲松县| 呼玛县| 陕西省| 岳阳市| 大厂| 蓬莱市| 武功县| 浮山县| 蓬溪县| 双城市| 沾化县| 天水市| 临邑县| 清远市| 嘉黎县| 府谷县| 裕民县| 隆德县| 南皮县| 清河县| 大同县| 镇江市| 淅川县| 濮阳县| 马鞍山市| 越西县|