激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Android - Android實現(xiàn)購物車添加商品動畫

Android實現(xiàn)購物車添加商品動畫

2022-03-07 14:59happy_horse Android

這篇文章主要為大家詳細介紹了Android實現(xiàn)購物車添加商品動畫,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了Android實現(xiàn)購物車添加商品動畫的具體代碼,供大家參考,具體內容如下

實現(xiàn)需求:

在商品列表頁面,從列表Item 添加商品的時候,需要一個動畫,仿佛是是往購物車里添加商品。

實現(xiàn)思路:

  1. 獲取起始點與終點的坐標,利用PathMeasure 繪制貝塞爾曲線;
  2. 為點擊的Item 商品View 設置屬性動畫;
  3. 監(jiān)聽屬性動畫的update,改變View 的坐標;

實現(xiàn)效果:

Android實現(xiàn)購物車添加商品動畫

實現(xiàn)中會用到 PathMeasure 類:

我們主要使用它兩個方法:

1、獲取長度:

?
1
2
3
4
5
6
7
/** //獲取弧線的總長度(周長)
   * Return the total length of the current contour, or 0 if no path is
   * associated with this measure object.
   */
  public float getLength() {
    return native_getLength(native_instance);//系統(tǒng)調用native 方法;
  }

2、獲取坐標:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
   * Pins distance to 0 <= distance <= getLength(), and then computes the
   * corresponding position and tangent. Returns false if there is no path,
   * or a zero-length path was specified, in which case position and tangent
   * are unchanged.
   *
   * @param distance The distance along the current contour to sample
   * @param pos If not null, eturns the sampled position (x==[0], y==[1])
   * @param tan If not null, returns the sampled tangent (x==[0], y==[1])
   * @return false if there was no path associated with this measure object
  */
  public boolean getPosTan(float distance, float pos[], float tan[]) {
    if (pos != null && pos.length < 2 ||
      tan != null && tan.length < 2) {
      throw new ArrayIndexOutOfBoundsException();
    }
    return native_getPosTan(native_instance, distance, pos, tan);
  }

方法 getPosTan(float distance, float pos[],float tan[]) - path 為 null ,返回 false
distance 為一個 0 - getLength() 之間的值,根據(jù)這個值 PathMeasure 會計算出當前點的坐標封裝到 pos 中。上面這句話我們可以這么來理解,不管實際 Path 多么的復雜,PathMeasure 都相當于做了一個事情,就是把 Path “拉直”,然后給了我們一個接口(getLength)告訴我們path的總長度,然后我們想要知道具體某一點的坐標,只需要用相對的distance去取即可,這樣就省去了自己用函數(shù)模擬path,然后計算獲取點坐標的過程。

代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
public class GoodsListActivity extends AppCompatActivity {
 
  private RelativeLayout mRootRl;
  private RecyclerView mGoodsRecyclerView;
  private ImageView mCarImageView;
  private TextView mCountTv;
 
