总结目录
- 视图篇
- 如何理解非主线程可以更新UI
- dialogFragment 全屏时左右留空的解决方案
- dialogFragment 全屏时状态栏出现黑色布局的解决方案
- 多个fragment 切换重叠的解决方案
- 多个fragment 保存状态时可能出现 TransactionTooLargeException 的解决方案
- recyclerview 调用 notifyItemRemoved 方法移除某个 Item 之后因为引用 position 引起 crash 的原因
- recyclerview 局部刷新Item时会因为默认动画导致闪烁的解决方案
- recyclerview 中的 item 出现莫名的偏移滚动
- recyclerview 内容超过一屏时,findFistCompletelyVisibleItemPosition 会返回 -1 的原因
- textview 中富文本点击事件拦截了长按事件的解决方案
- 如何禁止 ViewPager 的滑动
- 如何仿蘑菇街/马蜂窝 Viewpager 装载图片之后切换时动态变更高度
- 如何控制 appbarLayout 随时定位到某个位置
- 如何禁止 appbarLayout 滚动
- edittext 未能响应 onClickListener 事件的解决方案
- 使用 listview 或gridview 的处理 item 的 state_selected 事件是无效的解决方案
- 解决5.0以上Button自带阴影效果的方案
- 针对 onSingleTapUp 和 onSIngleTapConfirmed 的使用区别
- 如何使用layer-list画三角形
- 关于属性动画中旋转 View 时部分机型出现 View 闪烁的解决方案
- 关于 ConstraintLayout 的代码布局下的注意事项
- TextView 在 6.0 版本下设置单行尾部缩略的坑
- 服务篇
- 线程篇
- 网络篇
- 数据篇
- 机型系统适配篇
- 如何解决 NatigationBar 被 PopupWindow 遮挡的问题
- 如何解决MIUI系统后台无法 toast 的问题
- 如何解决关闭通知栏权限无法弹出 toast 的问题
- 如何适配 vivo 等双面屏幕
- 如何解决华为设备产生太多 broadcast 导致crash的问题
- 各种通知栏的适配方案
- 解决针对魅族推送内容限制的问题
- 解决从系统安装起安装应用后启动,Home 隐藏后 Launcher 重复启动的问题
- 针对有launcher做为Activity的应用,在完全没有启动下收到第三方推送(小米,华为,魅族)/分享拉起的注意事项
- 针对 App 多场景拉起场景下的场景判断分析
- 8.0 部分 ROM 出现 Only fullscreen opaque activities can request orientation 的解决方案
- 9.0 android 支持明文连接(Http)
- 编译构建篇
- travis-ci 高版本androidO编译遇到 license 没通过编译失败的解决方案
- Dalvik 支持的 android 版本下进行分包执行会有一些限制
- Dalvik 分包构建每一个 dex 文件时可能出现 java.lang.NoClassDefFoundError
- Java 8 methods of java.lang.Long and java.lang.Character are not desugared by D8
- databinding 中 findBinding vs getBinding 的场景区别
- 版本构建出现 Gradle sync failed: Cannot choose between the following configurations of project
- gradle 配置本地离线包
- 解决kvm/jvm 编译时 -classpath 遇到的分割及空格的问题
- databinding NoSuchMethodError with buildTool 3.4.0
- AS连接真机调试出现 debug info can be unavailabe 的解决方法
- 版本控制篇
- 其他
<<视图篇>>
-
如何理解非主线程可以更新UI
谷歌在 viewRootImpl 中检查更新ui的线程
void checkThread() { if (mThread != Thread.currentThread()) { throw new CalledFromWrongThreadException( "Only the original thread that created a view hierarchy can touch its views."); } }
在执行onCreate的时候这个判断并没有执行到
-
dialogFragment 全屏时左右留空的解决方案
在 fragment#onResume 中重新调整 window 布局
android.view.WindowManager.LayoutParams lp = window.getAttributes(); lp.width = WindowManager.LayoutParams.MATCH_PARENT; lp.height = WindowManager.LayoutParams.WRAP_CONTENT; window.setAttributes(lp);
-
dialogFragment 全屏时状态栏出现黑色布局的解决方案
在主题中设置
<item name="android:windowIsFloating">true</item>
此时 window 为 wrap_content,如果出现左右空白,则考虑使用上个问题的方案。
-
当应用退回后台一段时间重返后,Fragment 切换重叠的解决方案
在线上项目中我们遇到一个场景:当应用按下 Home 退回后台,然后过一段时间之后从后台拉起我们的项目。极少数机型在主页进行多个 fragment 的切换时出现了 fragment 的重叠。经过定位之后发现,这些机型的运存偏小,性能偏差,出现这种现象的原因是由于内存的压力的原因,系统并不知后台的程序哪一个才需要保持运行,就会尝试回收内存占用较大的页面,当我们的页面被系统销毁时,fragmentActivity#onSaveInstanceState 被执行并保存了一些瞬态信息,比如界面 fragment 的视图信息。当我们再次拉起应用的时候,会让原来的 fragmentActivity 重建并重新构建了一个新的 fragment ,此时会叠加到已经被恢复的 fragment 之上导致重叠。
比较暴力的做法是不让 activity 保存状态,比如
@Override public void onSaveInstanceState(Bundle outState) { //直接不调用 super.onSaveInstanceState(outState); //或者直接传递空数据 super.onSaveInstanceState(new Bundle()); }
比较优雅的做法是,比如
@Override public void onSaveInstanceState(Bundle outState) { getSupportFragmentManager().putFragment(outState, you_key, CusFragment); super.onSaveInstanceState(outState); } //在onCreate的时候判断是否已经存在保存的信息 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState != null) { CusFragment fragment = (CusFragment)getSupportFragmentManager().getFragment(savedInstanceState, you_key); } else { //init CusFragment } }
-
多个fragment 保存状态时可能出现 TransactionTooLargeException 的解决方案
出现
TransactionTooLargeException
异常时,因为线上我们使用了 FragmentStatePagerAdapter 作为 fragment 适配器为了尽可能过缓存下浏览过的 fragment 以获得更好的体验,承载多个 FragmentStatePagerAdapter#saveState 会被调用并对每一个 fragment 的 bundle 数据进行保存。由于我们的 bundle 较大,并且保存下来的 bundle 并不会因为 fragment 被销毁而销毁,所以需要保存的 bundle 数据会一直增长,直到出现TransactionTooLargeException
异常. 我们参考