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

首頁 > 系統 > Android > 正文

Android仿即刻首頁垂直滾動圖,炫酷到底!

2019-12-12 05:19:26
字體:
來源:轉載
供稿:網友

項目地址:https://github.com/JeasonWong/JikeGallery

話不多說,先上效果。

這個效果是在即刻app上看到,覺得很不錯,遂仿之。

先說下我的實現思路(以上方的圖片滾動為例,下方的文字實現效果類似):

自定義ViewGroup
裝載兩個ImageView和一個陰影View
通過一定規律交替控制兩個ImageView和它們的marginTop,在onLayout()中實現
marginTop的具體值由屬性動畫控制,不斷調用requestLayout()

接下來依次說明

一、自定義ViewGroup

 //滑動狀態 protected static final int STATUS_SMOOTHING = 0; //停止狀態 protected static final int STATUS_STOP = 1; //ViewGroup寬高 protected int mWidth, mHeight; //變化的marginTop值 protected int mSmoothMarginTop; //默認狀態 protected int mStatus = STATUS_STOP; //滾動時間間隔 protected int mDuration = 500; //重復次數 protected int mRepeatTimes = 0; ... @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {  super.onSizeChanged(w, h, oldw, oldh);  mWidth = w;  mHeight = h;  mSmoothMarginTop = -h;  initView(); } protected abstract void initView(); ... /**  * 是否是奇數圈  *  * @return 結果  */ protected boolean isOddCircle() {  return mRepeatTimes % 2 == 1; }

先了解下成員變量,其中最重要的一個就是mSmoothMarginTop,相信很多人都知道一個View的marginTop可以設為負數,這個負數可以給我們帶來太多的方便。

上圖的圖0就是我們展現在屏幕上的ImageView,圖1則是屏幕外marginTop為-height的ImageView,這個一定要明白,接下來才好繼續實現。

二、裝載兩個ImageView和一個陰影View

 private List<String> mImgList = new ArrayList<>(); private ImageView[] mImgs = new ImageView[2]; private View mShadowView; ... @Override protected void initView() {  //如果沒有內容,則不進行初始化操作  if (mImgList.size() == 0) {   return;  }  removeAllViews();  MarginLayoutParams params = new MarginLayoutParams(mWidth, mHeight);  //兩個ImageView加載前兩張圖  for (int i = 0; i < mImgs.length; i++) {   mImgs[i] = new ImageView(getContext());   addViewInLayout(mImgs[i], -1, params, true);   Glide.with(getContext()).load(getImgPath(i)).centerCrop().into(mImgs[i]);  }  //創建陰影View  mShadowView = new View(getContext());  mShadowView.setBackgroundColor(Color.parseColor("#60000000"));  mShadowView.setAlpha(0);  addViewInLayout(mShadowView, -1, params, true); } ... /**  * 獲取圖片地址  *   * @param position 位置  * @return 圖片地址  */ private String getImgPath(int position) {  position = position % mImgList.size();  return mImgList.get(position); } 

關鍵點說明:

MarginLayoutParams 為了之后方便取出margin值
addViewInLayout() 為了對requestLayout的絕對控制
getImgPath() 為了實現循環滾動
這樣一來,我們需要的View都已經創建好了。

三、通過一定規律交替控制兩個ImageView和它們的marginTop,在onLayout()中實現

 @Override protected void onLayout(boolean changed, int l, int t, int r, int b) {  int cCount = getChildCount();  MarginLayoutParams cParams;  for (int i = 0; i < cCount; i++) {   View childView = getChildAt(i);   cParams = (MarginLayoutParams) childView.getLayoutParams();   int cl = 0, ct = 0, cr, cb;   if (isOddCircle()) {    if (i == 1) {     cl = cParams.leftMargin;     ct = mSmoothMarginTop + mHeight;    } else if (i == 0) {     cl = cParams.leftMargin;     ct = mSmoothMarginTop;    }   } else {    if (i == 0) {     cl = cParams.leftMargin;     ct = mSmoothMarginTop + mHeight;    } else if (i == 1) {     cl = cParams.leftMargin;     ct = mSmoothMarginTop;    }   }   //控制shadowView   if (i == 2) {    cl = cParams.leftMargin;    ct = mSmoothMarginTop + mHeight;   }   cr = cl + mWidth;   cb = ct + mHeight;   childView.layout(cl, ct, cr, cb);  } }

以上實現的就是不斷的替換圖1和圖2誰上誰下,陰影和下方的圖保持同步。

四、marginTop的具體值由屬性動畫控制,不斷調用requestLayout()

先看基類ViewGroup

 /**  * 開啟滑動  *  */ public void startSmooth() {  if (mStatus != STATUS_STOP) {   return;  }  ValueAnimator animator = ValueAnimator.ofFloat(-mHeight, 0);  animator.setDuration(mDuration);  animator.setInterpolator(new AccelerateDecelerateInterpolator());  animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {   @Override   public void onAnimationUpdate(ValueAnimator animation) {    float marginTop = (float) animation.getAnimatedValue();    mSmoothMarginTop = (int) marginTop;    if (marginTop == 0) {     postDelayed(new Runnable() {      @Override      public void run() {       mRepeatTimes++;       mSmoothMarginTop = -mHeight;       doAnimFinish();       mStatus = STATUS_STOP;      }     }, 50);    } else {     doAnim();    }   }  });  animator.start();  mStatus = STATUS_SMOOTHING; } //動畫結束 protected abstract void doAnimFinish(); //動畫進行時 protected abstract void doAnim();

關鍵點說明:

屬性動畫控制著mSmoothMarginTop在[-mHeight, 0]中變化
每完成一圈,mRepeatTimes自增1

再來看看Gallery實現類

 @Override protected void doAnimFinish() {  if (isOddCircle()) {   Glide.with(getContext()).load(getImgPath(mRepeatTimes + 1)).centerCrop().into(mImgs[0]);  } else {   Glide.with(getContext()).load(getImgPath(mRepeatTimes + 1)).centerCrop().into(mImgs[1]);  }  mShadowView.setAlpha(0); } @Override protected void doAnim() {  mShadowView.setAlpha(((1 - (-mSmoothMarginTop) / (float) mHeight)));  requestLayout(); }

關鍵點說明:

通過mSmoothMarginTop與mHeight的比值控制陰影View的透明度
每次動畫完成時,下方的圖(此時下方的圖已經超出屏幕了,而上方圖顯示在屏幕內)需要加載第三張圖,使用getImgPath()取出
pic1

以上就是圖片的滾動實現,文字的滾動90%是一樣的,有點區別的就是需要文字需要控制下垂直居中,我就不贅述了。

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宜城市| 凤阳县| 罗定市| 仁布县| 白城市| 墨竹工卡县| 台州市| 怀化市| 溧阳市| 黔西县| 阿坝| 靖州| 元氏县| 朔州市| 固镇县| 阳谷县| 松滋市| 巩留县| 固原市| 柘城县| 长白| 玉林市| 临漳县| 屏东市| 营口市| 永丰县| 特克斯县| 高陵县| 阳西县| 麻栗坡县| 库尔勒市| 波密县| 南澳县| 黄山市| 崇义县| 凤山市| 门头沟区| 建宁县| 岳阳市| 天水市| 祁阳县|