1.finish Activity時軟鍵盤不關:在onPause
時用InputMethodManager
的hideSoftInputFromWindow
關閉。
2.<layer-list>
中的<item>
的android:gravity
屬性以及android:height
,android:width
,android:height
到API23之后才有的,別被AS忽悠了。
3.合并?selectableItemBackground
與你自己的背景資源
無法直接用xml定義layer-list
,因為drawable屬性不支持attr值
需要用代碼實現:
// Attribute array
int[] attrs = new int[] { android.R.attr.selectableItemBackground };
TypedArray a = getTheme().obtainStyledAttributes(attrs);
// Drawable held by attribute 'selectableItemBackground' is at index '0'
Drawable d = a.getDrawable(0);
a.recycle();
之后創建 LayerDrawable
:
LayerDrawable ld = new LayerDrawable(new Drawable[] {
// Nine Path Drawable
getResources().getDrawable(R.drawable.Your_Nine_Path),
// Drawable from attribute
d });
// Set the background to 'ld'
yourLayoutContainer.setBackground(ld);
4.無法啟用Hierarchy View解決方案:
在環境變量中添加ANDROID_HVPROTO=ddm
5.RatingBar組件流血效果解決方式:
切的星星底部留2個像素高的透明像素
6.點擊波紋效果屬性
-
android:background="?selectableItemBackground"
有邊界效果 -
android:background="?selectableItemBackgroundBorderless"
無邊界效果
7.在LinearLayout里增加了個分割線** ( Android3.0+版本 ) **
必要屬性:
-
android:divider
,分割線圖片 -
android:showDividers
,分割線位置
8.RadioButton
&RadioGroup
使用注意:
-
RadioGroup
繼承自LinearLayout
-
RadioButton
變化事件還是監聽其click事件,然后獲取isChecked()
- 設置
<RadioGroup>
的默認選中項- 代碼中
radiogroup.check(idOfRadioButton)
- xml中直接使用
<RadioGroup>
的android:checkedButton
屬性指定默認被選中的RadioButton
的id
注意:用
android:checkedButton
指選中的RadioButton
的id時要有+
號,因為<RadioButton>
定義在<RadioGroup>
后面,不加+
會報找不到id錯誤。 - 代碼中
9.在代碼中使用 ?selectableItemBackground
int[] attrs = new int[] { R.attr.selectableItemBackground};
TypedArray ta = themedContext.obtainStyledAttributes(attrs);
Drawable drawableFromTheme = ta.getDrawable(0);
ta.recycle();
10.代碼中使用<selector>
顏色,使用Resources
的getColorStateList
方法獲取,如
radioButton.setTextColor(getResources().getColorStateList(R.color.sl_rb_filter_item));
11.代碼中引用繼承形式的style,點用下劃線替換如
<style name="AppTheme.PopupMenu">
<item name="android:itemTextAppearance">@style/ItemTextStyle.AppTheme</item>
</style>
代碼中用使用R.style.AppTheme_PopupMenu
。
12.自定義PopMenu
的字體與分隔線
<style name="AppTheme.PopupMenu">
<!--<item name="android:itemTextAppearance">@style/ItemLargeTextStyle.AppTheme</item>--><!-- 這樣也是可以的! -->
<item name="textAppearanceLargePopupMenu">@style/ItemLargeTextStyle.AppTheme</item>
<item name="textAppearanceSmallPopupMenu">@style/ItemSmallTextStyle.AppTheme</item>
<item name="android:dropDownListViewStyle">@style/PopupMenuListView</item>
</style>
<style name="ItemLargeTextStyle.AppTheme" parent="TextAppearance.AppCompat.Widget.PopupMenu.Large">
<item name="android:textColor">@color/popup_menu_item_text_color</item>
<item name="android:textSize">16sp</item>
</style>
<style name="ItemSmallTextStyle.AppTheme" parent="TextAppearance.AppCompat.Widget.PopupMenu.Small">
<item name="android:textColor">@color/popup_menu_item_text_color</item>
<item name="android:textSize">16sp</item>
</style>
<style name="PopupMenuListView" parent="@style/Widget.AppCompat.ListView.DropDown">
<item name="android:divider">@color/divide_color</item>
<item name="android:dividerHeight">0.5dp</item>
</style>
13.上下級View的狀態傳遞
- 父傳子
android:duplicateParentState="true"
- 子傳父
android:addStatesFromChildren="true"
14.RadioButton
的padding是很坑的哦
API17+時 paddingLeft 是圖標與文字的間隔,也就是設置paddingLeft小圈圈位置是不變的喲
15.View即使在Activity中,View的getContext()
方法不一定返回的Context
不一定是對應的Activity,有可能是ContextWrapper
的子類如TintContextWrapper
、ContextThemeWrapper
,可以使用下面的方法獲取Activity:
private static Activity scanForActivity(Context cont) {
if (cont == null)
return null;
else if (cont instanceof Activity)
return (Activity)cont;
else if (cont instanceof ContextWrapper)
return scanForActivity(((ContextWrapper)cont).getBaseContext());
return null;
}
16.水平布局的LinearLayout
中有子View的android:layout_gravity="bottom"
沒有用,解決方法是在LinearLayout
中添加:
android:baselineAligned="false"
17.布局中關閉某View的硬件圖層加速
android:layerType=software
18.無線調試(wifi debug)方法
- 方法一
1.先連USB,開啟debug。
2.用adb shell netcfg
命令查看手機ip,蘋果系統adb shell ip route
。
3.用命令adb connect <DEVICE_IP_ADDRESS>:5555
連接。
4.可以拔USB線了。
5.adb -s <DEVICE_IP_ADDRESS>:5555 usb
關閉。 - 方法二(針對有些高端設備設置里有Wifi調試開關)
1.進入開發者選項,找到ADB over network
(在USB debugging
下面),開啟它。
2.上面的設置項顯示了地址和端口號,PC用命令adb connect <DEVICE_IP_ADDRESS>:<port>
連接。
3.關閉的話直接在設置里關。 - Android Studio有一個無線調試的插件
19.自定義SeekBar,點點與線線不對齊問題
android:thumbOffset="0dp"
20.用RadioButton
的setButtonDrawable(null)
在部分機器上(華為)沒卵用問題
使用setButtonDrawable(new StateListDrawable())
。
21.PopupWindow
點擊外面隱藏
只要有背景就行了,mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT))
。
22.PopupWindow
彈出后背后的界面黑化
步驟:
- 獲取
PopupWindow
根視圖了,有背景View會多一層,M之后也會多一層。 - 使用
WindowManager.LayoutParams
的FLAG_DIM_BEHIND
設置黑化,以及dimAmount
設置黑化程度。
代碼:
View container;
if (mPopupWindow.getBackground() == null) {
if (VERSION.SDK_INT >= VERSION_CODES.M){
container = (View) mPopupWindow.getContentView().getParent();
} else {
container = mPopupWindow.getContentView();
}
} else {
if (VERSION.SDK_INT >= VERSION_CODES.M) {
container = (View) mPopupWindow.getContentView().getParent().getParent();
} else {
container = (View) mPopupWindow.getContentView().getParent();
}
}
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams p = (WindowManager.LayoutParams) container.getLayoutParams();
p.flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND;
p.dimAmount = 0.3f;
wm.updateViewLayout(container, p);
23.獲取狀態欄高度
Rect frame = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
24.播放音頻時要先獲取音頻焦點
25.Activity
中DialogFragment
的回調丟失問題,在onCreate
判斷savedInstanceState
是否為null,若否說明是重新恢復的Activity
,根據tag獲取了DialogFragment
然后重新設置一下回調。
26.創建一個不用輸入就有提示的AutoCompleteTextView
繼承AutoCompleteTextView
,重寫enoughToFilter
、onFocusChanged
兩個方法:
@Override
public boolean enoughToFilter() {
return true;
}
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if (focused && getAdapter() != null) {
performFiltering("", KeyEvent.KEYCODE_UNKNOWN);
showDropDown();
}
}
27.讀取當前theme的屬性
TypedValue tv = new TypedValue();
if (getTheme().resolveAttribute(R.attr.actionBarSize, tv, true)) {
int actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
}
28.AppBarLayout的addOnOffsetChangedListener可以添加垂直偏移事件監聽
mAppBar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
Log.d("tag_scroll", "recycler_view current offset: "+verticalOffset);
}
});
29.RatingBar
的高度用wrap_content在23之前是沒用的,高度會變0哦,請使用minHeight
30.RadioButton
的選中圈不設置方式setButtonDrawable(new StateListDrawable())
31.RadioButton
在4.3以下先設置padding,再設置背景,padding會失效,得先調用setBackgroundDrawable
再調setPadding
32.DialogFragment
把title藏起來的方式整理。
//方式一
public static MyDialogFragment newInstance() {
MyDialogFragment mDialogFragment = new MyDialogFragment();
//Set Arguments here if needed for dialog auto recreation on screen rotation
mDialogFragment.setStyle(DialogFragment.STYLE_NO_TITLE, 0);
return mDialogFragment;
}
//方式二(不適用于用onCreateView創建界面的`DialogFragment`)
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
// request a window without the title
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
return dialog;
}
//方式三(和一差不多,也是用setStyle方法)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(STYLE_NO_TITLE, 0);
}
33.DialogFragment
定義高寬方式(特適用于沒有Title且用onCreateView
創建界面的)
public void onResume() {
super.onResume();
Window window = getDialog().getWindow();
window.setLayout(width, height);
window.setGravity(Gravity.CENTER);
//TODO:
}
34.顯示密碼方法
checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(!isChecked) {
passwordEt.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
} else {
passwordEt.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
}
}
});
35.兩種獲取屏幕參數的方式
WindowManager window = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = window.getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
DisplayMetrics metrics = getApplicationContext().getResources().getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels;
36.系統組件declare-styleable位置
/frameworks/base/core/res/res/values/attrs.xml
37.用Appcompat時獲取Activity引用
由于Context會被包裝成ContextWrapper,直接getContext()
不能直接cast成Activity
private Activity getActivity() {
Context context = getContext();
while (context instanceof ContextWrapper) {
if (context instanceof Activity) {
return (Activity)context;
}
context = ((ContextWrapper)context).getBaseContext();
}
return null;
}
38.用文件轉Drawable或Bitmap
//For a Drawable
String pathName = "/path/to/file/xxx.jpg";
Drawable d = Drawable.createFromPath(pathName);
//For a Bitmap:
Bitmap b = BitmapFactory.decodeFile(pathName);
39.查找無用資源
在AndroidStudio中Menu
->Analyze
-> Run Inspection by Name
->輸入 Unused resources
40.使用action跳轉到Activity
- AndroidManifest中對應的Activity添加
<intent-filter>
<action android:name="com.you.name.action" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
- 啟動代碼
Intent intent = new Intent("com.you.name.action");
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
} else {
//tell user the activity couldn't reach
}
41.監聽鍵盤是否開啟的正確姿勢
來自這里
boolean mKeyboardOpen;
private void addKeyboardVisibleListener() {
final View activityRootView = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
//r will be populated with the coordinates of your view that area still visible.
activityRootView.getWindowVisibleDisplayFrame(r);
int rootViewHeight = activityRootView.getRootView().getHeight();
int heightDiff = rootViewHeight - (r.bottom - r.top);
Cog.d(TAG, "heightDiff=", heightDiff);
if (heightDiff > rootViewHeight / 4 && !mKeyboardOpen) { // if more than 100 pixels, its probably a keyboard...
mKeyboardOpen = true;
} else {
mKeyboardOpen = false;
}
}
});
}
如果使用下面的方式,只能配合在Android Manifest中設置android:windowSoftInputMode="adjustResize"才有效
int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
if (heightDiff > dpToPx(this, 200)) { // if more than 200 dp, it's probably a keyboard...
// ... do something here
}
高度變化判斷不能簡單與100比較,在有NavigationBar的機器上會有問題。1/4根布局高度試下來可以。