Android初级教程通过简要分析“土司”源码,来自实现定义土司理论探讨
由于系统自带的土司瞬间即逝,而且非常难看。因此我们就希望自定义自己的土司风格。有些实例就是基于自定义土司完成的,例如金山卫士的火箭发射,基本原理就是个土司。但是在做出自己的土司风格之前,还是要简要分析一下土司的源码。看看系统自带的土司是如何实现的。此篇文章,对土司源码进行简要分析(由于笔者能力有限,全部源代码每一行都看懂不切实际,其实有些时候没必要太过追求细节,没必要追求每一行都看懂,能抓住源码的主要思路与核心代码就够了),理出系统实现土司的原理,和它的核心代码。在Android简易实战专栏里的
第十话,会举一个自定义土司的实例。来对这种知识点加深印象。
1,分析:看系统的Toast是怎么做出来
Toast.makeText(getApplicationContext(), "111", 1).show();
首先看一下土司的构造函数源码:
public Toast(Context context) {//传递了一个上下文对象
mContext = context;//被上下文对象给了mContext
mTN = new TN();//在这里创建TN对象
//给TN两个属性值(这里没必要追求太深入具体)
mTN.mY = context.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.toast_y_offset);
mTN.mGravity = context.getResources().getInteger(
com.android.internal.R.integer.config_toastDefaultGravity);
}
在这里只需要记住一点很重要的地方,创建土司构造函数,生成了一个TN对象就行,因为后边会用的到它。
a, makeText方法
//记得上边具体意义哦:构造土司对象,创建TN的实例 mTN = new TN();
Toast result = new Toast(context); LayoutInflater inflate = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null);//设置了一个自定义view布局(就是土司的布局)
//土司显示的文本框
TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message);
tv.setText(text);//设置文本 result.mNextView = v;//把当前土司的view给mNextView属性
result.mDuration = duration;//土司显示的时长 return result; b,show方法
if (mNextView == null) {//只要设定了view九部委null这里不会执行
throw new RuntimeException("setView must have been called");
} INotificationManager service = getService();//获取INotificationManager对象
String pkg = mContext.getPackageName();//获取包名
TN tn = mTN;//注意这个TN对象,开始提到过
tn.mNextView = mNextView;//把土司的view给了TN的mNextView属性 try {
service.enqueueToast(pkg, tn, mDuration);//这当你写多条土司时,会排队显示,其实都把每个土司对应的view放入了队列里面了
} catch (RemoteException e) {
// Empty
}
c, TN的源代码
TN的构造函数: 初始化LayoutParamsc, TN的源代码
TN的构造函数: 初始化LayoutParams
TN() {//再想一开始的时候,土司构造函数创建,内部实例化这个TN构造。不用再乎太多细节,这里其实是给土司设置一些参数,可以看到
//获取了一个 windowmanager实例。并给其设置对齐方式、动画、标题等等
// XXX This should be changed to use a Dialog, with a Theme.Toast
// defined that sets up the layout params appropriately.
final WindowManager.LayoutParams params = mParams;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
params.format = PixelFormat.TRANSLUCENT;
params.windowAnimations = com.android.internal.R.style.Animation_Toast;
params.type = WindowManager.LayoutParams.TYPE_TOAST;
params.setTitle("Toast");
}
public void handleShow() {
if (localLOGV) Log.v(TAG, "HANDLE SHOW: " + this + " mView=" + mView
+ " mNextView=" + mNextView);
if (mView != mNextView) {
// remove the old view if necessary
handleHide();
mView = mNextView;
mWM = WindowManagerImpl.getDefault();//获取WindowManager对象
final int gravity = mGravity;
mParams.gravity = gravity;
if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) {
mParams.horizontalWeight = 1.0f;
}
if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) {
mParams.verticalWeight = 1.0f;
}
mParams.x = mX;
mParams.y = mY;
mParams.verticalMargin = mVerticalMargin;
mParams.horizontalMargin = mHorizontalMargin;
if (mView.getParent() != null) {
if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this);
mWM.removeView(mView);
}
if (localLOGV) Log.v(TAG, "ADD! " + mView + " in " + this);
//土司显示的真正代码
mWM.addView(mView, mParams);//使用WindowManager对象,把土司的view以及参数加载进这个对象(这里看出,土司不是基于activity的,而是基于window的)
trySendAccessibilityEvent();
}
}
2,分析最终结果(怎么添加toast):
土司是加载到WindowManager中
mView 土司显示的View
mParams 土司在windowmanager中显示的参数配置
mWM.addView(mView, mParams);
好的,如果看得费劲,可以理解最后一句代码吧?
mWM.addView(mView, mParams);
就是自定义一个view,再给土司在Windowmanager中的显示参数做一些配置,最后加载到WindowManager中就行了。
在Android简易实战专栏里的 第十话中,会把模拟金山手机卫士那个小火箭发射的案例,通过这个案例,相信能做出更好的自定义土司效果。
Android初级教程通过简要分析“土司”源码,来自实现定义土司理论探讨的更多相关文章
- Android源码分析--CircleImageView 源码详解
源码地址为 https://github.com/hdodenhof/CircleImageView 实际上就是一个圆形的imageview 的自定义控件.代码写的很优雅,实现效果也很好, 特此分析. ...
- 【转载】Android异步消息处理机制详解及源码分析
PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbob ...
- [源码分析] 从源码入手看 Flink Watermark 之传播过程
[源码分析] 从源码入手看 Flink Watermark 之传播过程 0x00 摘要 本文将通过源码分析,带领大家熟悉Flink Watermark 之传播过程,顺便也可以对Flink整体逻辑有一个 ...
- android 在线升级借助开源中国App源码
android 在线升级借助开源中国App源码 http://www.cnblogs.com/luomingui/p/3949429.html android 在线升级借助开源中国App源码分析如下: ...
- 【Android 系统开发】CyanogenMod 13.0 源码下载 编译 ROM 制作 ( 手机平台 : 小米4 | 编译平台 : Ubuntu 14.04 LTS 虚拟机)
分类: Android 系统开发(5) 作者同类文章X 版权声明:本文为博主原创文章 ...
- Android 图片加载框架Glide4.0源码完全解析(二)
写在之前 上一篇博文写的是Android 图片加载框架Glide4.0源码完全解析(一),主要分析了Glide4.0源码中的with方法和load方法,原本打算是一起发布的,但是由于into方法复杂性 ...
- Android 进阶16:IntentService 使用及源码解析
It's time to start living the life you've only imagined. 读完本文你将了解: IntentService 简介 IntentService 源码 ...
- Android 全面插件化 RePlugin 流程与源码解析
转自 Android 全面插件化 RePlugin 流程与源码解析 RePlugin,360开源的全面插件化框架,按照官网说的,其目的是“尽可能多的让模块变成插件”,并在很稳定的前提下,尽可能像开发普 ...
- Android斗地主棋牌游戏牌桌实现源码下载
本次给大家分享下Android斗地主棋牌游戏牌桌实现源码下载如下: 为了节约内存资源,每张扑克牌都是剪切形成的,当然这也是当前编程的主流方法. 1.主Activity package com.biso ...
随机推荐
- hdu 5877 线段树(2016 ACM/ICPC Asia Regional Dalian Online)
Weak Pair Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- Codeforces Round #419 D. Karen and Test
Karen has just arrived at school, and she has a math test today! The test is about basic addition an ...
- BZOJ4943 [NOI2017] 蚯蚓
题目描述 蚯蚓幼儿园有nn 只蚯蚓.幼儿园园长神刀手为了管理方便,时常让这些蚯蚓们列队表演. 所有蚯蚓用从11 到nn 的连续正整数编号.每只蚯蚓的长度可以用一个正整数表示,根据入园要求,所有蚯蚓的长 ...
- 例10-7 uva10820(欧拉)
题意:输入n,要求满足1≤x,y≤n,且x,y互素的个数. 若输入2,则答案3为(1,1),(1,2),(2,1);所以欧拉函数求出所有数的phi值,除了1之外都加上phi值的2倍即可 通过推导: p ...
- [APIO/ctsc2007]
A.风铃 给一棵二叉树,叶子结点是玩具,为使你的弟弟满意,你需要选一个满足下面两个条件的风铃: (1) 所有的玩具都在同一层(也就是说,每个玩具到天花板之间的杆的个数是一样的)或至多相差一层.(2) ...
- 记一次java heap space的解决办法
问题缘由:后台上传excel导入到数据库,数据量太大,导致报错. 解决方案: 用jdk自带的性能分析器(jconsole)查看了一下,当excel开始导入的时候,发现堆空间直接爆掉. 增加堆空间,在c ...
- JS中怎样判断undefined(比较不错的方法)
最近做项目碰到的问题.拿出来跟大家分享一下吧. 用servlet赋值给html页面文本框值后,用alert来弹出这个值.结果显示"undefined".所以我就自然的用这个值和字符 ...
- React 关于组件(界面)更新
在最近在学 React , 将组件的UI更新稍微整理了一下.根据业务要求,可能会出现如下的技术实现要求:1.更新自己2.更新子组件3.更新兄弟组件4.更新父组件5.父 call 子 function ...
- jieba库分词统计
代码在github网站,https://github.com/chaigee/chaigee,中的z3.py文件 py.txt为团队中文简介文件 代码运行后词频统计使用xlwt库将数据发送到excel ...
- 操作系统内存管理之 内部碎片vs外部碎片
外部碎片:因为行程持续地被载入与置换,使得可用的记忆体空间被分割成许多不连续的区块.虽然记忆体所剩空间总和足够让新行程执行,却因为空间不连续,导致程式无法载入执行.内部碎片:发生在以固定长度分割区来进 ...