1. 程式人生 > >android TranslateAnimation 頂部segment分段移動動畫

android TranslateAnimation 頂部segment分段移動動畫

XML source mar android 實現 sla imp alt cache

這裏實現的功能是從主頁布局的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);
    }
}

android TranslateAnimation 頂部segment分段移動動畫