【乱码修正源码】【android如何读源码】【企业信用源码】dialogfragment源码

1.Android-开源通用弹窗的源码封装CommonPopupWindow(总得向别人学点什么)
2.Android常见知识点
3.Navigation源码解析及自定义FragmentNavigator详解
4.Android 原生BottomSheet 介绍及坑

dialogfragment源码

Android-开源通用弹窗的封装CommonPopupWindow(总得向别人学点什么)

       自我激励,封装Android通用弹窗

       开源地址:FanChael/CommonPopupWindow

       实现弹窗效果,源码当前功能基本可用,源码后续计划整合Rx家族与JSON,源码构建应用更新框架。源码

       注册登录弹窗借鉴国外原生样式,源码乱码修正源码注重设计与源码学习,源码提升自身技能。源码

       简单使用方法:

       1. 自定义布局

       1.1 创建Spinner背景形状布局

       1.2 替换为通用弹窗

       1.3 调用弹窗

       1.4 显示效果参照FanChael/CommonPopupWindow

       2. 分享弹窗

       提供两种常用分享样式,源码支持四种常规平台按钮与复制链接,源码提供两种出场方式。源码

       分享图标多时,源码支持水平滑动或网格展示,源码少于五个图标均匀分布。源码

       默认分享调用,源码提供仿腾讯样式调用。

       更新弹窗参考相关文档。android如何读源码

       其他学习资源

       比较Dialog, DialogFragment, PopupWindow,了解DialogFragment创建对话框的官方推荐。

       学习声明周期管理,提高适配性,但不一定完全替代旧有方法。

       通用弹窗需进一步完善,例如横竖屏切换等功能。

       持续关注相关资料,企业信用源码持续学习与实践。

