最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android可自定義神奇動效的卡片切換視圖實例

 更新時間:2019年02月12日 11:01:23   作者:BakerJ  
今天小編就為大家分享一篇關(guān)于Android可自定義神奇動效的卡片切換視圖實例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧

前言

面對眾多卡片層疊效果,我們的產(chǎn)品童鞋也突發(fā)奇想,搞出了另一種卡片層疊切換展示的交互,而且產(chǎn)品狗們居然要求多做幾種動效給他們看,好讓他們選擇,這簡直就是要搞事情啊,what are you 弄啥咧?!

“哥哥我做不到啊.....啊.....呸”,做為一名有節(jié)操的程序猿,自然是不能說出這么沒有出息的話,哥就滿足你們,于是,出了個可自定義動效的卡片切換視圖,效果如下所示

思路

首先,要展示出卡片層疊的視覺效果。在這里,我們通過方塊的縮放大小差異以及在Y方向上的位置差異,來展現(xiàn)這種視覺效果。

其次,要能夠方便的定義卡片視圖內(nèi)容。我們通過都很熟悉的設(shè)置Adapter的方式來構(gòu)建內(nèi)容視圖。

最后,要能夠自定義動效。我們通過定義一個由0到1的ValueAnimator,即每個動畫的過程,其實就是該ValueAnimator在一個動畫周期內(nèi),從0變化到1的過程,0表示動畫剛開始,1表示動畫結(jié)束了,0.5則表示這一輪動畫已經(jīng)執(zhí)行到了一半。這樣,通過轉(zhuǎn)換器以及插值器,我們就可以根據(jù)ValueAnimator實時的值,來設(shè)置當(dāng)前正在執(zhí)行動畫的卡片應(yīng)該有的“樣子”。

總覽

我們給出三種基本的動畫模式

/*
 * ANIM_TYPE_FRONT:被選中的卡片通過自定義動效移至第一,其他的卡片通過通用動效補位
 * ANIM_TYPE_SWITCH:選中的卡片和第一張卡片互換位置,并都是自定義動效
 * ANIM_TYPE_FRONT_TO_LAST:第一張圖片通過自定義動效移至最后,其他卡片通過通用動效補位
 */
public static final int ANIM_TYPE_FRONT = 0, ANIM_TYPE_SWITCH = 1, ANIM_TYPE_FRONT_TO_LAST = 2;

并通過Helper類來處理所有的動畫邏輯,以及Adapter來生成卡片視圖

private CardAnimationHelper mAnimationHelper;
private BaseAdapter mAdapter;

在onMeasure時根據(jù)卡片寬高比來設(shè)置卡片的尺寸,在此請注意,當(dāng)前情況下卡片寬度與整體容器寬度一致,后續(xù)通過自定義的方式,通過縮放來產(chǎn)生卡片的視覺效果。

private float mCardRatio = CARD_SIZE_RATIO;//寬高比:卡片高 / 卡片寬
private int mCardWidth, mCardHeight;//卡片寬高
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  ...
  if (mCardWidth == 0 || mCardHeight == 0) {
    setCardSize(true);
  }
}
/*
 * 根據(jù)卡片比例計算卡片寬高,并傳入Helper
 */
private void setCardSize(boolean resetAdapter) {
  mCardWidth = getMeasuredWidth();
  mCardHeight = (int) (mCardWidth * mCardRatio);
  mAnimationHelper.setCardSize(mCardWidth, mCardHeight);
  mAnimationHelper.initAdapterView(mAdapter, resetAdapter);
}

那么如此之后,自然Helper中就保存了視圖的主要數(shù)據(jù)與參數(shù)

//卡片列表
private LinkedList<CardItem> mCards;
//當(dāng)前正在向后以及向前移動的卡片
private CardItem mCardToBack, mCardToFront;
//正在向后以及向前移動卡片的位置
private int mPositionToBack = 0, mPositionToFront = 0;
//動畫運行的ValueAnimator
private ValueAnimator mValueAnimator;
//當(dāng)前的動畫系數(shù)
private float mCurrentFraction = 1;
...//以及一系列的轉(zhuǎn)換器與插值器

