2014年12月18日 星期四

Android 開發(七十八) GoogleCalendar ListView


不知道大家是否有看過這個特效,在滑動的時候listview裡面的圖片會跟著畫面移動
如下圖


第一次看到的時候真的覺得這個特效很特別,很想知道怎麼做的,
所以就花了幾天研究了這個功能.

在經過了初步的研究之後,發現這個功能應該很容易可以達到,

首先需要抓到該 item在畫面的位置,接著只需要針對位置做相對應的滑動即可,

所以列了兩個任務

  1. 可滑動的ImageView
  2. 抓到item在畫面中的位置

關於可滑動的ImageView
一開始的想法是 SlideImage_FirstVersion 
利用改變drawBitmap top的 position來改變圖片顯示的高度,
這個方法實際用起來的感覺有點頓頓的,所以後來這個寫法就被改寫了

第二個想法是 SlideImage_SecondVersion
利用改變scrollY 去改變可視的範圍
這個方法看起來是可行的,也不會造成額外的performance issue

當完成了上面的功能時,我以為可以很快的完成這個功能,
殊不知困難的會是在第二點,如何抓到item在畫面中的位置是非常困難的,

一開始是使用 recyclerView.getChildAt(index).getTop()
在看了debug log之後就知道這個方法是行不通的,這個方法取得的getTop並不是某個index的view的高度. 所以必須另尋他法,

接著使用了getLocationInWindow(location); 
這個方法也行不通,取得的高度也不是所預想的高度
在所有的方法都不可行的情況下,只好先暫緩這個功能的開發.

就在暫停開發的隔天,在逛Github的時候碰巧看到了ItemDecoration的 implements
覺得很有趣所以就稍微點進去看了一下,
不看還好,看了一下就發現這不就是我尋找已久的解法嗎,
就可以取得view的位置.

有了這兩項工具,就可以完成該功能了

最後,附上該 openSource

https://github.com/nightbear1009/GoogleCalendarListView

2014年12月15日 星期一

AngularJS - two way binding

小弟跟Html 以及javascript其實是完全不熟,由於最近公司有提供AngularJS的教程,
小弟從以前就對網頁就有極大的興趣但是一直找不到機會切入這個領域,所以這次就順便去學了AngularJS,在這邊就稍微記錄一些筆記囉!!


今天要講的是Binding的功能,由於以前就寫過windows app 所以對於binding這個功能並不陌生,binding有分為 one-way binding ,two-way binding, one-time binding
one-way binding 和 two-way binding最大的差別就是在於,資料被設定之後是否會被更新到view ,

例如  sample 的輸入框被鍵入文字時,顯示框會同時顯示鍵入的文字,
這個就是two-way binding 的功能

至於 one-time binding 在於,該資料只會被設定一次,之後就不會再被更動.

2014年12月2日 星期二

Android 開發(七十七) Activity Animations

先看一下下面的功能


我相信大部分的人都知道在5.0的時候有新增一個新的activity transaction的功能
讓我們可以在Activity 替換之間有一些動畫,but......what about 5.0以下呢?

今天就是要來說我們如何可以在5.0以下完成這個功能
首先我們可以將這個動作分成兩個部分
1.enter animation
2.exit animation

Enter animation

首先我們先看enter animation ,讓我們將速度放慢再看一次


我相信仔細看之後可以發現,enter animation(粉紅色塊)
其實是從button大小漸漸地放大到整個畫面,

所以我們要做的事情其實很簡單


  • 先將下一個view縮小到跟button一樣大的size
  • 將view恢復到跟原本的view一樣大的size


but 我們是要startActivity耶,這並不是單純的把view 縮小並且恢復正常而已
所以必須要有額外的步驟

1.首先我們必須取消activity原本的transaction功能

            // Override transitions: we don't want the normal window animation in addition
            // to our custom one
            overridePendingTransition(0, 0);


所以我們必須 開啟粉紅色activity之後呼叫上面的程式碼,避免startactivity之後的default animation

2.接著我們必須將下一個activity用成透明的

    <style name="Transparent"  parent="android:Theme.Holo.Light.DarkActionBar">>

        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
    </style>


3.接著就到了將view縮小到跟button一樣大然後再慢慢恢復的動作了
為了達到這個目的我們必須先取得button的位置以及size

        int[] screenLocation = new int[2];
        view.getLocationOnScreen(screenLocation);
        intent.putExtra("left", screenLocation[0]).
                putExtra("top", screenLocation[1]).
                putExtra("width", view.getWidth()).
                putExtra("height", view.getHeight());


然後再將粉紅色activity的view 轉換到跟button一樣大的size和一樣的起始位置,

        mView.setPivotX(0);
        mView.setPivotY(0);
        mView.setScaleX(mWidthScale);
        mView.setScaleY(mHeightScale);
        mView.setTranslationX(mLeftDelta);
        mView.setTranslationY(mTopDelta);

setPivotX/setPivotY  設定animation的動畫起始點,
setScaleX/setScaleY 將粉紅色的view縮小到跟button一樣大
setTranslationX/setTranslationY 將粉紅色的view移動到跟button一樣的位置
在初始設定完成之後,接著就是要將他恢復到原本的大小

      mView.animate().setDuration(duration).
                scaleX(1).scaleY(1).
                translationX(0).translationY(0).
                setInterpolator(sDecelerator);


這部分就相對簡單許多.
這樣enter animation的部分就完成了
接下來就要談exitAniamtion

Exit animation


exit animation相對於enter animation單純許多,
我們要做的動作就是

1.將粉紅色的view縮小到button的size以及位置並且漸漸的變透明
2.finish activity

所以程式碼如下


        mView.animate().setDuration(duration).
                scaleX(mWidthScale).scaleY(mHeightScale).
                translationX(mLeftDelta).translationY(mTopDelta);

        ObjectAnimator bgAnim = ObjectAnimator.ofFloat(mView, "alpha", 0);
        bgAnim.setDuration(duration);
        bgAnim.start();


這個動作就是將粉紅色的view縮小並位移到button的位置,
接著將activity finish掉即可


最後附上sourceCode

reference可以去參考Chet Haase 的
https://www.youtube.com/watch?v=CPxkoe2MraA
基本上這篇文章是聽完他的youtube再花點時間研究程式碼之後的成果