从实习到现在Android开发的备忘
有效的回车监听
editText.setEditorActionListener(), EditorInfo.IME_XXX,跟xml里imeOptions里一致
自定义dialog去除自定义布局的上端多余白色背景
style里 windowIsFloating = true
AppCompatActivity中背景透明
<style name="ActivityTransparent" parent="AppTheme">
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@color/transparent</item>
</style>
addView时的LayoutParam需要新建,在addView的时候传进去,跟container的类型一致
ViewPager不滑动的方法
onTouchEvent和onInterceptTouchEvent全return false
AsyncTask的onPostExecute在UI线程执行,可以对控件进行操作
TextView代码设置drawable方法
按原有的大小setCompoundDrawablesWithIntrinsicBounds
手动设置drawable.setBounds setCompoundDrawables
代码设置文字颜色selector
把selector文件移动到color文件夹
ColorStateList colorStateList = getResource().getColorStateList(R.color.XXX)
setDrawable()如果要设为null的话使用new ColorDrawable(),或者任意new Drawable()
添加背景时不被拉伸方法:在drawable下新建bitmap,不平铺不拉抻
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity=“top"
android:src="@mipmap/icon1"
android:tileMode="disabled" />
Textview 删除线
//下划线
textview.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG);
//中间横线
textview.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG);
// 抗锯齿
textview.getPaint().setAntiAlias(true);
Fragment懒加载
重写setUserVisibleHint()方法
设置所有activity跳转动画,application使用
<style name="Anim_activity" parent="AppBaseTheme">
<item name="android:windowAnimationStyle">@style/activity_anim</item>
</style>
<style name="activity_anim" parent="@android:style/Animation.Activity">
<item name="android:activityOpenEnterAnimation">@anim/anim</item>
<item name="android:activityOpenExitAnimation">@anim/anim</item>
<item name="android:activityCloseEnterAnimation">@anim/anim</item>
<item name="android:activityCloseExitAnimation">@anim/animt</item>
</style>
让RadioGroup全部取消选中的小黑科技
选中一个隐藏的
颜色渐变类ArgbEvaluator
调用evaluator(float, 0x,0x)方法, 配合ColorDrawable
关于LayoutInflater的inflate
inflate(int resource, ViewGroup root, boolean attachToRoot)方法三个参数的含义:true:并且root存在,将xml挂载到root下,返回root;false:返回xml的根布局
WebView初级使用
//启用js
webview.getSettings().setJavaScriptEnabled(true);
//拦截url
webView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return true;
}
});
RecycleView设置header
需要设置的SpanSize
GridLayoutManager manager = new GridLayoutManager(mContext,2);
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return 2;
}
});
Java进制转换
10转2、8、16
Integer.toBinaryString()
Integer.toOctalString()
Integer.toHexString()
16、8、2转10
Integer.parseInt(num, "x")
关闭输入法
if (getWindow().peekDecorView() != null) {
InputMethodManager inputManger = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputManger.hideSoftInputFromWindow(getWindow().peekDecorView().getWindowToken(), 0);
}
打开输入法
InputMethodManager inputManager = (InputMethodManager) etSearch.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.showSoftInput(etSearch, 0);
RecyclerView移动和删除:ItemTouchHelper
控制其显示的方式:LayoutManager
控制Item间的间隔(可绘制):ItemDecoration
控制Item增删的动画:ItemAnimator
触发点击声音
view.playSoundEffect(SoundEffectConstants.CLICK);
Java中的反射
用于获取、设置类中的private变量或方法
属性使用Filed类获取,方法使用Method类去调用。
MyClass myClass = new MyClass(); //测试类
Field field = Class.forName(MyClass.class.getName()).getDeclaredField("mName");
field.setAccessible(true); // 设置可获取
Object name = field.get(myClass); //取值
field.set(myClass, "new name”); //设置
Method method = Class.forName(MyClass.class.getName()).getDeclaredMethod("print", new Class[]{int.class, String.class}); // 参数数组
method.setAccessible(true);
method.invoke(myClass, 100, "Victor”); //对应的参数
Shader类可在canvas里实现渐变图形、混合渐变等
RecyclerView.computeVerticalScrollOffset() 计算纵向滑动距离
FragmentManager
Fragment里用getChildFragmentManager()
Activity里用getSupportFragmentManager()
Observable操作符大致分为以下几种
创建:Observable.create() Observable.just() Observable.from()等
转换:observable.map() observable.flatMap() observable.buffer()等
过滤:observable.filter() observable.sample() observable.take()等
组合:observable.join() observable.merge() observable.combineLatest()等
错误处理: observable.onErrorResumeNext() observable.retry()等
功能:observable.subscribeOn() observable.observeOn() observable.delay()等
条件:observable.amb() observable.contains() observable.skipUntil()等
运算、聚合如:observable.count() observable.reduce() observable.concat()等
其他:observable.toList() observable.connect() observable.publish()等
ViewGroup.setdescendantfocusability()
FOCUS_BEFORE_DESCENDANTS ViewGroup本身先对焦点进行处理,如果没有处理则分发给child View进行处理
FOCUS_AFTER_DESCENDANTS 先分发给Child View进行处理,如果所有的Child View都没有处理,则自己再处理
FOCUS_BLOCK_DESCENDANTS ViewGroup本身进行处理,不管是否处理成功,都不会分发给Child View进行处理
进入界面拦截EditText焦点
找父控件
android:focusable="true"
android:focusableInTouchMode="true"
Resources类中的getIndentifier(name, defType, defPackage)方法,根据资源名字获取其ID
View类的callOnClick() performClick()和performLongClick()
TextView类中的append方法,追加文本
DecimalFormat
用于字串格式化,包括指定位数,百分数和科学技术等
剥夺父view对touch事件的处理权
getParent().requestDisallowInterceptTouchEvent(true);
Palette
Android 5.0加入的可以提取一个Bitmap中突出颜色的类,可用于获取主题颜色
FragmentManager.enableDebugLogging(),在需要观察 Fragment 状态的时候会有帮助
Activity.recreate(),强制让 Activity 重建
Drawable淡入淡出效果
android:enterFadeDuration android:exitFadeDuration
此属性在 Drawable 具有多种状态的时候,可以定义它展示前的淡入淡出效果
SparseArray
Map的高效优化版本。
姐妹类SparseBooleanArray、SparseIntArray和SparseLongArray。
ActivityManager.clearApplicationUserData()
一键清理你的app产生的用户数据,可能是做用户退出登录功能,有史以来最简单的方式了。
清除画布上的内容
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
在自定义View的onDetachedFromWindow方法中清理与View相关的资源
选择使用ClipDrawable实现进度条功能
自定义view中有getContext(),不需要专门创建一个mContext全局对象
Activity共享元素
xml设置android:transitionName = “xxx"
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, view,”xxx”).toBundle())
如果有多个的话就用
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, Pair.create(view, “xxx1”),Pair.create(view, “xxx2”)).toBundle())
View圆形展开用CircularReveal
用ViewAnimationUtils.createCircularReveal生成Animator然后设置相关属性
跳转到另一个应用的Activity
//用这个方法打开的activity和另一个应用里的这个activity是两个独立的
Intent i = new Intent();
i.setClassName("com.centling.chuniang", "com.activity.MainActivity");
startActivity(i);
在View中设置GestureDetector有两点需要注意
View必须设置longClickable为true,否则手势识别无法正确工作,只会返回Down, Show, Long三种手势。
必须在View的setOnTouchListener中调用手势识别,而不能重写onTouchEvent,否则手势识别无法正确工作。
VelocityTracker使用时通过obtain获得实例,要在Switch Event之前addMovement(),不然无效,不要在ACTION_DOWN里addMovement。
解决滑动冲突
外部拦截:重写viewGroup的intercept,其中down和up都返回false,move时自己需要此事件就拦截返回true
内部拦截:重写view的dispatch,使用parent.requestdisallow… 父控件需要就false,自己需要就true,return super.dispatch,另外重写父控件的intercept,down时返回false,其他true
Fragment动画
setCustomAnimations()方法必须在add、remove、replace调用之前被设置,否则无效。
模拟按home键返回桌面
Activity.moveTaskToBack(true)
沉浸式状态栏
(1) Activity里
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); //透明状态栏
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); //透明导航栏
(2) xml里 父布局 里的最上面的布局添加
android:clipToPadding=“true” (系统默认是true)
android:fitsSystemWindows="true"
反射的Tips:
对已知的类用 类名.class.getXXX
对未知的类用 Class.forName(类对象.getClass().getName()).getXXX,尤其是在源码里没有的类的对象使用时,效果显著
wrap_content在可滑动的父控件里是UNSPECIFIED,在不可滑动的父控件里是AT_MOST
播放系统声音
val notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val r = RingtoneManager.getRingtone(applicationContext, notification)
r.play()
在项目里引用本地aar
添加本地仓库
repositories {
flatDir { dirs 'libs' }
}
build.gradle
compile(name: 'aar_name', ext: 'aar')
判断是否有SD卡
Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
在Activity应用<meta-data>元素
ActivityInfo info = this.getPackageManager().getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
info.metaData.getString("meta_name");
在application应用<meta-data>元素
ApplicationInfo appInfo = this.getPackageManager() .getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
appInfo.metaData.getString("meta_name");
在service应用<meta-data>元素
ComponentName cn = new ComponentName(this, MetaDataService.class);
ServiceInfo info = this.getPackageManager().getServiceInfo(cn, PackageManager.GET_META_DATA); info.metaData.getString("meta_name");
在receiver应用<meta-data>元素。
ComponentName cn = new ComponentName(context, MetaDataReceiver.class);
ReceiverInfo info = context.getPackageManager().getReceiverInfo(cn, PackageManager.GET_META_DATA); info.metaData.getString("meta_name");
selector里的status_press必须在View已经设了点击事件时才有效
查看keystore
keytool -list -v -keystore
重写onMeasure时一定要先measureChildren
禁止截屏
getWindow().addFlags(WindowManager.LayoutParams. FLAG_SECURE);
给child用的attr, name后面加 _Layout
自定义LayoutParams
要重写View的generateDefaultLayoutParams和两个generateLayoutParams方法
全屏且有状态栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
PathMeasure获取角度
pathMeasure.getPosTan(value * pathMeasure.getLength(), pos, tans)
float degrees = (float) (Math.atan2(tans[1], tans[0]) * 180.0 / Math.PI)
poet生成通配符
(1) java: Class<?> kotlin: Class<*>
TypeVariableName.get(“*” / “?”)
(2) java: Class<? extend A> kotlin: Class<out A>
ParameterizedTypeName.get() WildcardTypeName.subtypeOf()
(3) java: Class<? super A> kotlin: Class<in A>
ParameterizedTypeName.get() WildcardTypeName.supertypeOf()
AccessibilityService
android:animateLayoutChanges add remove view时动画 可配合LayoutTransition自定义
View生成Bitmap
val screenshot = Bitmap.createBitmap(v.width, v.height), Bitmap.Config.ARGB_8888)
val c = Canvas(screenshot)
c.translate(-v.scrollX.toFloat(), -v.scrollY.toFloat())
v.draw(c)
BitmapFactory.Options.inJustDecodeBounds
如果inJustDecoedBounds设置为true的话,解码bitmap时可以只返回其高、宽和Mime类型,而不必为其申请内存,从而节省了内存空间
TextView.setTransformationMethod 用来设置其中text的转换显示。
ReplacementTransformationMethod可以自定义替换 例如把小写字母替换成大写字母。
Android自带的菜单PopupMenu ListPopupWindow