細(xì)節(jié)

那么,動畫到底是如何實現(xiàn)的,以及如何自定義的呢,我們以通用動畫為例,來看看動畫的主要流程

首先,在ValueAnimator更新的時候,獲得當(dāng)前的動畫系數(shù),依次來執(zhí)行動畫

/**
 * ValueAnimator動畫更新
 */
@Override
public void onAnimationUpdate(ValueAnimator animation) {
  //獲取當(dāng)前動畫系數(shù)
  mCurrentFraction = (float) animation.getAnimatedValue();
  //通過插值器獲取插值系數(shù)
  fractionInterpolated = mAnimInterpolator.getInterpolation(mCurrentFraction);
  doAnimationCommon(mCurrentFraction, fractionInterpolated);
  ...
}

接著,對需要執(zhí)行動畫的卡片,執(zhí)行動畫,以ANIM_TYPE_FRONT動畫模式為例,當(dāng)選中的卡片移動到最前的時候,原來在這張卡片之前的所有卡片,都要向后移動一位,來留出第一個的位置

/**
 * 執(zhí)行通用動畫
 */
private void doAnimationCommon(float fraction, float fractionInterpolated) {
  //如果當(dāng)前動畫模式為選中的卡片移到最前
  if (mAnimType == InfiniteCardView.ANIM_TYPE_FRONT) {
    //則遍歷在選中卡片之前的卡片
    for (int i = 0; i < mPositionToFront; i++) {
      CardItem card = mCards.get(i);
      //對卡片執(zhí)行動畫,從當(dāng)前位置移動到后一個位置
      doAnimationCommonView(card.view, fraction, fractionInterpolated, i, i + 1);
      ...
    }
  }...
}

最后,通過轉(zhuǎn)換器,對卡片進(jìn)行自定義動畫處理

/**
 * 對視圖執(zhí)行通用動畫
 * @param view         卡片視圖
 * @param fromPosition     從該位置
 * @param toPosition      移動到該位置
 */
private void doAnimationCommonView(View view, float fraction, float fractionInterpolated, int
    fromPosition, int toPosition) {
  //通用轉(zhuǎn)換器轉(zhuǎn)換動畫
  mTransformerCommon.transformAnimation(view, fraction, mCardWidth,
      mCardHeight, fromPosition, toPosition);
  if (mAnimInterpolator != null) {
    //通用轉(zhuǎn)換器轉(zhuǎn)換插值動畫
    mTransformerCommon.transformInterpolatedAnimation(view, fractionInterpolated,            mCardWidth,mCardHeight, fromPosition, toPosition);
  }
}

而轉(zhuǎn)換器的具體實現(xiàn)則以DefaultCommonTransformer為例

@Override
public void transformAnimation(View view, float fraction, int cardWidth, int cardHeight, int fromPosition, int toPosition) {
  //需要跨越的卡片數(shù)量
  int positionCount = fromPosition - toPosition;
  //以0.8做為第一張的縮放尺寸,每向后一張縮小0.1
  //(0.8f - 0.1f * fromPosition) = 當(dāng)前位置的縮放尺寸
  //(0.1f * fraction * positionCount) = 移動過程中需要改變的縮放尺寸
  float scale = (0.8f - 0.1f * fromPosition) + (0.1f * fraction * positionCount);
  ViewHelper.setScaleX(view, scale);
  ViewHelper.setScaleY(view, scale);
  //在Y方向的偏移量,每向后一張,向上偏移卡片寬度的0.02
  //-cardHeight * (0.8f - scale) * 0.5f 對卡片做整體居中處理
  ViewHelper.setTranslationY(view, -cardHeight * (0.8f - scale) * 0.5f - cardWidth * (0.02f *
     fromPosition - 0.02f * fraction * positionCount));
}

對于向第一位移動的選中卡片,也是同理,只不過是根據(jù)該卡片對應(yīng)的轉(zhuǎn)換器來進(jìn)行自定義動畫的轉(zhuǎn)換。

