android TranslateAnimation 頂部segment分段移動動畫

来源:http://www.cnblogs.com/xiaoliao/archive/2017/09/08/7496300.html
-Advertisement-
Play Games

這裡實現的功能是從主頁佈局的fragment點擊跳轉到一個acitivity,然後頂部是一個切換的segment底部部是一個listview,點擊segment分段讓listview載入不同的內容。我這裡沒再使用viewpager,應該使用viewpager+listview也能實現。我這裡使用的算 ...


        這裡實現的功能是從主頁佈局的fragment點擊跳轉到一個acitivity,然後頂部是一個切換的segment底部部是一個listview,點擊segment分段讓listview載入不同的內容。我這裡沒再使用viewpager,應該使用viewpager+listview也能實現。我這裡使用的算是一個自定義的viewpager。下麵我主要圍繞TranslateAnimation segment切換動畫類來談,這東西吭比較多,我原本也是才做android開發的, 它這個類實現動畫很多效果上的bug,效果bug直接說明android這個動畫類沒ios做的好,我遇到的這些效果bug主要出現在控制項移動的距離和移動時間上的計算上。比如移動動畫帶有緩衝,或則移動分段兩個以上,就沒有動畫效果。

 

下麵先帖上佈局,主要就是

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
              android:background="@color/white_color"
              android:orientation="vertical" >
    <TextView
        android:layout_width="match_parent"
        android:layout_height="@dimen/navigationbar_height"
        android:textSize="@dimen/title_fontsize"
        android:text="線上視頻"

        android:textColor="@color/navigation_title_color"
        android:background="@color/navigationbar_backround_color"
        android:gravity="center"/>
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="53dp"
         android:orientation="vertical"
         android:animateLayoutChanges="true"
         >
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="50dp"
             android:orientation="horizontal"
             >

         <TextView
             android:layout_width="match_parent"
             android:layout_height="@dimen/navigationbar_height"
             android:layout_weight="1"
             android:textSize="@dimen/title_fontsize"
             android:text="推薦"
             android:id="@+id/tuijianVideo"
             android:textColor="@color/hot_price_color"
             android:background="@color/navigationbar_backround_color"
             android:gravity="center"/>
         <TextView
             android:layout_width="match_parent"
             android:layout_height="@dimen/navigationbar_height"
             android:textSize="@dimen/title_fontsize"
             android:layout_weight="1"
             android:text="電影"
             android:id="@+id/dianying"
             android:textColor="@color/navigation_title_color"
             android:background="@color/navigationbar_backround_color"
             android:gravity="center"/>
         <TextView
             android:layout_width="match_parent"
             android:layout_height="@dimen/navigationbar_height"
             android:textSize="@dimen/title_fontsize"
             android:text="電視"
             android:id="@+id/dianshi"
             android:layout_weight="1"
             android:textColor="@color/navigation_title_color"
             android:background="@color/navigationbar_backround_color"
             android:gravity="center"/>
         <TextView
             android:layout_width="match_parent"
             android:layout_height="@dimen/navigationbar_height"
             android:textSize="@dimen/title_fontsize"
             android:text="動漫"
             android:layout_weight="1"
             android:id="@+id/dongman"
             android:textColor="@color/navigation_title_color"
             android:background="@color/navigationbar_backround_color"
             android:gravity="center"/>
         <TextView
             android:layout_width="match_parent"
             android:layout_height="@dimen/navigationbar_height"
             android:textSize="@dimen/title_fontsize"
             android:text="綜藝"
             android:id="@+id/zongyi"
             android:layout_weight="1"
             android:textColor="@color/navigation_title_color"
             android:background="@color/navigationbar_backround_color"
             android:gravity="center"/>
         </LinearLayout>

         <ImageView
             android:layout_width="match_parent"
             android:id="@+id/Imagezhishiqi"
             android:layout_height="3dp"
             android:background="@color/hot_price_color"/>
     </LinearLayout>

    <com.lt.WBTaoBaoKe.custom.xPullRefresh.XListView
        android:id="@+id/xListView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" android:cacheColorHint="#00000000">
    </com.lt.WBTaoBaoKe.custom.xPullRefresh.XListView>
</LinearLayout>
View Code

下麵貼代碼,有動畫說明的詳細註視

public class HomeFragment_VideoActivity extends Activity implements View.OnClickListener {

    private ListViewAdapter listViewAdapter;
    private ViewPagerAdapter viewPagerAdapter;
    private Context context;
    private LinearLayout.LayoutParams zhishiqilinearParams;
    private int zhishiqiWidth;
    private ImageView zhishiqi;
    private TextView tuijianView;
    private TextView dianying;
    private TextView dianshi;
    private TextView dongman;
    private TextView zongyi;
    private int currentTopItemIndex;
    private TranslateAnimation moveAnimation;
    private int moveStepValue;

