欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android實現(xiàn)去哪兒攜程地址互換效果

 更新時間:2018年06月28日 09:59:56   作者:xinyang_code  
這篇文章主要為大家詳細介紹了Android實現(xiàn)去哪兒攜程地址互換效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下

昨天朋友項目中有個需求讓我?guī)兔纯丛趺锤?,就跟去哪兒攜程買機票時點中間按鈕互換出發(fā)地和目的地的效果,當時一看覺得挺簡單,用補間動畫,在動畫完成時設(shè)置給兩邊各textview互換值就好,做出來后發(fā)現(xiàn)效果不好,在最后互換值得時候會有閃爍,于是就用了一種較為麻煩的方法,不過效果是達到了,記錄一下。gif效果不好。

這里寫圖片描述

內(nèi)容

簡單說下思路,在點擊互換按鈕后:

1、計算互換位置的需要的偏移量:

這里需要需要考慮的特殊地方就是左右兩邊有可能文字長度不一樣,所以我在textview外面套了一層相對布局.畫個圖來說明吧.布局最外層是個水平的線性布局,中間一個button,兩邊各一個相對布局寬度0dp權(quán)重1,里面的textview寬度都是包裹內(nèi)容的.

這里寫圖片描述

這里寫圖片描述

2、獲取兩側(cè)textview的坐標及繪圖緩存,創(chuàng)建鏡像view,隱藏兩側(cè)的textview,這里直接看下面代碼就好啦,需要注意的是Y坐標要減去狀態(tài)欄高度.

3、隱藏兩側(cè)的textview,開啟鏡像view的屬性動畫,在結(jié)束時互換textview的值,顯示出textview,移除鏡像view,釋放資源.

代碼

public class AddressActivity extends AppCompatActivity {