最后的效果,就像演示圖中第一次點擊,圖片向前翻轉(zhuǎn)到第一位的效果一樣。

對于產(chǎn)品狗突如其來的想法,咱們程序猿不善于口水仗的,就只能用代碼來讓他們來服氣了。畢竟,大家還都是伐木累嘛,哈哈。

當(dāng)實現(xiàn)某個東西遇到困難時,不妨想想Android系統(tǒng)自身的一些實現(xiàn)方式,比如參考ListView的Adapter,ViewPager定義翻頁動畫的Transformer等等,總會有意想不到的啟發(fā)。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接

相關(guān)文章

  • Android中你可能不知道的Fragment妙用

    Android中你可能不知道的Fragment妙用

    自從Android 3.0中引入fragments 的概念,根據(jù)詞海的翻譯可以譯為:碎片、片段。下面這篇文章主要給大家分享了關(guān)于Android中你可能不知道的Fragment妙用,對大家具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下。
    2017-07-07
  • Android利用RecyclerView編寫聊天界面

    Android利用RecyclerView編寫聊天界面

    這篇文章主要為大家詳細(xì)介紹了Android利用RecyclerView編寫聊天界面,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • 分享Android中ExpandableListView控件使用教程

    分享Android中ExpandableListView控件使用教程

    這篇文章主要介紹了Android中ExpandableListView控件使用教程,可以實現(xiàn)二級列表展示效果,需要的朋友可以參考下
    2015-12-12
  • Android studio so庫找不到問題解決辦法

    Android studio so庫找不到問題解決辦法

    這篇文章主要介紹了Android studio so庫找不到問題解決辦法的相關(guān)資料,希望通過本文能幫助到大家解決出現(xiàn)的這種問題,需要的朋友可以參考下
    2017-10-10
  • Android編程應(yīng)用風(fēng)格和主題詳解

    Android編程應(yīng)用風(fēng)格和主題詳解

    這篇文章主要介紹了Android編程應(yīng)用風(fēng)格和主題,較為詳細(xì)的分析了Android應(yīng)用風(fēng)格和主題的概念、功能、使用方法與注意事項,需要的朋友可以參考下
    2016-10-10
  • Android監(jiān)聽Home鍵實例詳解

    Android監(jiān)聽Home鍵實例詳解

    這篇文章主要介紹了Android監(jiān)聽Home鍵的方法,結(jié)合實例形式詳細(xì)分析了Android編程實現(xiàn)監(jiān)聽Home鍵的具體步驟與相關(guān)功能代碼,需要的朋友可以參考下
    2016-02-02
  • android studio按鈕監(jiān)聽的5種方法實例詳解

    android studio按鈕監(jiān)聽的5種方法實例詳解

    這篇文章主要介紹了android studio按鈕監(jiān)聽的5種方法,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • Android自定義彈出框的方法

    Android自定義彈出框的方法

    這篇文章主要為大家詳細(xì)介紹了Android自定義彈出框的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 解析Android中webview和js之間的交互

    解析Android中webview和js之間的交互

    本篇文章是對Android中webview和js之間的交互進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-07-07
  • Android DragImageView實現(xiàn)下拉拖動圖片放大效果

    Android DragImageView實現(xiàn)下拉拖動圖片放大效果

    這篇文章主要為大家詳細(xì)介紹了Android DragImageView實現(xiàn)下拉拖動圖片放大效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12

最新評論

深水埗区| 犍为县| 宜兰市| 射阳县| 兖州市| 确山县| 扶风县| 聊城市| 崇阳县| 密山市| 开平市| 宜良县| 宁南县| 南宁市| 原平市| 孟村| 五家渠市| 双江| 化隆| 阆中市| 峨眉山市| 永和县| 湖北省| 宜章县| 正宁县| 曲阳县| 罗山县| 潜山县| 荣昌县| 仁寿县| 游戏| 开封县| 桑日县| 和龙市| 普陀区| 百色市| 旺苍县| 罗城| 定兴县| 遂宁市| 舞阳县|