    //視頻數據
    private XListView listView;
    private JSONArray CurrentVideoDataArray;
    private int currentVideoPageIndex;
    private String refreshTime = "第一次刷新";
    private ViewGroup.MarginLayoutParams margin;

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = getApplicationContext();
        setContentView(R.layout.home_video_activity);
        //指示器
        zhishiqi = (ImageView) findViewById(R.id.Imagezhishiqi);
        currentTopItemIndex = 1;
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        int width = dm.widthPixels;
        //由於我們分段是固定的5段,所以這裡先使用手機屏幕寬度/5,計算出分段指示器的寬度
        zhishiqiWidth = width / 5;
        //由於在固定佈局中無法準確設置出指示器的寬度,所以這裡需要使用計算出的寬度重新設置指示器寬度
        zhishiqilinearParams = (LinearLayout.LayoutParams) zhishiqi.getLayoutParams();
        zhishiqilinearParams.width = zhishiqiWidth;
        zhishiqi.setLayoutParams(zhishiqilinearParams);
        //下麵都是每個分段裡面顯示文字的textview控制項
        tuijianView = (TextView) findViewById(R.id.tuijianVideo);
        dianying = (TextView) findViewById(R.id.dianying);
        dianshi = (TextView) findViewById(R.id.dianshi);
        dongman = (TextView) findViewById(R.id.dongman);
        zongyi = (TextView) findViewById(R.id.zongyi);

        tuijianView.setTag(1);
        dianying.setTag(2);
        dianshi.setTag(3);
        dongman.setTag(4);
        zongyi.setTag(5);