 private TextView mTvLeft;
 private TextView mTvRight;
 private Button mBtn;
 private RelativeLayout mRlLeft;
 private RelativeLayout mRlRight;
 private WindowManager mWindowManager;
 private int[] mLeftLocation;
 private int[] mRightLocation;
 private Bitmap mLeftCacheBitmap;
 private Bitmap mRightCacheBitmap;
 private LinearLayout mLl;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_address);

  mWindowManager = getWindowManager();

  mTvLeft = (TextView) findViewById(R.id.tv_left);
  mTvRight = (TextView) findViewById(R.id.tv_right);
  mRlLeft = (RelativeLayout) findViewById(R.id.rl_left);
  mRlRight = (RelativeLayout) findViewById(R.id.rl_right);
  mLl = (LinearLayout) findViewById(R.id.ll);
  mBtn = (Button) findViewById(R.id.btn);
  mBtn.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
    textAnim();
    mBtn.setEnabled(false);
   }
  });
 }


 /**
  * 左邊tv的鏡像view
  */
 private ImageView copyViewLeft;
 /**
  * 右邊tv的鏡像view
  */
 private ImageView copyViewRight;

 /**
  * 獲取tv的屬性,計算偏移量,
  */
 private void textAnim() {

  //獲取tv控件距離父控件的位置
  int leftRight = mTvLeft.getRight();
  int rightLeft = mTvRight.getLeft();

  //包裹右側(cè)tv距離父控件的距離
  int rlRight = mRlRight.getRight();
  int rlLeft = mRlRight.getLeft();
  //在哪里設(shè)的padding就要用哪個控件來獲取padding值
  int paddingStart = mLl.getPaddingStart();

  Log.d("AddressActivity", "paddingStart:" + paddingStart);

  //左側(cè)textview需要移動的距離
  int leftOffset = rlRight - leftRight - paddingStart;
  //右側(cè)textview需要移動的距離
  int rightOffset = rlLeft + rightLeft - paddingStart;

  //創(chuàng)建出鏡像view
  createCopyView();

  //隱藏掉兩邊的tv
  mTvLeft.setVisibility(View.INVISIBLE);
  mTvRight.setVisibility(View.INVISIBLE);

  //開啟鏡像view的動畫
  leftAnim(leftOffset,mLeftLocation[0]);
  rightAnim(rightOffset,mRightLocation[0]);
 }

 /**
  * 創(chuàng)建鏡像view
  */
 private void createCopyView(){
  mLeftLocation = new int[2];
  mRightLocation = new int[2];
  //獲取相對window的坐標
  mTvLeft.getLocationInWindow(mLeftLocation);
  mTvRight.getLocationInWindow(mRightLocation);

  //獲取左邊tv的緩存bitmap
  mTvLeft.setDrawingCacheEnabled(true);
  mLeftCacheBitmap = Bitmap.createBitmap(mTvLeft.getDrawingCache());
  mTvLeft.destroyDrawingCache();
  //獲取右邊tv的緩存bitmap
  mTvRight.setDrawingCacheEnabled(true);
  mRightCacheBitmap = Bitmap.createBitmap(mTvRight.getDrawingCache());
  mTvRight.destroyDrawingCache();

  //創(chuàng)建出兩個鏡像view
  copyViewLeft = createCopyView(mLeftLocation[0], mLeftLocation[1], mLeftCacheBitmap);
  copyViewRight = createCopyView(mRightLocation[0], mRightLocation[1], mRightCacheBitmap);
  //釋放bitmap資源...這我不確定是不是這么做
  mLeftCacheBitmap = null;
  mRightCacheBitmap = null;
 }
 /**
  * 左側(cè)鏡像view的動畫
  * @param offset 偏移量
  * @param defX  原始位置的x
  */
 private void leftAnim(int offset, final int defX){
  ValueAnimator leftAnimV = ValueAnimator.ofInt(0,offset);
  leftAnimV.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
   @Override
   public void onAnimationUpdate(ValueAnimator valueAnimator) {
    int animatedValue = (int) valueAnimator.getAnimatedValue();
    WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) copyViewLeft.getLayoutParams();
    //往右邊移動所以x是變大的
    layoutParams.x = defX + animatedValue;
    mWindowManager.updateViewLayout(copyViewLeft,layoutParams);
   }
  });
  leftAnimV.setDuration(400);
  leftAnimV.start();
  //左側(cè)動畫監(jiān)聽
  leftAnimV.addListener(new AnimatorListenerAdapter() {
   @Override
   public void onAnimationEnd(Animator animation) {
    //改變值
    String s = mTvLeft.getText().toString();
    mTvLeft.setText(mTvRight.getText().toString());
    mTvRight.setText(s);
    mTvLeft.setVisibility(View.VISIBLE);
    mWindowManager.removeView(copyViewLeft);
    copyViewLeft = null;
    mBtn.setEnabled(true);
   }
  });
 }

 /**
  * 右側(cè)鏡像view動畫
  * @param offset 偏移量
  * @param defX  原始位置的x
  */
 private void rightAnim(int offset, final int defX){
  ValueAnimator rightAnimV = ValueAnimator.ofInt(0,offset);
  rightAnimV.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
   @Override
   public void onAnimationUpdate(ValueAnimator valueAnimator) {
    int animatedValue = (int) valueAnimator.getAnimatedValue();
    WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) copyViewRight.getLayoutParams();
    layoutParams.x = defX - animatedValue;
    mWindowManager.updateViewLayout(copyViewRight,layoutParams);
   }
  });
  rightAnimV.setDuration(400);
  rightAnimV.start();
  rightAnimV.addListener(new AnimatorListenerAdapter() {
   @Override
   public void onAnimationEnd(Animator animation) {
    mTvRight.setVisibility(View.VISIBLE);
    mWindowManager.removeView(copyViewRight);
    copyViewRight = null;
   }
  });
 }

 /**
  * 創(chuàng)建鏡像view
  *
  * @param x
  * @param y
  * @param bitmap
  */
 private ImageView createCopyView(int x, int y, Bitmap bitmap) {
  WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams();
  mLayoutParams.format = PixelFormat.TRANSLUCENT;   //圖片之外其他地方透明
  mLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
  mLayoutParams.x = x; //設(shè)置imageView的原點
  mLayoutParams.y = y - getStatusHeight(this);
  mLayoutParams.alpha = 1f;        //設(shè)置透明度
  mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
  mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
  mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
    | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
  ImageView copyView = new ImageView(this);
  copyView = new ImageView(this);
  copyView.setImageBitmap(bitmap);
  mWindowManager.addView(copyView, mLayoutParams); //添加該iamgeView到window
  return copyView;
 }

 /**
  * 獲取狀態(tài)欄的高度
  * @param context
  * @return
  */
 private static int getStatusHeight(Context context) {
  int statusHeight = 0;
  Rect localRect = new Rect();
  ((Activity) context).getWindow().getDecorView().getWindowVisibleDisplayFrame(localRect);
  statusHeight = localRect.top;
  if (0 == statusHeight) {
   Class<?> localClass;
   try {
    localClass = Class.forName("com.android.internal.R$dimen");
    Object localObject = localClass.newInstance();
    int i5 = Integer.parseInt(localClass.getField("status_bar_height").get(localObject).toString());
    statusHeight = context.getResources().getDimensionPixelSize(i5);
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
  return statusHeight;
 }
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android編程單元測試實例詳解(附源碼)

    Android編程單元測試實例詳解(附源碼)

    這篇文章主要介紹了Android編程單元測試,結(jié)合完整實例形式詳細分析了Android單元測試的具體步驟與相關(guān)技巧,并附帶完整實例代碼供讀者下載參考,需要的朋友可以參考下
    2015-11-11
  • RecyclerView實現(xiàn)查看更多及收起

    RecyclerView實現(xiàn)查看更多及收起

    這篇文章主要為大家詳細介紹了RecyclerView實現(xiàn)查看更多及收起,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 淺談Android中Drawable使用知識總結(jié)

    淺談Android中Drawable使用知識總結(jié)

    本篇文章主要介紹了淺談Android中Drawable使用知識總結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • Android View 布局流程(Layout)全面解析

    Android View 布局流程(Layout)全面解析

    這篇文章主要為大家全面解析了Android View 布局流程Layout,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • Android編程中圖片特效處理方法小結(jié)

    Android編程中圖片特效處理方法小結(jié)

    這篇文章主要介紹了Android編程中圖片特效處理方法,實例總結(jié)了Android實現(xiàn)圖片的轉(zhuǎn)換、縮放、圓角及倒影等效果的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-10-10
  • android實現(xiàn)數(shù)獨游戲機器人

    android實現(xiàn)數(shù)獨游戲機器人

    這篇文章主要為大家詳細介紹了android實現(xiàn)數(shù)獨游戲機器人,文中安裝步驟介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Android編程之防止反編譯的實現(xiàn)方法

    Android編程之防止反編譯的實現(xiàn)方法

    這篇文章主要介紹了Android編程之防止反編譯的實現(xiàn)方法,涉及Android針對運行環(huán)境、簽名及程序相關(guān)信息的獲取與判定技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-11-11
  • Android自定義控件之創(chuàng)建可復(fù)用的組合控件

    Android自定義控件之創(chuàng)建可復(fù)用的組合控件

    這篇文章主要為大家詳細介紹了Android自定義控件之創(chuàng)建可復(fù)用的組合控件,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • Android刮刮卡實現(xiàn)原理與代碼講解

    Android刮刮卡實現(xiàn)原理與代碼講解

    這篇文章主要為大家詳細介紹了Android刮刮卡實現(xiàn)原理、實現(xiàn)原理步驟以及代碼講解,感興趣的小伙伴們可以參考一下
    2016-04-04
  • AOSP源碼下載示例代碼

    AOSP源碼下載示例代碼

    這篇文章主要介紹了AOSP源碼下載,由于清華源中給出很清晰的配置下載方法,這兒只做幾條總結(jié),對AOSP源碼感興趣的朋友一起看看吧
    2022-08-08

最新評論