
作者:李旺成
時間:2016年4月20日
接上篇:AndroidStudyDemo之Android6.x新API介紹(一)
五、 Text Selection
先看下效果:

簡介
Android 6.x 提供了 Text Selection,在選擇文本后,可以顯示一個浮動工具欄,一般可以提供剪切、拷貝、粘貼等操作,這個 TextSelection 的交互過程和實現(xiàn) 與 contextual action bar 的實現(xiàn)一樣。
注意:
如果使用的是 Android Support Library revision 22.2,需要注意浮動工具欄不向后兼容且因為 appcompat 默認接管 ActionMode 對象,阻止了浮動工具欄被顯示。為了在 AppCompatActivity 中支持 ActionMode,需要調(diào)用getDelegate()方法,之后對返回的 AppCompatDelegate 對象調(diào)用setHandleNativeActionModesEnabled() 方法,并設置輸入?yún)?shù)為 false,該調(diào)用將ActionMode對象的控制交還給系統(tǒng)框架層。在 Android6.0(API level 23) 的設備上,框架層支持 ActionBar 或浮動工具欄模式,在 Android 5.1(API level 22) 及以下的設備上,只支持 ActionBar 模式。
簡單使用
演示代碼很簡單,直接看代碼:
@TargetApi(23)
private void initData() {
mCallback2 = new ActionMode.Callback2() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
if (inflater == null) {
return false;
}
inflater.inflate(R.menu.actionmode_menu, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
Toast.makeText(TextSelectionActivity.this, item.getTitle(), Toast.LENGTH_LONG).show();
mode.finish();
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
// 控制浮動菜單的位置
@Override
public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
super.onGetContentRect(mode, view, outRect);
}
};
this.mTestTV.setCustomSelectionActionModeCallback(mCallback2);
}
注意事項
實現(xiàn)選擇文字后的浮動工具欄,在app代碼中需要做如下修改:
- 在View 或 Activity對象
ActionMode的調(diào)用從startActionMode(Callback) 變?yōu)?startActionMode(Callback, ActionMode.TYPE_FLOATING) - 替換原有的ActionMode.Callback為ActionMode.Callback2
- 重寫OnGetContentRect()方法,提供內(nèi)容Rect對象(文本選擇的矩形框)在view中的位置
- 在矩形框作為唯一的元素不再有效時,調(diào)用invalidateContentRect() 方法
(參考自:值得你關注的Android6.0上的重要變化(一))
相機 API
先看 Demo 效果:

Android 6 提供了 setTorchMode() 方法來直接控制閃光燈,并且可以監(jiān)聽閃光燈的開光狀態(tài)。這里演示一下閃關燈控制以及監(jiān)聽閃關燈狀態(tài),主要使用了 CameraManager 中的方法:

代碼很簡單,直接看代碼:
public class CameraTestActivity extends AppCompatActivity {
private Switch mTorchModeSwitch;
private TextView mShowTorchModeTV;
private CameraManager mCameraManager;
private CameraManager.TorchCallback mTorchCallback;
private String[] mCameraIdList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cameratest);
initView();
initData();
initListener();
}
private void initView() {
this.mTorchModeSwitch = (Switch) this.findViewById(R.id.switch_torchmode);
this.mShowTorchModeTV = (TextView) this.findViewById(R.id.tv_showtorchmode);
}
@TargetApi(23)
private void initData() {
mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
mTorchCallback = new CameraManager.TorchCallback() {
@Override
public void onTorchModeChanged(String cameraId, boolean enabled) {
super.onTorchModeChanged(cameraId, enabled);
mShowTorchModeTV.setText("Camera:" + cameraId + " TorchMode change :" + enabled);
}
@Override
public void onTorchModeUnavailable(String cameraId) {
super.onTorchModeUnavailable(cameraId);
}
};
try {
mCameraIdList = mCameraManager.getCameraIdList();
} catch (CameraAccessException e) {
mCameraIdList = null;
e.printStackTrace();
}
// 注冊回調(diào)監(jiān)聽
mCameraManager.registerTorchCallback(mTorchCallback, new Handler());
}
private void initListener() {
this.mTorchModeSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (mCameraIdList == null) return;
changeTorchMode(isChecked);
}
});
}
@TargetApi(23)
private void changeTorchMode(boolean isChecked) {
try {
mCameraManager.setTorchMode(mCameraIdList[0], isChecked);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@TargetApi(23)
@Override
protected void onDestroy() {
super.onDestroy();
mCameraManager.unregisterTorchCallback(mTorchCallback);
}
}
支持主題化的 ColorStateLists
先看 Demo 的效果:

簡介
使用 context.getColorStateList(int id) 可以獲取當前主題對應的 ColorStateLists,使用 ColorStateList,就能為按鈕的每個狀態(tài)提供不同的顏色。
ColorStateList 并不是個新東西,看官方介紹:

文檔中說 ColorStateList 是從 xml 創(chuàng)建的,在 Resources 類中提供了如下方法:
@Deprecated
getColorStateList(@ColorRes int id)
getColorStateList(@ColorRes int id, @Nullable Theme theme)
Android 6 在 Context 類中添加了 getColorStateList() 方法:
public final ColorStateList getColorStateList(int id) {
return getResources().getColorStateList(id, getTheme());
}
其實還是調(diào)的 Resources 中的相關方法。
簡單使用
使用很簡單,直接看代碼:
@TargetApi(23)
private void testGetColorStateList() {
ColorStateList csl = getColorStateList(R.color.text_selector1);
if (csl != null) {
mTestBtn.setTextColor(csl);
}
Resources resources = getResources();
ColorStateList csl2 = resources.getColorStateList(R.color.text_selector2);
if (csl2 != null) {
mTestBtn2.setTextColor(csl2);
}
}
App Linking
簡介
這是一個把 APP 和網(wǎng)頁直接打通的技術,能夠讓 APP 能夠直接來處理你的網(wǎng)站普通的 URL 鏈接,來展示你對應的網(wǎng)站內(nèi)容。這絕對是一個值得關注的改進,Web 和 APP 之間縫隙將越來越小。這對既有網(wǎng)站又有 APP 的應用來說非常有利,例如知乎和淘寶等。
有點類似于之前的 APP 的 Deep link,可以通過特殊的Schema也可以讓 APP 直接打開對應的內(nèi)容。APP Linking 的特點是,只要使用傳統(tǒng)的 URL 就可以,而且是根據(jù) URL 的域名對應特定的 APP 的。
開發(fā)者需要做的是在AndroidManifest.xml做一下對應的聲明即可。如果需要讓系統(tǒng)默認用你的 APP 打開對應的 URL 的話,還需要網(wǎng)站配合提供assetlinks.json。詳情可以參考這里。
(參考自:Android 6.0 中的新技術總結)
簡單使用
鑒于手頭的資源不夠,沒有服務器上傳 web-app關聯(lián)文(statements.json),所以這里就不做實驗了。
有幾篇文章我認為講解得挺詳細了,有興趣的建議去看看:
Android M 的"App Links"實現(xiàn)詳解
Android M DeepLinks AppLinks 詳解
Android M App Links: 實現(xiàn), 缺陷以及解決辦法
其他
還有很多新 API 以及改動的 API 沒有介紹,這里也不打算介紹了。前后兩篇文章挑了 Android 6.x 中新提供的幾個比較重要和我感興趣的 API,簡單的做了個 Demo。
雖然,不打算繼續(xù)介紹其余的新 API,這里做個簡單的記錄,以后用到了再去詳細了解:
- 指紋解鎖:FingerprintManager
- 支持藍牙觸控筆
- 新的省電模式:Doze 和 App Standby
- APP 數(shù)據(jù)自動備份
- 通知(Notifications):移除了Notification.setLatestEventInfo()
- AudioManager Changes:setStreamSolo()方法過時和setStreamMute()方法過時
- Browser Bookmark Changes:移除了全局書簽的支持、Browser.getAllBookmarks()移除、Browser.saveBookmark()移除、READ_HISTORY_BOOKMARKS權限移除、WRITE_HISTORY_BOOKMARKS權限移除
- Android KeyStore變化:Android Keystore provider 不再支持DSA,仍舊支持ECDSA
- Wi-If和網(wǎng)絡變化:只能修改你自己創(chuàng)建的WifiConfiguration對象的狀態(tài),添加 multinetwork APIs
- 相機服務變化:改為基于優(yōu)先級的訪問方式
- 企業(yè)Android的變化
- 數(shù)據(jù)流量統(tǒng)計(Data Usage)
- 全局設置變化:不再能通過setGlobalSettings()來設置,現(xiàn)在能通過setGlobalSettings()來設置
- Runtime:可以恰當?shù)膶崿F(xiàn)newInstance()的訪問規(guī)則
小結
關于 Android 6.x 的新 API 介紹就到這里了,下一篇開始介紹 Android 6.x 的新控件。
未完待續(xù)...
項目地址
附件
揭秘Android 6.0之Text Selection
值得你關注的Android6.0上的重要變化(一)
Android M新特性Doze and App Standby模式詳解
Android學習 之 ColorStateList按鈕文字變色
Android ColorStateList使用方法
Android 6.0 中的新技術總結
Android M 的"App Links"實現(xiàn)詳解
Android M App Links: 實現(xiàn), 缺陷以及解決辦法