        tuijianView.setOnClickListener(this);
        dianying.setOnClickListener(this);
        dianshi.setOnClickListener(this);
        dongman.setOnClickListener(this);
        zongyi.setOnClickListener(this);


    }

    //每個分段textview點擊事件
    @Override
    public void onClick(View v) {

        int tag = (Integer) v.getTag();

        //獲得控制項移動的段數確定移動方向,如果是正數表示向右移動,負數左移動
        moveStepValue = tag - currentTopItemIndex;

        switch (tag) {
            case 1:
                if (currentTopItemIndex == 1) {
                    return;
                } else {
                    currentTopItemIndex = tag;

                    tuijianView.setTextColor(this.getResources().getColor(R.color.hot_price_color));

                    dianying.setTextColor(this.getResources().getColor(R.color.white_color));
                    dianshi.setTextColor(this.getResources().getColor(R.color.white_color));
                    dongman.setTextColor(this.getResources().getColor(R.color.white_color));
                    zongyi.setTextColor(this.getResources().getColor(R.color.white_color));

                }
                break;

            case 2:
                if (currentTopItemIndex == 2) {
                    return;
                } else {
                    currentTopItemIndex = tag;


                    tuijianView.setTextColor(this.getResources().getColor(R.color.white_color));

                    dianying.setTextColor(this.getResources().getColor(R.color.hot_price_color));
                    dianshi.setTextColor(this.getResources().getColor(R.color.white_color));
                    dongman.setTextColor(this.getResources().getColor(R.color.white_color));
                    zongyi.setTextColor(this.getResources().getColor(R.color.white_color));


                }
                break;


            case 3:
                if (currentTopItemIndex == 3) {
                    return;
                } else {
                    currentTopItemIndex = tag;


                    tuijianView.setTextColor(this.getResources().getColor(R.color.white_color));

                    dianying.setTextColor(this.getResources().getColor(R.color.white_color));
                    dianshi.setTextColor(this.getResources().getColor(R.color.hot_price_color));
                    dongman.setTextColor(this.getResources().getColor(R.color.white_color));
                    zongyi.setTextColor(this.getResources().getColor(R.color.white_color));
                }
                break;
            case 4:
                if (currentTopItemIndex == 4) {
                    return;
                } else {
                    currentTopItemIndex = tag;


                    tuijianView.setTextColor(this.getResources().getColor(R.color.white_color));

                    dianying.setTextColor(this.getResources().getColor(R.color.white_color));
                    dianshi.setTextColor(this.getResources().getColor(R.color.white_color));
                    dongman.setTextColor(this.getResources().getColor(R.color.hot_price_color));
                    zongyi.setTextColor(this.getResources().getColor(R.color.white_color));
                }
                break;

            default:
                if (currentTopItemIndex == 5) {
                    return;
                } else {
                    currentTopItemIndex = tag;
                    tuijianView.setTextColor(this.getResources().getColor(R.color.white_color));
                    dianying.setTextColor(this.getResources().getColor(R.color.white_color));
                    dianshi.setTextColor(this.getResources().getColor(R.color.white_color));
                    dongman.setTextColor(this.getResources().getColor(R.color.white_color));
                    zongyi.setTextColor(this.getResources().getColor(R.color.hot_price_color));
                }
                break;

        }
        margin = new ViewGroup.MarginLayoutParams(tuijianView.getLayoutParams());
        //Animation.RELATIVE_TO_SELF,  0.0f,這兩個其實是一個參數(合併一起看,表示相對定位+坐標變動值),所以只看2/4/6/8這4個參數
       //第一個值:0.0f表示控制項的原始x坐標不變動。
        //第二個值moveStepValue*0.5f表示原始x坐標前提下變動的值
        //第三個值0.0f表示y坐標變動
        //第四個值0.0f表示原始y坐標前提下變動的值
        //重點:這裡由於我們只是x坐標左右移動,所以y軸的值一隻不變動0.0f 0.0f
        //當moveStepValue為負數時,moveStepValue*0.5f segment是往左移動,正數往右移動,這樣動畫效果才不會有bug,
        moveAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
                Animation.RELATIVE_TO_SELF, moveStepValue * 0.5f, Animation.RELATIVE_TO_SELF,
                0.0f, Animation.RELATIVE_TO_SELF, 0.0f);

        //下麵的代碼是計算動畫的執行時間,如果不計算就會出現切換分段數量不一致,指示器的動畫執行速度太快或太慢。

        if (moveStepValue < 1) {
            moveStepValue = moveStepValue * -1;
        }
        moveAnimation.setDuration(moveStepValue * 70);
        moveAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {

                zhishiqi.clearAnimation();


                //移動效果實現之後,還需要將移動segment分段的margin設置一次,如果不設置動畫又會反回去,為什麼這樣我覺得應該是和android是使用xhtml佈局的原因。
                zhishiqilinearParams.setMargins((currentTopItemIndex - 1) * zhishiqiWidth, margin.topMargin, zhishiqiWidth, zhishiqilinearParams.height);
                zhishiqi.setLayoutParams(zhishiqilinearParams);

            }
        });


        zhishiqi.startAnimation(moveAnimation);
        zhishiqi.setVisibility(View.VISIBLE);
    }
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 背景 之間在一篇介紹過 Table 組件《 React 實現一個漂亮的 Table 》 的文章中講到過,在企業級後臺產品中,用的最多且複雜的組件主要包括 Table、Form、Chart,在處理 Table 的時候我們遇到了很多問題。今天我們這篇文章主要是分享一下 Form 組件,在業務開發中, 相 ...
  • async await 解決非同步問題,這兩個關鍵字是es7提出的,所以測試,node和瀏覽器版本提高一些 async await 操作基於promise實現的 async await這兩個關鍵字是一起使用,分開使用會報錯 await 後面只能跟promise對象 不熟悉的promise非同步操作的朋友 ...
  • 今年6月份開始,我開始負責對“得到app”的android代碼進行組件化拆分,在動手之前我查閱了很多組件化或者模塊化的文章,雖然有一些收穫,但是很少有文章能夠給出一個整體且有效的方案,大部分文章都只停留在組件單獨調試的層面上,涉及組件之間的交互就很少了,更不用說組件生命周期、集成調試和代碼邊界這些最 ...
  • 本文提出的組件化方案demo已經開源,參見文章 "Android徹底組件化方案開源" 。 文末有羅輯思維“得到app”的招聘廣告,歡迎各路牛人加入!! 一、模塊化、組件化與插件化 項目發展到一定程度,隨著人員的增多,代碼越來越臃腫,這時候就必須進行模塊化的拆分。在我看來,模塊化是一種指導理念,其核心 ...
  • 正常在Activity中使用Fragment的生命周期,第一次啟動過程是onAtach()-onCreate()-onCreateView()-onViewCreated()-onActivityCreated()-onStart()-onResume();隨著Activity被退棧銷毀,Fragm ...
  • 綁定服務 右邊部分就是綁定服務的運行過程 這樣綁定的目的就是服務綁定者調用服務的方法,在我的樣例里就是體現為服務訪問者調用服務的show()方法 來張效果圖吧 分析: 1、第一步還是繼承服務類 2、第二步的話就是配置服務 3、第三步就是綁定服務 ...
  • 播放音樂案例 分析: 和上一篇文章的結構是一樣的,只不過我們需要在這裡裡面加上播放音樂的一些操作: 其實也就是調用系統的播放音樂的API而已,寫在服務裡面就好, //媒體播放器 private MediaPlayer player; 第一步,照樣找個類來繼承服務類 第二步,該配置的監聽服務也是要配置 ...
  • service 下圖昨天是沒被綁定的情況,右邊是被綁定的情況 看下測試的效果圖: 程式被關閉,服務還是會在後臺運行,再次運行程式,程式還是能啟動和停止服務 分析: 1、先整個類繼承服務類 2、然後去配置這個服務 fry.myService是上面那個類的路徑 3、再去啟動和停止服務 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...