Android 開發中不得不知道的 Tips 集合 (持續更新 ing)

辰暮發表於2017-05-14

1.sp還是dp?

眾所周知,官方建議我們字型的單位使用sp,這樣使用者在“系統設定”中調整了系統字型大小的時候,我們app中的字型會隨著系統字型的大小而改變。So,眾猿機智的在佈局檔案中寫下了以下程式碼

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="this is text"
        android:textSize="15sp" />複製程式碼

當然上述TextView不會有什麼問題,因為這貨height是自適應的。但是很多情境下,例如ListView或者Recyclerview的item中,高度是固定的時候,sp就會有適配問題,例如

Android 開發中不得不知道的 Tips 集合 (持續更新 ing)

解決方案:
在Application中重寫onConfigurationChanged 強制字型不隨著系統改變而改變(微信也是這麼幹的)

@Override
    public void onConfigurationChanged(Configuration newConfig) {
        if (newConfig.fontScale != 1)//非預設值
            getResources();
        super.onConfigurationChanged(newConfig);
    }

    @Override
    public Resources getResources() {
        Resources res = super.getResources();
        if (res.getConfiguration().fontScale != 1) {//非預設值
            Configuration newConfig = new Configuration();
            newConfig.setToDefaults();
            //設定預設
            res.updateConfiguration(newConfig, res.getDisplayMetrics());
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                createConfigurationContext(newConfig);
            } else {
                res.updateConfiguration(newConfig, res.getDisplayMetrics());
            }
        }
        return res;
    }複製程式碼

2.使用PhotoView+Viewpager崩潰問題

這幾天碰到一個詭異的問題,PhotoView+Viewpager開發圖集效果的時候,在三星Galxy系列手機上手指放大的時候沒問題,手指捏合的時候出現java.lang.IllegalArgumentException: pointerIndex out of range 異常然後閃退。Google了一波,說是三星系統的Bug。。。我等應用層開發汪總不見得給每個三星使用者修改一下底層程式碼吧。

解決方案:
自定義一個Viewpager,重寫onInterceptTouchEvent函式,在裡面捕獲IllegalArgumentException就妥了。

public class PhotoViewPager extends android.support.v4.view.ViewPager {
    public PhotoViewPager(Context context) {
        super(context);
    }

    public PhotoViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        try {
            return super.onTouchEvent(ev);
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        }
        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        try {
            return super.onInterceptTouchEvent(ev);
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        }
        return false;
    }
}複製程式碼

佈局檔案中用PhotoViewPager代替系統原生的ViewPager就好啦。

3.什麼?DatePickerDialog有Bug?

專案中用到了修改使用者生日的功能,打算直接用DatePickerDialog來做一個時間選擇起,然後詭異的事情發生了。使用者選擇完時間之後onDateSelect的回撥函式竟然執行了兩次。原來4.1跟4.2版本有個系統Bug,這時候我們需要重新定義一個DatePickerDialog來遮蔽onStop方法。


public class RepairDatePickDialog extends DatePickerDialog {
    public RepairDatePickDialog(Context context, OnDateSetListener callBack,
                                int year, int monthOfYear, int dayOfMonth) {
        super(context, callBack, year, monthOfYear, dayOfMonth);
        // TODO Auto-generated constructor stub
    }

    public RepairDatePickDialog(Context context, int theme,
                                OnDateSetListener callBack, int year, int monthOfYear,
                                int dayOfMonth) {
        super(context, theme, callBack, year, monthOfYear, dayOfMonth);
        // TODO Auto-generated constructor stub
    }

    protected void onStop() {
        // TODO Auto-generated method stub
    }
}複製程式碼

4.瀏覽器中開啟自家App的那些套路

大體的需求是使用者分享出去連線,被分享的使用者在瀏覽器中開啟此連線,如果該使用者裝置上有我們的app則吊起app,如果沒有則通知使用者去下載我們的app
之前寫過一片部落格,詳細的介紹了這種Deeplink的實現方式,請移步
juejin.im/entry/590fe…
github地址
github.com/weixinjie/D…

5.Android路由機制淺析

大廠的客戶端裡面都用了路由來實現頁面之前的跳轉,引入路由機制並不全是為了頁面之間的解耦合,更多的是為了配合運營的套路。例如:大部分app裡面都有Banner,這個Banner不一定全是開啟Webview。有的Banner item開啟的是充值頁面,有的Banner item開啟的是使用者詳情頁面等。當然你可以為了Banner來寫一個Map集合,每次使用者點選Banner的時候Switch一下type,然後開啟相應的頁面,但是如果使用者在瀏覽器中Deeplink到本地客戶端呢?是不是也要實現一套Map?如果是在Webview中與js互動開啟各個頁面呢?是不是還要實現一套Map?

推薦一個很好用的路由框架
github.com/mzule/Activ…
後期我會獻上這個庫的原始碼解析。

相關文章