  private List<Bitmap> mBitmapList = new ArrayList<>();
  private PathMeasure mPathMeasure;
  private float[] mCurrentPosition = new float[2];
  private int mCount = 0;
 
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_goods_list);
    initView();
    initData();
    GoodsAdapter goodsAdapter = new GoodsAdapter(mBitmapList);
    mGoodsRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    mGoodsRecyclerView.setAdapter(goodsAdapter);
  }
 
  private void initView(){
    mGoodsRecyclerView = (RecyclerView)findViewById(R.id.recyclerView);
    mCarImageView = (ImageView)findViewById(R.id.imageview_shop_car);
    mCountTv = (TextView)findViewById(R.id.tv_count);
    mRootRl = (RelativeLayout)findViewById(R.id.rl_root);
  }
 
  private void initData(){
    mBitmapList.add(BitmapFactory.decodeResource(getResources(), R.drawable.car));
    mBitmapList.add(BitmapFactory.decodeResource(getResources(), R.drawable.car));
    mBitmapList.add(BitmapFactory.decodeResource(getResources(), R.drawable.car));
  }
 
  class GoodsAdapter extends RecyclerView.Adapter<GoodsViewHolder>{
 
    private List<Bitmap> mData;
 
    public GoodsAdapter(List<Bitmap> data) {
      mData = data;
    }
 
    @Override
    public GoodsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
      View itemView = LayoutInflater.from(GoodsListActivity.this)
          .inflate(R.layout.rv_goods_item, parent, false);
      return new GoodsViewHolder(itemView);
    }
 
    @Override
    public void onBindViewHolder(final GoodsViewHolder holder, int position) {
      holder.ivGood.setImageBitmap(mData.get(position));
      holder.tvBuy.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          addGoodToCar(holder.ivGood);
        }
      });
    }
 
    @Override
    public int getItemCount() {
      return mData != null ? mData.size() : 0;
    }
  }
 
  private void addGoodToCar(ImageView imageView){
    final ImageView view = new ImageView(GoodsListActivity.this);
    view.setImageDrawable(imageView.getDrawable());
    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(100, 100);
    mRootRl.addView(view, layoutParams);
 
    //二、計算動畫開始/結束點的坐標的準備工作
    //得到父布局的起始點坐標(用于輔助計算動畫開始/結束時的點的坐標)
    int[] parentLoc = new int[2];
    mRootRl.getLocationInWindow(parentLoc);
 
    //得到商品圖片的坐標(用于計算動畫開始的坐標)
    int startLoc[] = new int[2];
    imageView.getLocationInWindow(startLoc);
 
    //得到購物車圖片的坐標(用于計算動畫結束后的坐標)
    int endLoc[] = new int[2];
    mCarImageView.getLocationInWindow(endLoc);
 
    float startX = startLoc[0] - parentLoc[0] + imageView.getWidth()/2;
    float startY = startLoc[1] - parentLoc[1] + imageView.getHeight()/2;
 
    //商品掉落后的終點坐標:購物車起始點-父布局起始點+購物車圖片的1/5
    float toX = endLoc[0] - parentLoc[0] + mCarImageView.getWidth() / 5;
    float toY = endLoc[1] - parentLoc[1];
 
    //開始繪制貝塞爾曲線
    Path path = new Path();
    path.moveTo(startX, startY);
    //使用二次薩貝爾曲線:注意第一個起始坐標越大,貝塞爾曲線的橫向距離就會越大,一般按照下面的式子取即可
    path.quadTo((startX + toX) / 2, startY, toX, toY);
    mPathMeasure = new PathMeasure(path, false);
 
    //屬性動畫
    ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, mPathMeasure.getLength());
    valueAnimator.setDuration(1000);
    valueAnimator.setInterpolator(new LinearInterpolator());
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
        float value = (float)animation.getAnimatedValue();
        mPathMeasure.getPosTan(value, mCurrentPosition, null);
        view.setTranslationX(mCurrentPosition[0]);
        view.setTranslationY(mCurrentPosition[1]);
      }
    });
    valueAnimator.addListener(new Animator.AnimatorListener() {
      @Override
      public void onAnimationStart(Animator animation) {
 
      }
 
      @Override
      public void onAnimationEnd(Animator animation) {
        // 購物車的數(shù)量加1
        mCount++;
        mCountTv.setText(String.valueOf(mCount));
        // 把移動的圖片imageview從父布局里移除
        mRootRl.removeView(view);
 
        //shopImg 開始一個放大動畫
        Animation scaleAnim = AnimationUtils.loadAnimation(GoodsListActivity.this, R.anim.shop_car_scale);
        mCarImageView.startAnimation(scaleAnim);
      }
 
      @Override
      public void onAnimationCancel(Animator animation) {
 
      }
 
      @Override
      public void onAnimationRepeat(Animator animation) {
 
      }
    });
    valueAnimator.start();
  }
 
  class GoodsViewHolder extends RecyclerView.ViewHolder{
 
    private ImageView ivGood;
    private TextView tvBuy;
 
    public GoodsViewHolder(View itemView) {
      super(itemView);
      ivGood = (ImageView)itemView.findViewById(R.id.iv_goods);
      tvBuy = (TextView) itemView.findViewById(R.id.tv_buy);
    }
  }
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/happy_horse/article/details/67646202

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本久久网站 | 99re热视频这里只精品 | 91精品国产91久久久久久不卞 | h网站在线观看 | 91九色蝌蚪在线 | 国产88久久久国产精品免费二区 | 免费毛片观看 | 国产精品久久久久久久久久尿 | 久久999精品| 国产精品一区二区x88av | 手机av免费电影 | 亚州综合图片 | 逼片| 一级做a爱性色毛片免费1 | 久久久久久久久久久久久久久久久久 | 亚洲一区中文字幕 | 羞羞视频一区二区 | 草莓视频久久 | 私库av在线免费观看 | 超碰99在线观看 | 久久我不卡 | 欧美久久久一区二区三区 | 毛片免费观看视频 | 天天操天天看 | 国产精品久久久久久久久粉嫩 | 爽爽淫人网 | 午夜精品福利影院 | 国产精品久久久久无码av | 国产成人精品区一区二区不卡 | 精品国产一区二区三区成人影院 | 久草在线最新免费 | av免费大全 | 一级免费在线视频 | hd性videos意大利复古 | 久久久久久久久久久久久久国产 | 久久精品一区二区三区四区五区 | 成人做爰高潮片免费视频韩国 | 亚洲啪| 久久精品久久久久 | 懂色av懂色aⅴ精彩av | 福利免费观看 |