Android常见知识点

        跳槽无非就是钱少了或不爽了,无论怎么样,记住:

        不要裸辞!

        不要裸辞!

        不要裸辞!

        为什么呢?

        1、裸辞就没有钱拿了,还不如骑驴找马。

        2、裸辞之后如果一个月内没有找到工作,那么社保就会断了,除非你自己找渠道交了。

        3、裸辞之后真的会很颓废!

        当初还在上班的时候就想着,裸辞了,首先花几天时间吧简历完善一下,把知识点恶补一下,然后投简历,面试,妥妥的妥妥。

        结果呢?每次裸辞之后都是:

        首先躺尸一个星期;

        然后用了一个星期才慢吞吞的改完简历;

        然后海投,没回复,修改简历;

        再次海投,面试,被虐得体无完肤,怀疑人生;

        再改简历,再海投,一不小心中了。

        当然海投也是有个目标范围的。

        如果不是裸辞,那么现在应该还是在公司上班,在完成工作之余,就会逼着自己复习知识点了,起码不会在家堕落。在家不上班就是睡觉、看电影,樯橹灰飞烟灭,所以不要裸辞。

        然并卵,我依然裸辞了。请假面试真的很烦。

        onPause,假如从ActivityA启动B,如果B是透明的,则不会回调A的onStop方法。

        方法一:

        方法二:

        1、写好动画文件 R.anim.enter 、 R.anim.exit

        2、调用 overridePendingTransition 设置动画

        引申:如Activity设置为singleInstance,则应该怎么设置跳转动画?

        1、startService启动方与Service并没有关联,只有当Service调用 stopSelf 或者其它组件调用 stopService 的时候服务才会终止。

        2、bindService启动方绑定Service,并且可以通过Binder与之交互,当启动方销毁时,也会自动unbindService,当所有启动方都unbindService之后,Service也就自动销毁了。

        为什么呢?官方文档是这样写的:

        大概意思是 onReceive() 执行完毕之后,它所在的进程就会变成低优先级进程,极易被系统杀死。

        分两种情况分析一下:

        一、收到广播的时候,应用正在运行:

        此时如果没有在Manifest中设置了独立进程,则 onReceive() 就直接在主进程主线程执行,这里很明显不能执行耗时操作。

        二、收到广播的时候,应用没有启动:

        这时候系统会启动一个进程去执行 onReceive() ,(如果Manifest中没有设置进程名,则进程名为包名),(插一句,所有进程都会创建一个Application实例),当onReceive执行完毕之后,此进程就变成低优先级了,随时有可能被系统杀死,如果你在onReceive里面启动了线程执行耗时任务,那很有可能子线程没执行完毕,进程就被杀死了,进程没了,线程自然就挂了。

        那么确实要执行耗时操作呢,怎么办?

        方法一:goAsync()

        方法二:schedule a JobService from the receiver using the JobScheduler

        三种实现方法

        1、继承现有的组件,如TextView等,进行拓展。

        2、继承ViewGroup,自定义布局。

        3、继承View,在onDraw()中描绘。

        onMeasure()

        onLayout()

        onDraw()

        其它

        attachToRoot 从字面理解就是是否绑定到 root 上面去了。

        1、 attachToRoot=true :则返回的view为root的子view;

        2、 attachToRoot=false :则返回的view是个单独的view,传入的root只是提供一些参数给view使用而已。

        那么这里不传入 attachToRoot 呢?那就看root是否为空了,如果传入root不为空,则默认绑定到root,作为root的子view返回。

        也就是所谓的Frame动画。指通过指定每一帧的图片和播放时间,有序的进行播放而形成动画效果。

        可以通过插入器 Interpolator 控制动画的变化速度。

        也就是所谓补间动画。指通过指定View的初始状态、变化时间、方式,通过一系列的算法去进行图形变换,从而形成动画效果,主要有 AlphaAnimation 、 TranslateAnimation 、 ScaleAnimation 、 RotateAnimation 四种。

        注意:只是在视图层实现了动画效果,并没有真正改变View的属性。

        属性动画,通过不断的改变View的属性,不断的重绘而形成动画效果。相比于视图动画,View的属性是真正改变了。

        注意:Android 3.0(API )以上才支持。

        最常用的类有 ObjectAnimator

        P.S. 我不明白cancel存在的意义。

        另外, DialogFragment 是没有cancel的。

        ping

        内存大致分为三个区:栈区、堆区、方法区。

        栈区

        堆区

        方法区

        JAVA不允许手动释放内存,只能通过垃圾回收程序不定期对那些不再被引用的对象进行回收。

        那么怎么判断哪些对象需要回收?

        1、引用计数法

        就是给对象添加一个引用计数器,引用对象时+1,引用失效时-1。但是这种方法解决不了对象相互引用的情况。

        2、可达性分析法

        通过一系列“GCRoots”对象作为起点进行搜索,当GCRoots和一个对象之间没有可达路径,则认为此对象不可用,但是不可用不一定会成为可回收对象。

        编写AIDL文件,定义接口。

        编译生成JAVA文件。

        定义进程级Service,onBind中返回Interface.Stub()。

        onServiceConnected中Interface aidl = Interface.Stub.asInterface(service);

        把已修复的class文件打包成dex文件,网络传输到用户手机中,利用类加载器把这些类加载到类队列的前面即可。

        【未完待续】

        如果公司录用我,不管是三年还是五年,首先我都会先把公司的任务做好,然后不断深入研究Android的相关技术,特别是Android源码,了解Android底层原理,以便更好的优化性能,避免一些不必要的奇葩问题,还有就是研究一些新的框架的原理,学习别人的思维。最后就是学习周边语言,比如后台,前端等等。

Navigation源码解析及自定义FragmentNavigator详解

       谷歌推出的Navigation主要目标是统一应用内页面跳转行为。使用方法简单,新项目选择Bottom Navigation Activity,系统自动生成页面逻辑。

       Navigation源码设计简洁,包含多个关键类。其中,企业源码最新分享NavHostFragment是直接在XML文件中定义的,其生命周期方法onCreate中直接创建了NavHostController,并通过findNavController暴露给外部调用者。NavHostController继承自NavController。在此过程中,通过navController获取NavigatorProvider并添加了两个Navigator:DialogFragmentNavigator和FragmentNavigator。NavController构造方法中还额外添加了两个Navigator,分别对应DialogFragment、重庆打车app源码Fragment和Activity的页面跳转。NavGraphNavigator用于在XML配置的navGraph与根节点文件中的startDestination之间实现跳转,功能单一。

       各个Navigator通过重写navigate方法实现各自的跳转逻辑。FragmentNavigator的关键实现在于注释1处,使用replace加载Fragment,这不符合实际开发需求。文章后续将解释如何自定义FragmentNavigator以避免Fragment在切换时执行生命周期。

       NavigatorProvider内部维护了一个HashMap存储相关Navigator信息,通过获取Navigator的注解Name作为键和getClass作为值进行存储。在onCreate方法中,mNavController调用了setGraph,解析XML配置的mobile_navigation节点信息文件,根据不同的节点各自解析。通过获取NavInflater进行解析,返回NavGraph,NavGraph继承自NavDestination,保存了所有解析出的节点信息。

       总结,通过NavHostFragment获取到NavContorl并存储了相关Navigator信息。通过各自navigate方法进行页面跳转,通过setGraph解析配置的页面节点信息并封装为NavGraph对象。其中,通过SparseArray存储Destination信息。

       自定义Navigator实现思路主要在于继承现有FragmentNavigator并重写其navigate方法,将replace方法替换为show和hide方法,完成Fragment切换。通过@Navigator.Name(value)注解标记自定义类为Navigator,加入NavigatorProvider中即可识别。自定义Navigator核心代码实现后,需调整mobile_navigation节点中的fragment为fixFragment,并删除布局文件中NavHostFragment节点信息,手动关联FixFragmentNavigator与NavControl,完成Fragment切换时生命周期不会重新执行。

