1.finish Activity时软键盘不关:在onPause
时用InputMethodManager
的hideSoftInputFromWindow
关闭。
2.
中的
的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.check(idOfRadioButton)
- xml中直接使用
的android:checkedButton
属性指定默认被选中的RadioButton
的id
注意:用
android:checkedButton
指选中的RadioButton
的id时要有+
号,因为
定义在
后面,不加+
会报找不到id错误。 - 代码中
9.在代码中使用 ?selectableItemBackground
int[] attrs = new int[] { R.attr.selectableItemBackground};
TypedArray ta = themedContext.obtainStyledAttributes(attrs);
Drawable drawableFromTheme = ta.getDrawable(0);
ta.recycle();
10.代码中使用
颜色,使用Resources
的getColorStateList
方法获取,如
radioButton.setTextColor(getResources().getColorStateList(R.color.sl_rb_filter_item));
11.代码中引用继承形式的style,点用下划线替换如
代码中用使用R.style.AppTheme_PopupMenu
。
12.自定义PopMenu
的字体与分隔线
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
连接。:5555
4.可以拔USB线了。
5.adb -s
关闭。:5555 usb - 方法二(针对有些高端设备设置里有Wifi调试开关)
1.进入开发者选项,找到ADB over network
(在USB debugging
下面),开启它。
2.上面的设置项显示了地址和端口号,PC用命令adb connect
连接。:
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 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根布局高度试下来可以。