Android开发个人小记

1.finish Activity时软键盘不关:在onPause时用InputMethodManagerhideSoftInputFromWindow关闭。
2.中的android:gravity属性以及android:heightandroid:widthandroid: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.代码中使用颜色,使用ResourcesgetColorStateList方法获取,如
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的子类如TintContextWrapperContextThemeWrapper,可以使用下面的方法获取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.用RadioButtonsetButtonDrawable(null)在部分机器上(华为)没卵用问题

使用setButtonDrawable(new StateListDrawable())

21.PopupWindow点击外面隐藏

只要有背景就行了,mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT))

22.PopupWindow弹出后背后的界面黑化

步骤:

  • 获取PopupWindow根视图了,有背景View会多一层,M之后也会多一层。
  • 使用WindowManager.LayoutParamsFLAG_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.ActivityDialogFragment的回调丢失问题,在onCreate判断savedInstanceState是否为null,若否说明是重新恢复的Activity,根据tag获取了DialogFragment然后重新设置一下回调。

26.创建一个不用输入就有提示的AutoCompleteTextView
继承AutoCompleteTextView,重写enoughToFilteronFocusChanged两个方法:

@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根布局高度试下来可以。

你可能感兴趣的:(Android开发个人小记)