2015年2月8日 星期日

Android 開發(八十) kotlin GettingStart

什麼是kotlin?

http://kotlinlang.org/

kotlin settingup

http://kotlinlang.org/docs/reference/using-gradle.html

如何將程式碼轉換















轉換後的結果















要學kotlin其實就像是必須學新的語言,雖然必須花點時間才能學會but...
學會之後的好處還蠻多的,例如我相信下面的程式碼是大多數人會遇到的情況

    val obj2: MyObject? = null
        obj2?.getMethod("2")


    MyObject obj2 = null;
    obj2.getMethod("2");
        
第一個程式碼並不會crash,但是第二個程式碼會crash, 原因是並沒有做null check,
在這裡使用kotlin的好處就是....我們再也不需要寫一堆if來判斷是否為null
學會了kotlin之後
 if(data !=null && data.list !=null && data.list.get(0).name) 
相信這樣的程式碼就不會再出現了 bravo!!

2015年1月7日 星期三

Android 開發(七十九) How to handle Deeplinking in Android (Facebook, Native Browser)


前陣子facebook改版,導致我們的deeplinking的功能無法使用, 當時有想出一個暫時的解法,不過這幾天facebook再度改版,之前的做法又不能用了,這是只好花點時間來看文件找解法,最後有找到一些相關的解決方法,在這邊分享給各位


facebook deeplinking

關於facebook deeplinking 在最近一次改版之後,假設沒有按照facebook官方文件設定的話,都會出現粉絲頁無法載入的問題,所以我們只好依照官方文件實作了

<head>
    ...
    <meta property="al:android:url" content="sharesample://story/1234">
    <meta property="al:android:package" content="com.facebook.samples.sharesample">
    <meta property="al:android:app_name" content="ShareSample">
    ...
</head>

在html的header加入上面這些meta即可,
基本上我覺得主要是看al:android:url 裡面的參數
其他兩個似乎沒什麼用處(for now)

如上範例,在app的activity裡面就必須要有對應的code

<activity android:name=".MainActivity"
    android:label="@string/app_name" >
    ...
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="sharesample" />
    </intent-filter>
</activity>

基本上這樣實作之後facebook導頁就不會有問題了.....
but....內建的browser還是不會work啊怎麼辦??


Native Browser

在google 文件的深處,有一個關於deep linking文件裡面有教我們該如何做相關的導頁動作

<a href="intent://gizmos#Intent;scheme=example;package=com.example.android;end;">example://gizmos</a>
只要點擊網頁中的超連結就可以開啟監聽特定scheme的app了

but......deeplink就是希望user點擊完某特定連結之後就可以直接開啟app啊!!!
怎麼能夠讓user再點完一次連結之後再點令一次連結呢?

相信有做過實驗的人都知道使用 window.location 和  setTimeout
在內建瀏覽器是不work的,那.......該怎麼辦?

<meta http-equiv="refresh" content="5;url=intent://gizmos#Intent;scheme=example;package=com.example.android;end;/>




將上面的meta加到header裡就可以完成自動導頁的功能囉!!!

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再花點時間研究程式碼之後的成果

2014年11月26日 星期三

Android 開發(七十六) split icon effect

不知道大家有沒有看過這個影片




裡面的這個這個劈腿真的很厲害,
所以我也希望我們的android icon也可以做到類似的問題
恩....扯得有點遠了XD

其實我只是想做到將一張圖片分開的特效XD 如下圖


這個特效其實概念很簡單,首先將我們的image 切成四個等分,
之後利用移動的距離來分別移動我們四個bitmap即可

首先,我們遇到的第一個問題是該如何將一張完整個圖片分成四個等分?


    private Bitmap createRightUp() {
        Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        Canvas myCanvas = new Canvas(bitmap);
        myCanvas.clipRect(new Rect(getWidth() / 2, 0, getWidth(), getHeight() / 2));
        super.onDraw(myCanvas);
        return bitmap;
    }

首先我們必須先創建一個跟圖一樣大小的bitmap,接著利用clipRect將圖裁減成希望的大小或者圖型,向我這邊就是裁減出右上角的圖,當我call super.onDraw時就會將圖片畫在我的bitmap上,接著我們只需要將我的bitmap畫在view的canvas上即可
canvas.drawBitmap(rightup, deltaY, -deltaY, null);

第一個問題這樣就解決了,那麼接下來是第二個問題
我該怎麼讓四張bitmap移動?

首先我們可以利用touchevent來計算出移動的距離,
然後我們只需要將bitmap畫在canvas上的位置做相對的移動即可也就是
canvas.drawBitmap(rightup, deltaY, -deltaY, null);
裏的deltaY

這樣就可以完成我們想要的功能了

講了那麼多,最後還是附上sample