1. android怎樣優雅的動態改變整個application的theme
Android中實現theme主題可以使用在activity中晌祥使用setTheme(int)的方法,SDK中對此方法的說明為:
//Set the base theme for this context. Note that this should be called before any views are instantiated in the Context (for example before calling android.app.Activity.setContentView or android.view.LayoutInflater.inflate).
//需要在setcontentview函數或者inflate函數之前使用。
效果圖如下:
實現步驟:
首先需要定義一個屬性,此屬性用於賦值給控制項的屬性,相當於控制項屬性值的「變數」。
在attrs.xml中,定義三個屬性,屬性的format均為reference|color
<resources>
<attr name="button_bg" format="reference|color" />
<attr name="activity_bg" format="reference|color" />
<attr name="text_cl" format="reference|color" />
</resources>
接下來,在styles.xml中,編寫自定義的Theme
<style name="AppBaseTheme" parent="android:Theme.Light">
</style>
<style name="AppTheme" parent="AppBaseTheme">
<item name="text_cl">#ffffff</item>
<宴鎮搏item name="button_bg">#000000</item>
<item name="activity_bg">#ffffff</item>
</style>
<style name="DarkTheme" parent="AppBaseTheme">
<item name="text_cl">#000000</item>
<item name="button_bg">#ffffff</item>
<item name="activity_bg">#000000</item>
</style>
選擇一種模式旅顫作為程序的默認theme,注意:由於我是在layout布局文件中定義的view的樣式,因此,為了保證theme切換時不會出現找不到資源的問題,因此需要在每一種用到的自定義theme中,都加上item。這里的item如text_cl和view的textColor屬性的format是一致的。
Android manifest文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testandroidsettheme"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:name="com.example.testandroidsettheme.app.MyApp"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.testandroidsettheme.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
2. Android系統自帶樣式Theme總結
本文從網上復制,給自己做筆記的,摘自: http://blog.csdn.net/hongya1109110121/article/details/11985545
Android系統自帶樣式(@android:style/) (轉)
1 android:theme="@android:style/Theme.Holo.Light.NoActionBar.Fullscreen"
布局頁面最上面 不會顯示 android:icon="@drawable/ic_launcher"中的值和android:label="@string/app_name"的值。
2 android:theme="@style/AppTheme"
布局頁面最上面 顯示 android:icon="@drawable/ic_launcher"中的值和android:label="@string/app_name"的值。
其他
在AndroidManifest.xml文件的activity中配置
1、android:theme="@android:style/Theme"
默認狀態,即如果theme這里不填任何屬性的時候,默認為Theme
2、android:theme="@android:style/Theme.NoDisplay"
任何都不顯示。比較適用於只是運行了activity,但未顯示任何東西
3、android:theme="@android:style/Theme.NoTitleBar「
背景主題的沒有標題欄的樣式,默認如果沒有設置的話,顯示黑背景
4、android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
背景主題的沒有標題欄且全屏的樣式,默認為黑背景
5、android:theme="@android:style/Theme.Black"
默認狀態下黑背景
6、android:theme="@android:style/Theme.Black.NoTitleBar"
黑背景主題的沒有標題欄的樣式
7、android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
黑背景主題的沒有標題欄且全屏的樣式
8、android:theme="@android:style/Theme.Light"
默認狀態下亮背景,與上述黑背景Theme.Black相反
9、android:theme="@android:style/Theme.Light.NoTitleBar"
亮背景主題的沒有標題欄的樣式,與Theme.Black.NoTitleBar相反
10、android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen"
亮背景主題的沒有標題欄且全屏顯示的樣式,與Theme.Black.NoTitleBa.Fullscreenr相反
11、android:theme="@android:style/Theme.Dialog"
對話框樣式 將整個activity變成對話框樣式出現
12、android:theme="@android:style/Theme.InputMethod"
Window animations that are applied to input method overlay windows
13、android:theme="@android:style/ Theme.Panel"
刪除掉所有多餘的窗口裝飾,在一個空的矩形框中填充內容,作用范圍相當於把dialog中的所有元素全部去掉,只是一個空的矩形框,且此為默認的樣式
14、android:theme="@android:style/ Theme.Light.Panel"
刪除掉所有多餘的窗口裝飾,在一個空的矩形框中填充內容,作用范圍相當於把dialog中的所有元素全部去掉,只是一個空的矩形框,且默認是light的樣式
15、android:theme="@android:style/Theme.Wallpaper"
使用牆紙做主題,默認狀態。
16、android:theme="@android:style/ Theme.WallpaperSettings"
使用牆紙做主題,默認是使用將上一個界面調暗之後作為主題
17、android:theme="@android:style/ Theme.Light.WallpaperSettings"
使用牆紙做主題,默認Light狀態
18、android:theme="@android:style/Theme.Wallpaper.NoTitleBar"
使用牆紙做主題,且沒有標題欄
19、android:theme="@android:style/Theme.Wallpaper.NoTitleBar.Fullscreen"
使用牆紙做主題,且沒有標題欄,且全屏顯示
20、android:theme="@android:style/Theme.Translucent"
半透明狀態下的背景,將運行此activity之前的屏幕作為半透明狀態作為此activity運行時的樣式。
21、android:theme="@android:style/Theme.Translucent.NoTitleBar"
半透明狀態下沒有標題欄的背景,將運行此activity之前的屏幕作為半透明狀態作為此activity運行時的樣式。
22、android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"
半透明狀態下沒有標題欄且全屏的背景,將運行此activity之前的屏幕作為半透明狀態作為此activity運行時的樣式。
摘自: http://blog.csdn.net/hongya1109110121/article/details/11985545
3. Android APP啟動白(黑)屏解決方案(適用於App啟動立即展現logo、版權等)
Android APP啟動白(黑)屏解決方案(適用於App啟動立即展現logo、版權等)
我們要求在App啟動時顯示我們設置的啟動頁面,實測發現打開app的時候,會有短暫的1秒--2秒的白屏或者黑屏,然後才進入到程序界面。
簡單高效的解決方案一:
1、使用layer-list製作背景樣式
新建bg_start_pic.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 設置整個屏幕背景為白色 -->
<item>
<color android:color="@color/white" />
</item>
<!-- 中間logo -->
<item
android:width="@dimen/dp_150"
android:height="@dimen/dp_150"
android:gravity="center">
<bitmap android:src="@drawable/icon_splash_logo" android:gravity="center" />
</item>
<!-- 底部圖表 -->
<item
android:bottom="10dp"
android:gravity="bottom|center_horizontal">
<bitmap android:src="@drawable/pic_banner_home" />
</item>
</layer-list>
2、修改styles.xml文件
增加SplashTheme主題
<style name="SplashTheme" parent="AppTheme">
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@drawable/bg_start_pic</item>
</style>
3、修改AndroidManifest.xml
LauncherActivity使用StartAppTheme主題
<activity
android:name=".LauncherActivity"
android:label="@string/app_name"
android:theme="@style/StartAppTheme" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
4. 如何讓手機主頁背景變成攝像頭代碼
android攝像頭去背景代碼,Android《第一行代碼》-調用攝像頭拍照問題解決
說明:由於在測試的時候使用的是Android 7.1的機器,代碼會出現以下問題,
(1)APP安裝在機器上實測會出現調用相機無法打開的現象;
(2)APP調用裁剪工具的時候會有Toast提示「無法載入此圖片」。
Step 1. 新建一個activity_main.xml布局,這個沒什麼問題。
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:id="@+id/take_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="拍照"/>
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"/>
Step 2. 新建MainActivity,以毀伏下是郭霖大神書中原來的代碼。代碼中比較難以理解的地方注釋都寫的很詳細。
public class MainActivity extends AppCompatActivity {
public static final int TAKE_PHOTO = 1;
public static final int CROP_PHOTO = 2;
private Button takePhoto;
private ImageView imageView;
private Uri imageUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
takePhoto = (Button)findViewById(R.id.take_photo);
imageView = (ImageView)findViewById(R.id.image_view);
takePhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
File outputImage = new File(Environment.getExternalStorageDirectory(),
"maybe.jpg");
if(outputImage.exists()){
outputImage.delete();
}
try {
outputImage.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
//將File對象轉換成Uri對象,因為Uri對象標識著maybe.jpg這張圖片的唯一地址。
//由纖輪攜於Intent能傳遞的數據空間有桐喊限,所以需要轉化成Uri
//大圖片用Uri,小圖片用Bitmap
//以下代碼解決了Android 7.0 打開相機崩潰的問題
if(Build.VERSION.SDK_INT > 24){
imageUri = FileProvider.getUriForFile(MainActivity.this,
"com.example.android.choosepicdemo.fileprovider",outputImage);
}else{
imageUri = Uri.fromFile(outputImage);
}
//Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
//第一個參數:一個Intent對象
//第二個參數:如果> = 0,當Activity結束時requestCode將歸還在onActivityResult()中,
//以便確定返回的數據是從哪個Activity中返回
startActivityForResult(intent,TAKE_PHOTO);
}
});
}
/*第一個參數:這個整數requestCode提供給onActivityResult,是以便確認返回的數據是從哪個Activity返回的。
這個requestCode和startActivityForResult中的requestCode相對應。
第二個參數:這整數resultCode是由子Activity通過其setResult()方法返回。
第三個參數:一個Intent對象,帶有返回的數據。*/
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case TAKE_PHOTO:
if(resultCode == RESULT_OK){
Intent intent = new Intent("com.android.camera.action.CROP");
//以下兩行代碼適配Android 7.0 解決了無法載入圖片的問題
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.setDataAndType(imageUri,"image/*");
intent.putExtra("scale",true);
intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
startActivityForResult(intent,CROP_PHOTO);
}
break;
case CROP_PHOTO:
if(resultCode == RESULT_OK){
// 因為imageUri是Uri類型的,需要轉換才能被decodeStream使用
// 使用getContentResolver()
// 因為在Android系統裡面,資料庫是私有的。
// 一般情況下外部應用程序是沒有許可權讀取其他應用程序的數據。
// 如果你想公開你自己的數據,你有兩個選擇:
// 你可以創建你自己的內容提供器(一個ContentProvider子類)或者
// 你可以給已有的提供器添加數據-如果存在一個控制同樣類型數據的內容提供器且你擁有寫的許可權。
// 外界的程序通過ContentResolver介面可以訪問ContentProvider提供的數據,
// 在Activity當中通過getContentResolver()可以得到當前應用的 ContentResolver實例
try {
//解析成Bitmap
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
imageView.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
break;
default:
break;
}
}
}
需要注意的是以下代碼是增加了的內容:
//以下代碼解決了Android 7.0 打開相機崩潰的問題
if(Build.VERSION.SDK_INT > 24){
imageUri = FileProvider.getUriForFile(MainActivity.this,
"com.example.android.choosepicdemo.fileprovider",outputImage);
}else{
imageUri = Uri.fromFile(outputImage);
}
如果不這么處理的話,會導致在調用相機獲取 Uri 的時候發生崩潰。
原因很明顯,file:// 不被允許作為一個附加的 Uri 的意圖,否則會拋出 FileUriExposedException 。其實背後有一個很好的理由,如果文件路徑被發送到目標應用程序(相機應用程序在這種情況下),文件將完全訪問通過相機應用程序的過程,而不僅僅只有發起者能收到。但讓我們考慮一下,實際上是由我們的應用程序去啟動攝像頭拍照,並保存作為我們的應用程序的代表文件。因此,該文件的訪問許可權應該是我們的應用程序而不是攝像頭應用程序本身。這就是為什麼現在 file:// 在 targetSdkVersion 24 中要求每一位開發者都去完成這個任務。參考博文:http://www.sohu.com/a/136282885_659256
所以需要採用FileProvider來處理。
具體的步驟如下:
首先在AndroidManifest.xml中聲明provider。這里要注意android:authorities要是你的包名一致,其他固定。
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
android:authorities="com.example.android.choosepicdemo.fileprovider"
android:name="android.support.v4.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
在res文件夾下創建xml文件夾,並創建provide_paths.xml(該名稱應與上述android:resource里一致),maybe為圖片保存時的名稱,根據你自己命名而定。
修改java代碼如下
//以下代碼解決了Android 7.0 打開相機崩潰的問題
if(Build.VERSION.SDK_INT > 24){
imageUri = FileProvider.getUriForFile(MainActivity.this,
"com.example.android.choosepicdemo.fileprovider",outputImage);
}else{
imageUri = Uri.fromFile(outputImage);
5. 如何修改Android App的樣式風格
android中可以自定義主題和風格。風格,也就是style,我們可以將一些統一的屬性拿出來,比方說,長,寬,字體大小,字體顏色等等。可以在res/values目錄下新建一個styles.xml的文件,在這個文件裡面有resource根節點,在根節點裡面添加item項,item項的名字就是屬性的名字,item項的值就是屬性的值,如下所示:
復制代碼 代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyText" parent="@android:style/TextAppearance">
<item name="android:textColor">#987456</item>
<item name="android:textSize">24sp</item>
</style>
</resources>
style中有一個父類屬性parent, 這個屬性是說明當前的這個style是繼承自那個style的,當然這個style的屬性值中都包含那個屬性中的,你也可以修改繼承到的屬性的值,好了,style完成了,我們可以測試一下效果了,先寫一個布局文件,比如說一個TextView什麼的,可以用到這個style的。這里我就寫一個EditText吧。下面是布局文件:
復制代碼 代碼如下:
<?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">
<EditText
android:id="@+id/myEditText"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="@style/MyText"
android:text="測試一下下"/>
</LinearLayout>
說完了style,下面就說說Theme,Theme跟style差不多,但是Theme是應用在Application或者Activity裡面的,而Style是應用在某一個View裡面的,還是有區別的,好了,廢話不多說,還是看代碼吧。下面的是style文件:
復制代碼 代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyText" parent="@android:style/TextAppearance">
<item name="android:textColor">#987456</item>
<item name="android:textSize">24sp</item>
</style>
<style parent="@android:style/Theme" name="CustomTheme">
<item name="android:windowNoTitle">true</item>
<item name="android:windowFrame">@drawable/icon</item>
<item name="android:windowBackground">?android:windowFrame</item>
</style>
</resources>
style中有一個父類屬性parent, 這個屬性是說明當前的這個style是繼承自那個style的,當然這個style的屬性值中都包含那個屬性中的,你也可以修改繼承到的屬性的值,好了,style完成了,我們可以測試一下效果了,先寫一個布局文件,比如說一個TextView什麼的,可以用到這個style的。這里我就寫一個EditText吧。下面是布局文件:
復制代碼 代碼如下:
<?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">
<EditText
android:id="@+id/myEditText"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="@style/MyText"
android:text="測試一下下"/>
</LinearLayout>
說完了style,下面就說說Theme,Theme跟style差不多,但是Theme是應用在Application或者Activity裡面的,而Style是應用在某一個View裡面的,還是有區別的,好了,廢話不多說,還是看代碼吧。下面的是style文件:
復制代碼 代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyText" parent="@android:style/TextAppearance">
<item name="android:textColor">#987456</item>
<item name="android:textSize">24sp</item>
</style>
<style parent="@android:style/Theme" name="CustomTheme">
<item name="android:windowNoTitle">true</item>
<item name="android:windowFrame">@drawable/icon</item>
<item name="android:windowBackground">?android:windowFrame</item>
</style>
</resources>
可以看到這里寫了一個繼承自系統默認的Theme的主題,裡面有3個屬性,這里強調一下第三個屬性的值的問題,這里打個問號,然後加前面的一個item的名字表示引用的是那個名字的值,也就是那個名字對應的圖片。
然後我們在Manifest.xml裡面的Application裡面加一個Theme的屬性,這個屬性對應的就是我們上面寫的Theme。
復制代碼 代碼如下:
<application android:icon="@drawable/icon" android:label="@string/app_name"
android:theme="@style/CustomTheme">
<activity android:name=".TestStyle"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
上面的代碼沒有標題欄,背景和fram都是我們設置的圖片。當然也可以在代碼中設置主題:
復制代碼 代碼如下:
package com.test.shang;
import android.app.Activity;
import android.os.Bundle;
public class TestStyle extends Activity {
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.CustomTheme);
setContentView(R.layout.test_style);
}
}
6. 記一次使用Android AppCompat(兼容庫)的Theme所引發的思考
最近在優化App,首先從界面上優化,對所有頁面的ui繪制進行查看和優化,其中發現在
Api 小於21的手機設備上的效果圖為:
運行在Api大於21的設備上的效果圖為:
同樣是使用統一兼容主題
在圖1中發現了過度繪制現象。就是這一端綠色的區域。可我們的完全定義的是全屏的啊?為什麼會出現這種情況呢。
在解釋上面現象之前,首先了解下Android使用Theme的正確用法:
Android的Theme的主要來源分為以下三種:
這里主要探討前兩者,自定義主題不做探討,使用Android系統自帶的Theme要加上"android:",如:android:Theme.Light,使用v7兼容包的主題就不需要前綴了,直尺灶接:Theme.AppCompat。現在看看有哪些主題:
1.系統自帶主題:
Theme.AppCompat主題是兼容主題,是什麼意思呢?
意思就是說如果運行程序在手機API是21則就是相當於使用Material主題,如果運行程序的手機API是11則就相當於使用Holo主題,以此類推。
兼容v7會被Google公司不斷升級:
比如appcompat-v7-21.0表示升級到向API 21兼容
比如appcompat-v7-23.2表示升級到向API 23兼容
所以要使用最新的兼容包。
我們已經知道了統一使用兼容包的話,目標設備API 為21及以上時會使用Material主題,API 為11時使用Holo主題,下面我們來比較下Material與Holo主題高困和的區別:
通過比較發現Holo主題的windoContentOverlay使用ab_solid_shadow_holo為背景,而Material未設置任戚盯何背景。再來看下windoContentOverlay是何許人也,查看源碼得知:
onCreate()中設置的Window.FEATURE_NO_TITLE對應的窗口修飾布局文件為screen_simple.xml:
windowContentOverlay代表content的foreground並且填充寬,位於content的頂部,代表內容區域頂部的陰影背景(與TitleBar和ActionBar都沒有關系),因為這種屬性是在無標題欄的時候才會被設置到content的top,所以有標題欄或者actionBar時也不會出現這種情況。現在問題就迎刃而解了,修改Theme為:
增加<item name="android:windowContentOverlay">@null</item>
7. 如何在 Android 應用程序中使用自定義主題
在Android中,定義外觀最簡單的方式是直接設置屬性在視圖對象上。由於要對整個應用程序設置樣式,這種方法就顯得不是很方便了。因此,我們可以創建 樣式來綁定視圖屬性。但要注意的是,樣式只能設置在xml里。這意味著,我們在創建/載入視圖的時候,只能一次設置一個樣式。下面是如何在res /values/styles.xml文件中給TextView設置屬性的示例。 <style name="CustomText" parent="<a href="http" target="_blank" rel="nofollow">@android</a> :style/TextAppearance.Medium"> <item name="android:textSize">20sp</item> <item name="android:textColor">#008</item> </style> 我們引用@style/CustomText樣式應用在我們的layout.xml文件中。該樣式引用了一個父樣式 @android:style/TextAppearance.Medium。由於開始樣式引自android: 命名空間,那麼我們這個樣式默認也隨android平台。 創建主題綁定樣式 假設我們要改變我們所有TextView的文字大小和顏色,並且不需要明確設置每一個TextView。這是一個非常常見的情況,幸運的 是,Android提供了一個非常強大的主題機制。從本質上講,主題就是樣式資源本身,使用「key」指向具體的樣式。一個視圖對象基於這個key可以查 看到具體的樣式。下面是一個簡單的例子,在res/values/themes.xml文件: <style name="Theme.MyApp" parent="<a href="http" target="_blank" rel="nofollow">@android</a> :style/Theme.Holo"> <item name="android:textAppearance">@style/CustomText</item> </style> 如上所述,主題是樣式資源本身,所以我們聲明一個Theme.App繼承自Android平台提供的holo主題。我們將我們的CustomText樣式 指定到android:textAppearance屬性。屬性就是一個預定義的「變數」,它可以被其他資源元素引用。事實上,它也可以創建自定義屬性在 res/values/attr.xml文件。 現在有趣的事情來了。我們的主題Theme.MyApp不僅可以通過AndroidManifest.xml的設置應用到Activity上,它也可以在 運行時在代碼中設置。你將不得不重新啟動當前Activity(或使用ContextWrapper應用UI的主題部分),但它使主題更加動態。
8. 安卓怎麼修改系統「DIALOG」風格
具體步驟如下:
1編寫一個文本樣式。
DIALOG的標題是一個textview,在sytles.xml中,添加如下代碼來設置你自己的文本樣式:
<style name="DialogWindowTitle">
<item name="android:textSize">22sp</item>
<item name="android:textColor">@color/font_dark_grey</item>
</style>
2設置對話框的標題主題。
上面的標題文本並不能直接設置譽笑緩為對話框的標題樣式。 我們還需要編寫一個表示標題的主題的style,在這里指定標題的文本樣式慶模。代碼如下:
<style name="DialogWindowTitle.DeviceDefault">
<item name="android:maxLines">1</item>
<item name="android:scrollHorizontally">true</item>
<item name="android:textAppearance">@style/DialogWindowTitle</item>
</style>
3設置對話框主題。
接下來,我們編寫我們的對話框主題,在這里指定標題的主題。由於一些屬性並不是public的,所以我們需要繼承自原來的某個style,代碼如下:
<!--Dialog主題-->
<style name="Theme.DeviceDefault.Dialog" parent="@android:style/Theme.DeviceDefault.Light.Dialog">
<item name="android:windowTitleStyle">@style/DialogWindowTitle.DeviceDefault</item>
</style>
4自定義App的主題。
接下來,我們需要在我們的App theme中指定我們的對話框使用這種主題,所以需要定義一個App theme。同樣由於App theme的許多屬性並不是public的(比如下面要提到的標題下面的那條藍線),所以我們要繼承自一個原生的style。這里我根據程序需要選擇了Theme.Holo.Light.NoActionBar,代碼如下:
<style name="ParkingTheme" parent="@android:style/Theme.Holo.Light.NoActionBar">
<item name="android:dialogTheme">@style/Theme.DeviceDefault.Dialog</item>
</style>
5指定App主題
我們需要在升顫AndroidManifest.xml文件中,指定我們的app主題。這步很簡單,只需要在application標簽中指定android:theme的值即可,如下:
android:theme="@style/ParkingTheme"
6編寫AlertDialog主題。
我們無法直接繼承系統主題里的AlertDialog的style。如把parent指定為Theme.DeviceDefault.Dialog.Alert,Theme.Holo.Dialog.Alert,Theme.DeviceDefault.Light.Dialog.Alert或Theme.Holo.Light.Dialog.Alert,都會導致編譯不過。所以我們需要繼承自Dialog的style。在這里我以Theme.Holo.Light.Dialog為例,代碼如下:
<!--AlderDialog主題-->
<style name="Theme.DeviceDefault.Dialog.Alert" parent="@android:style/Theme.Holo.Light.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowTitleStyle">@style/DialogWindowTitle.DeviceDefault</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
</style>
7指定AlertDialog的主題。
我們需要在第4步所說的自定義的AppTheme中,添加一行代碼來指定要使用的AlertDialog的style,代碼如下:
<item name="android:alertDialogTheme">@style/Theme.DeviceDefault.Dialog.Alert</item>
8修改標題下面的藍色線。
表示這條藍色的線的叫做titleDivider,我們可以通過getResources()的API來獲取它的IP,然後設置顏色。代碼如下:
public static final void dialogTitleLineColor(Dialog dialog, int color) {
Context context = dialog.getContext();
int divierId = context.getResources().getIdentifier("android:id/titleDivider", null, null);
View divider = dialog.findViewById(divierId);
divider.setBackgroundColor(color);
這行代碼對於自定義的Dialog,可以在setContentView之後調用。但是對於AlertDialog,必須在show()方法被調用之後才可以去調用,否則會報錯。
9. Android開發主題樣式詳解
application標簽中的@style/AppTheme引用自哪個文唯弊枝件夾中的styles.xml,這是根據運行此程序的手機系統來決定的,卜逗如果手機系統的API版本是11以上就是v11/styles.xml,API版本是14以上就是v14/styles.xml,以此類推。我們可以通過修改AppBaseTheme的父主題來實現我們需要的樣式,此文章主要就是來討論這個主題如何修改。
使用android系統中自帶的主題要加上"android:",如:android:Theme.Black
使用v7兼容包中的主題不需要前綴,如:Theme.AppCompat
系統自帶主題:
API 1:
android:Theme 根主題
android:Theme.Black 背景黑色
android:Theme.Light 背景白色
android:Theme.Wallpaper 以桌面牆紙為背景
android:Theme.Translucent 透明背景
android:Theme.Panel 平板風格
android:Theme.Dialog 對話框風格
API 11:
android:Theme.Holo Holo根主題
android:Theme.Holo.Black Holo黑主題
android:Theme.Holo.Light Holo白主題
API 14:
android:Theme.DeviceDefault 設備默認根主題
android:Theme.DeviceDefault.Black 設備默認黑主題
android:Theme.DeviceDefault.Light 設備默認白主題
API 21: (網上常說的 Android Material Design 就是要用這種主題)
android:Theme.Material Material根主題
android:Theme.Material.Light Material白主題
兼容包v7中帶的主題:
Theme.AppCompat 兼容主題的根主題
Theme.AppCompat.Black 兼容主題的黑色主題
Theme.AppCompat.Light 兼容主題的白色主題
以下都是指「包含」,比如包含「Dialog」表示對話框風格
比如Theme.Dialog、Theme.Holo.Dialog、Theme.Material.Dialog、Theme.AppCompat.Dialog都是對話框風格
Black 黑色風格
Light 光明風格
Dark 黑暗風格
DayNight 白晝風格
Wallpaper 牆紙為背景
Translucent 透明背景
Panel 平板風格
Dialog 對話框風格
NoTitleBar 沒有TitleBar
NoActionBar 沒有ActionBar
Fullscreen 全屏風格
MinWidth 對話框或者ActionBar的寬度根據內指敏容變化,而不是充滿全屏
WhenLarge 對話框充滿全屏
TranslucentDecor 半透明風格
NoDisplay 不顯示,也就是隱藏了
WithActionBar 在舊版主題上顯示ActionBar
10. Android關於Theme.AppCompat相關問題的深入分析
先來看這樣一個錯誤:
No resource found that matches the given name '@style/Theme.AppCompat.Light'
對於這個錯誤,相信大部分Android開發者都遇到過,可能很多朋友通過網路或者Google已經解決了這個問題,但是網上大部分都只給出了解決方法。
正所謂知其然,知其所以然,本文將從此問題出發,深入分析探討導致此問題的原因、由其衍生出來的一系列問題及其解決方案。
Android的SDK版本很多,新的SDK版本包含了很多新的特性,為此Google官方提供Android Support Library package來保證高版本SDK的向下兼容。通過使用此包,可以讓擁有最新SDK特性的應用運行在API lever 4(即Android 1.6) 及更高版本的設備之上。
在4.0之前Android可辯州以說是沒有設計可言的,在4.0之後推出了Android Design,從此Android在設計上有了很大的改善,而在程序實現上相應的就滲灶廳是Holo風格,所以你看到有類似 Theme.Holo.Light 、 Theme.Holo.Light.DarkActionBar 就是4.0的設計風格,但是為了讓4.0之前的版本也能有這種風格怎麼辦呢?這個時候就不得不引用v7包了,所以對應的就有 Theme.AppCompat.Light 、 Theme.AppCompat.Light.DarkActionBar ,如果你的程序最小支持的版本是API14(即Android 4.0),那麼可以不用考慮v7的兼容。
Android在5.0版本推出了Material Design的概念,這是Android設計上又一大突破。對應的程序實現上就有 Theme.Material.Light 、 Theme.Material.Light.DarkActionBar 等,但是這種風格只能應用在在5.0版本的手機,如果在5.0之前應用Material Design該怎麼辦呢?同樣的引用appcompat-v7包,這個時候的 Theme.AppCompat.Light 、 Theme.AppCompat.Light.DarkActionBar 就是相對應兼容的Material Design的Theme。
由此可以得出以下情形會導致本文一開始提出的問題。
AndroidManifest.xml文件裡面
此時的解決方法有如下幾種:
此時再將項目values,values-v11,values-v14目錄下的styles.xml文件裡面style都改為
3.2 將此目錄下的項目導入到Eclipse中
3.3 右鍵點擊我們的Android項目,選擇Properties,左側選擇Android,在下方Library框里叢隱點擊Add,最後選擇appcompat_v7,確定。
此時問題就解決了。
出現此問題的原因是appcompat_v7已經更新到了最新版本並且高於編譯環境的SDK版本,此時在Android SDK Manager將SDK及編譯工具更新到最高版本
升級完成之後右鍵點擊appcompat_v7項目,選擇Properties,選擇Project Build Target 為最新版本,這樣就OK了。
通過以上的分析,相信朋友們以後再遇到AppCompat相關的問題應該不再是問題了。歡迎大家留言討論。
純凈日報 https://github.com/laucherish/PureZhihuD
一個採用 RxJava + Retrofit + OkHttp 框架實現的開源軟體