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

首頁 > 系統 > Android > 正文

Android實現去哪兒攜程地址互換效果

2019-10-21 21:49:23
字體:
來源:轉載
供稿:網友

昨天朋友項目中有個需求讓我幫忙看看怎么搞,就跟去哪兒攜程買機票時點中間按鈕互換出發地和目的地的效果,當時一看覺得挺簡單,用補間動畫,在動畫完成時設置給兩邊各textview互換值就好,做出來后發現效果不好,在最后互換值得時候會有閃爍,于是就用了一種較為麻煩的方法,不過效果是達到了,記錄一下。gif效果不好。

Android,去哪兒,攜程,地址互換

內容

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

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

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

Android,去哪兒,攜程,地址互換

Android,去哪兒,攜程,地址互換

 

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

3、隱藏兩側的textview,開啟鏡像view的屬性動畫,在結束時互換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();  //包裹右側tv距離父控件的距離  int rlRight = mRlRight.getRight();  int rlLeft = mRlRight.getLeft();  //在哪里設的padding就要用哪個控件來獲取padding值  int paddingStart = mLl.getPaddingStart();  Log.d("AddressActivity", "paddingStart:" + paddingStart);  //左側textview需要移動的距離  int leftOffset = rlRight - leftRight - paddingStart;  //右側textview需要移動的距離  int rightOffset = rlLeft + rightLeft - paddingStart;  //創建出鏡像view  createCopyView();  //隱藏掉兩邊的tv  mTvLeft.setVisibility(View.INVISIBLE);  mTvRight.setVisibility(View.INVISIBLE);  //開啟鏡像view的動畫  leftAnim(leftOffset,mLeftLocation[0]);  rightAnim(rightOffset,mRightLocation[0]); } /**  * 創建鏡像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();  //創建出兩個鏡像view  copyViewLeft = createCopyView(mLeftLocation[0], mLeftLocation[1], mLeftCacheBitmap);  copyViewRight = createCopyView(mRightLocation[0], mRightLocation[1], mRightCacheBitmap);  //釋放bitmap資源...這我不確定是不是這么做  mLeftCacheBitmap = null;  mRightCacheBitmap = null; } /**  * 左側鏡像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();  //左側動畫監聽  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);   }  }); } /**  * 右側鏡像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;   }  }); } /**  * 創建鏡像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; //設置imageView的原點  mLayoutParams.y = y - getStatusHeight(this);  mLayoutParams.alpha = 1f;        //設置透明度  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; } /**  * 獲取狀態欄的高度  * @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; }}

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


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 红河县| 北海市| 巴林左旗| 甘德县| 高陵县| 勐海县| 特克斯县| 西充县| 镇康县| 鄂托克旗| 卢湾区| 鱼台县| 平江县| 巴彦县| 榆社县| 雷州市| 凤台县| 景宁| 泗阳县| 西安市| 基隆市| 东阳市| 岳西县| 亳州市| 南京市| 平定县| 慈溪市| 尚义县| 深泽县| 英超| 交城县| 剑川县| 濮阳市| 普兰店市| 桦甸市| 澄迈县| 石柱| 酒泉市| 德昌县| 苍溪县| 阳西县|