編輯:關於Android編程
主要是注意平板和手機之間布局的區別:
幾個關鍵的java類
SystemUIService
PhoneWindowManager
WindowManagerPolicy
PhoneStatusBar
TabletStatusBar
NavigationBar
SystemUIService-->onCreate中判斷加載平板布局還是手機布局
[java]
<SPAN style="WHITE-SPACE: pre"> </SPAN>// Pick status bar or system bar.
IWindowManager wm = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
try {
SERVICES[0] = wm.canStatusBarHide()
? R.string.config_statusBarComponent
: R.string.config_systemBarComponent;
} catch (RemoteException e) {
Slog.w(TAG, "Failing checking whether status bar can hide", e);
}
// Pick status bar or system bar.
IWindowManager wm = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
try {
SERVICES[0] = wm.canStatusBarHide()
? R.string.config_statusBarComponent
: R.string.config_systemBarComponent;
} catch (RemoteException e) {
Slog.w(TAG, "Failing checking whether status bar can hide", e);
} 然後在frameworks\base\packages\systemui\res\values\config.xml中
[html] view plaincopyprint?<SPAN style="WHITE-SPACE: pre"> </SPAN><string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.PhoneStatusBar</string>
<string name="config_systemBarComponent" translatable="false">com.android.systemui.statusbar.tablet.TabletStatusBar</string>
<string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.PhoneStatusBar</string>
<string name="config_systemBarComponent" translatable="false">com.android.systemui.statusbar.tablet.TabletStatusBar</string>
然後通過類加載器加載PhoneStatusBar或者TabletStatusBar。也就是手機的狀態欄還是平板的狀態欄。
判斷的關鍵就在wm.canStatusBarHide()這個方法裡面。
我們跳過幾個類後最後跟進到PhoneWindowManager中:
[java]
<SPAN style="WHITE-SPACE: pre"> </SPAN>public boolean canStatusBarHide() {
return mStatusBarCanHide;
}
public boolean canStatusBarHide() {
return mStatusBarCanHide;
} mStatusBarCanHide是一個成員變量,修改它值得地方在:
public void setInitialDisplaySize(int width, int height) {...}中。
[java]
<SPAN style="WHITE-SPACE: pre"> </SPAN>int shortSizeDp = shortSize
* DisplayMetrics.DENSITY_DEFAULT
/ DisplayMetrics.DENSITY_DEVICE;
mStatusBarCanHide = shortSizeDp < 600;
mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
mStatusBarCanHide
? com.android.internal.R.dimen.status_bar_height
: com.android.internal.R.dimen.system_bar_height);
mHasNavigationBar = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_showNavigationBar);
// Allow a system property to override this. Used by the emulator.
// See also hasNavigationBar().
String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
if (! "".equals(navBarOverride)) {
if (navBarOverride.equals("1")) mHasNavigationBar = false;
else if (navBarOverride.equals("0")) mHasNavigationBar = true;
}
int shortSizeDp = shortSize
* DisplayMetrics.DENSITY_DEFAULT
/ DisplayMetrics.DENSITY_DEVICE;
mStatusBarCanHide = shortSizeDp < 600;
mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
mStatusBarCanHide
? com.android.internal.R.dimen.status_bar_height
: com.android.internal.R.dimen.system_bar_height);
mHasNavigationBar = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_showNavigationBar);
// Allow a system property to override this. Used by the emulator.
// See also hasNavigationBar().
String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
if (! "".equals(navBarOverride)) {
if (navBarOverride.equals("1")) mHasNavigationBar = false;
else if (navBarOverride.equals("0")) mHasNavigationBar = true;
}
這個方法略微有點長,繞過前面的判斷,取上面一部分來分析。大致的意思是:
首先取shortSize,shortSize指的是屏幕最短的像素,比如1024*600,那麼值就是600。 shortSizeDp是把pix單位轉化成dip單位。 DisplayMetrics.DENSITY_DEFAULT的值是固定死的160,在更具手機的密度算出shortSizeDp。突出標記的地方就是平板和手機狀態欄切換的關鍵了。只有最短屏幕dp大於600的設備才會加載平板布局。
剩下的代碼用來判斷底部虛擬按鍵是否顯示的關鍵。首先是去讀取frameworks\base\core\res\res\values\config.xml中config_showNavigationBar這個key,下面 SystemProperties.get("qemu.hw.mainkeys")這個屬性主要是給模擬器使用,可以直接忽略掉。
分析完畢!
現在如何切換平板和手機狀態欄布局已經很明了了,就是讓shortSizeDp 的值>=600。以1024*600為例,因為DisplayMetrics.DENSITY_DEFAULT的值已經固定死是160,所以只要把DisplayMetrics.DENSITY_DEVICE的值<=160即可。修改屏幕密度的方法:
/build/tools/buildinfo.sh中設定 ro.sf.lcd_density=160,
當然MTK自己定義了一套屬性,MTK項目中可以通過這個屬性來設置,比較保險
/mediatek/config/[Project_name]/system.prop中設定該屬性的值
如此基本大功告成。mm編譯,然後報錯。。。。
錯誤定位到TabletStatusBar的makeStatusBarView()中,代碼如下:
[java]
<SPAN style="WHITE-SPACE: pre"> </SPAN> try {
// Sanity-check that someone hasn't set up the config wrong and asked for a navigation
// bar on a tablet that has only the system bar
if (mWindowManager.hasNavigationBar()) {
throw new RuntimeException(
"Tablet device cannot show navigation bar and system bar");
}
} catch (RemoteException ex) {
}
try {
// Sanity-check that someone hasn't set up the config wrong and asked for a navigation
// bar on a tablet that has only the system bar
if (mWindowManager.hasNavigationBar()) {
throw new RuntimeException(
"Tablet device cannot show navigation bar and system bar");
}
} catch (RemoteException ex) {
}
問題很明顯,平板設備中不需要NavigationBar,因為NavigationBar的東西已經全部合並到StatusBar裡面了。修改方法:
frameworks\base\core\res\res\values\config.xml中config_showNavigationBar修改為false
啰嗦半天,其實就兩個問題:
一。虛擬按鍵的隱藏和顯示:
修改frameworks\base\core\res\res\values\config.xml中config_showNavigationBar
二。狀態欄平板和手機之間的切換:
1. /build/tools/buildinfo.sh中設定 ro.sf.lcd_density=160,
當然MTK自己定義了一套屬性,MTK項目中可以通過這個屬性來設置,比較保險
/mediatek/config/[Project_name]/system.prop中設定該屬性的值
2. frameworks\base\core\res\res\values\config.xml中config_showNavigationBar修改為false
由於RN在Android平台上不支持gif格式的圖片,今天介紹下我們是怎麼處理這個問題的。先來看看我們需要實現的效果,這是一張gif圖片,當我們列表上拉加載下一頁的時候需
先看看效果圖:問題: 1、下拉列表(因為還沒看到這裡...) 2、標題欄顯示問題 3、按鈕的 Enable 設置 ....
上一節通訊錄原型的實現(-)中,將到了最基本最簡單的通訊錄的實現,這節就講講類似QQ好友列表的分組名稱懸浮在最頂部的實現。我的基本實現思路如下:1.使用Expandabl
我相信,在平時的開發過程中,大家一定會或多或少地接觸到 SQLite。然而在使用它時,我們往往需要做許多額外的工作,像編寫 SQL 語句與解析查詢結果等。所以,適用於 A