国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android實現購物車添加商品動畫

2019-10-21 21:48:55
字體:
來源:轉載
供稿:網友

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

實現需求:

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

實現思路:

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

實現效果:

Android,購物車,動畫

實現中會用到 PathMeasure 類: 

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

1、獲取長度:

/** //獲取弧線的總長度(周長)   * 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);//系統調用native 方法;  }

2、獲取坐標:

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

代碼如下:

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) {        // 購物車的數量加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);    }  }}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 揭阳市| 泰安市| 大庆市| 嵊泗县| 城固县| 常山县| 清镇市| 凤冈县| 昌平区| 临江市| 洛隆县| 崇信县| 正镶白旗| 酒泉市| 林甸县| 扬州市| 新平| 依安县| 阿克苏市| 云浮市| 彭州市| 讷河市| 开阳县| 扎兰屯市| 白河县| 巴南区| 阿拉善右旗| 红原县| 富平县| 宝坻区| 北碚区| 万全县| 南平市| 兰西县| 巴南区| 镇巴县| 南江县| 东方市| 南华县| 永登县| 平泉县|