Android 原生BottomSheet 介绍及坑

       Android Support Library .2 推出之后,增加了几个功能,例如支持Vector Drawables 和Animated Vector Drawables;增加AppCompat DayNight 主题;Design 库中增加Bottom Sheets,RecyclerView 支持 auto-measurement,之前的wrap_content ,match_parent 都将可以发挥作用等等

        公司的App 之前使用过第三方的[BottomSheet] ( /BottomSheet ),现在Android 有自己的BottomSheet 那还不赶紧换成原生的。然而好事多磨,Android 原生BottomSheet 资料太少,深研下去发现BottomSheet 就是个大坑!

        BottomSheet 使用需要CoordinatorLayout作为父布局,BottomSheet 的布局作为CoordinatorLayout 的子布局,并且BottomSheetBehavior(比如加上app:layout_behavior=”android.support.design.widget.BottomSheetBehavior”)

        实际使用过程中主要依靠BottomSheetBehavior来控制BottomSheet的展示及回调。

        BottomSheetBehavior 具有五种状态:

        设置状态:

        bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);

        回调:

        强调:

        BottomSheetBehavior将能帮你实现 常驻bottom sheet( persistent bottom sheet) 的场景, 但这个版本还提供了BottomSheetDialog 和 BottomSheetDialogFragment 来实现 modal bottom sheets 的场景。只需要将AppCompatDialog 或者AppCompatDialogFragment分别替换成上述的两个控件,你就拥有了 bottom sheet 风格的对话框

        然而我们实际我们需要BottomSheetDialog 是展开的,而BottomSheetDialog只展示一部分

        原因:BottomSheetDialog默认是STATE_COLLAPSED,所有BottomSheetDialog 依靠peekHight来设置高度,系统BottomSheetDialog 默认高度为dp(查源码得知),那按理来说我们的BottomSheetDialog 高度该是dp,但是我们实际发现BottomSheetDialog高度也不等于dp。我们研究下BottomSheetBehavior的中控制BottomSheetDialog高度源码:

        通过源码我们可以得知BottomSheetBehavior通过改变child的偏移量而控制BottomSheetDialog的高度,默认状态为STATE_COLLAPSED,child向下移动mMaxOffset高度,从而控制child显示高度为mPeekHeight,这就需要child与parent 顶部对齐,child的getTop 为0;

        然而我们再去查看Android的BottomSheetDialog 内中布局R.layout.design_bottom_sheet_dialog,发现我们自定义的的BottomSheetDialog 的contentView 是放置在FrameLayout 中的,然而FrameLayout出于某些原因为垂直居中的,而不是顶部对齐,从而导致BottomSheetDialog在dp的基础上向下偏移,只展示一部分。

        所以我们可以通过下面方法解决BottomSheetDialog 的显示问题

        解决方法如下:

        当我们设置bottomSheetDialog每次点击后不new,而是直接show的话,然而当我们会bottomSheetDialog 展开后,我们将BottomSheetDialog划下隐藏后, 再点击展示BottomSheetDialog后,会发现页面只是变暗,BottomsheetDialog未展开,这是由于之前我们划下收缩隐藏BottomSheetDialog后,bottomSheetDialogBehavior的状态为隐藏,再次show之后,系统未恢复bottomSheetDialogBehavior的状态,还是隐藏,所以再次点击后页面只是变暗。

更多内容请点击【休闲】专栏