首页 文章 精选 留言 我的

精选列表

搜索[android things],共10000篇文章
优秀的个人博客,低调大师

Android笔记:onSaveInstanceState和onRestoreInstanceState总结

一、方法调用时间 onSaveInstanceState是用来保存UI状态,在Activity杀死之前,它一般在onStop或者onPause之前触发; onRestoreInstanceState是在onResume之前触发来恢复状态; Activity被杀死了,onCreate会被调用,且onRestoreInstanceState在 onResume之前恢复上次保存的信息; Activity没被杀死,onCreate不会被调用,但onRestoreInstanceState 仍然会被调用,在 onResume之前恢复上次保存的信息; 二、方法使用场景 onSaveInstanceState() 只有在Acitivity被系统kill掉时才会调用。所以通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。 onSaveInstanceState()方法只适合保存瞬态数据, 比如UI控件的状态, 成员变量的值等,而不应该用来保存持久化数据,持久化数据应该当用户离开当前的activity时,在onPause()中保存(比如将数据保存到数据库或文件中)。说到这里,还要说一点的就是在onPause()中不适合用来保存比较费时的数据,所以这点要理解。 由于onSaveInstanceState()方法方法不一定会被调用, 因此不适合在该方法中保存持久化数据, 例如向数据库中插入记录等. 保存持久化数据的操作应该放在onPause()中。若是永久性值,则在onPause()中保存;若大量,则另开线程吧,别阻塞UI线程。 三、使用方法 1.在onSaveInstanceState方法中保存bundle: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Override protected void onSaveInstanceState(BundleoutState) { super .onSaveInstanceState(outState); mMapView.onSaveInstanceState(outState); saveState(outState); } @Override protected void onRestoreInstanceState(BundleInState) { super .onRestoreInstanceState(InState); mMapView.onSaveInstanceState(InState); restoreState(InState); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 /** *进入三维模块后,该activity会被kill掉,此处保存被杀掉前的一些状态数据 * *@paramoutState */ private void saveState(BundleoutState) { outState.putParcelable(HBContant.KEY_STATE_ESTATEINFO_JSON,mJson); outState.putParcelable(HBContant.KEY_STATE_ESTATEINFO_GALLERY,mGalleryJson); outState.putParcelable(HBContant.KEY_STATE_ESTATEINFO_FLASH,mFlashJson); outState.putParcelableArrayList(HBContant.KEY_STATE_ESTATEINFO_VIDEO,mVideoList); outState.putParcelableArrayList(HBContant.KEY_STATE_ESTATEINFO_NEWS,mNewsList); outState.putParcelableArrayList(HBContant.KEY_STATE_ESTATEINFO_HOUSELIST,mEstateHouseList); } private void restoreState(BundleinState) { } 2.在oncreate或者onRestoreInstanceState方法中读取保存的bundle: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 if (savedInstanceState== null ) { //正常情况 loadTask(); } else { //进入三维图被kill后返回,恢复页面数据 mJson=savedInstanceState.getParcelable(HBContant.KEY_STATE_ESTATEINFO_JSON); mGalleryJson=savedInstanceState.getParcelable(HBContant.KEY_STATE_ESTATEINFO_GALLERY); mFlashJson=savedInstanceState.getParcelable(HBContant.KEY_STATE_ESTATEINFO_FLASH); mVideoList=savedInstanceState.getParcelableArrayList(HBContant.KEY_STATE_ESTATEINFO_VIDEO); mNewsList=savedInstanceState.getParcelableArrayList(HBContant.KEY_STATE_ESTATEINFO_NEWS); mEstateHouseList=savedInstanceState.getParcelableArrayList(HBContant.KEY_STATE_ESTATEINFO_HOUSELIST); if (mJson!= null &&mGalleryJson!= null &&mFlashJson!= null &&mVideoList!= null &&mEstateHouseList!= null ) { loadComplete(); } else { loadTask(); } } 本文转自 glblong 51CTO博客,原文链接:http://blog.51cto.com/glblong/1432616,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android学习笔记--WIFI的操作

MicrosoftInternetExplorer402DocumentNotSpecified7.8Normal0 1.什么是WIFI WIFI就是一种无线联网的技术,则又称为"热点" 2.获取WIFI网卡的状态 0-->正在关闭 1-->关闭状态 2-->正在打开 3-->网卡可用 4-->位置状态 3.操作WIFI所需要的权限 4.改变WIFI网卡的状态 例: 1.声明控件对象(略) 2.获得控件对象(略) 3.绑定事件(略) 4.创建监听器对象 PublicvoidonClick(Viewv){ WifiManagerwifiManager=(WifiManager)WifiActivity.this.getSystemService(Serivce.WIFI_SERVICE); wifiManager.setWifiEnabled(true);//打开WIfi网卡false关闭 System.out.println("wifistate--->"+wifiManager.getWifiState()); Toast.makeText(WifuActivity.this,"当前的WIFI网卡状态为"+wifiManager.getWifiState()); } 本文转自My_King1 51CTO博客,原文链接:http://blog.51cto.com/apprentice/1360563,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android 动态加载 (三) PAK 详解

pak文件经常出现于游戏的安装目录中,其实pak文件是一种特殊的游戏压缩文件,用于压缩声音、图片等资料。由于pak文件专门针对游戏设计文件结构,pak文件就是将多个文件(图片、音乐、文本)打包为一个单独文件,在pak文件中保存着多个文件的数据。 pak是什么文件? 现 在大部分游戏的客户端都采用pak压缩格式,以便于游戏的开发。由于是一种压缩格式,pak文件可以用一些专业压缩软件(如WinRAR、 WinZip)打开,但由于其特殊性与一般的压缩文件格式打开方式有所不同。pak文件一般是游戏的文件,里面存了很多游戏所需的重要文件,并且是加密了 的,现在虽说有能打开pak文件的软件,但也仅限于未加密的。不过有一些专门的浏览工具可以提取其中的声音进行修改后保存为其他格式音乐。 pak文件如何打开? 那么pak文件怎么打开呢?下面小编就收集了一些支持pak文件的软件供大家使用。 特点: 1.声音,地图,3D模型,材质贴图等文件是按着保留 目录路径结构的方式压缩入PAK文件的。 2.压缩的时候可以令压缩也可以按照一定的 压缩率压缩。 使用pak这种文件格式对于游戏的开发者和玩家都有著无以伦比的方便性和可塑性(或者说自定义性)。具体如何实现的,等一下我将举例说明。使用pak包这种形式有几点好处: 1.对于程开发人员来说资源调用方便,易于管理; 2.由于结构特殊,对初学者有屏蔽作用避免被乱改,对高手却很容易修改,比较方便; 3.所有模式都是利用这个特点做的; 4.pak包被游戏的引擎视为一个目录,能利用外置pak文件的形式进行升级而无需删除原有文件。利於增加效果包,新地图,改进界面,增加model等扩展内容; 5.修改还原便利,文件之间互不影响。 如果想要打开pak结尾的文件,使用PAk浏览器 RPGViewer 3.0 下载了以后一定要看说明书(readme.txt) 可以直接查看PAK格式的内容 PAK解压: 工具里面有“解压包”的按钮,可以解压PAK 本文转自 一点点征服 博客园博客,原文链接:http://www.cnblogs.com/ldq2016/p/5253787.html ,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android 自定义ViewGroup(一)

自定义viewgroup,这个东西可以说简单也简单,说复杂也复杂。主要是因为用到所以复习了一下,那就顺便做个笔记。 暂时只讲简单的用法 一.重要方法 (1)onMeasure 设置viewgroup的大小 (2)onLayout 设置如何摆放子View (3)generateLayoutParams 设置LayoutParams 最重要的是前面两个方法,所以说viewgroup很简单,你只需要知道在onMeasure 和 onLayout中写什么内容就行。 注:这里说的自定义viewgroup是值直接继承ViewGroup,而不是继承各种Layout之类已封装好的ViewGroup。 1.确定自己要做的viewgroup是怎么样的 首先要确认自己要做出怎样的viewgroup,因为onMeasure和onLayout 可以说是关联很小的,他们是配合使用才能出现自己想要的效果,如果不注意细节的话很容易弄错,所以要先确定自己想做出来的viewgroup是怎样的,才开始做。 2.onMeasure 首先要记好自定义onMeasure的流程,他会先调用onMeasure再调用onLayout,而onMeasure会调用多次,这个以后讲。 (1)onMeasure做的事很简单,就是测量ViewGroup的大小,准确来说是根据子View来测量viewgroup的大小。所以在onMeasure方法里面一般会用measureChildren去测量子view的大小。 (2)onMeasure方法中一般要分两种情况去测量,viewgroup在xml中定义时,宽高是不是wrap_content 你想想,如果viewgroup固定宽高或者填充父布局的话,那实际中的宽高肯定是你定义的,但是如果是wrap_content的话,你就需要自己去设置宽高让它包裹所有子View,所以自定义viewgroup的onMeasure中会分两种情况去setMeasuredDimension宽高 2.onLayout 设置完viewgroup的宽高之后,就要去摆放子view。 (1)摆放子View的规则是,设置这个view的左上角的点在viewgroup的位置: child.layout(left, top, right,bottom); 而根据这个坐标点和宽高,我们就能在viewgroup中正确的摆放子view (2)需要注意的是如果子view超出了viewgroup所onMeasure(设置好大小)的部分,那部分不会显示出来。 (3)获取子view的方法View child = getChildAt(i); 得到的view一般是addview时添加view的顺序,但是还有特殊情况,这个过后再解释。 3.generateLayoutParams 设置LayoutParams,那么LayoutParams是什么东西,一般我们给viewgroup添加view都会用到LayoutParams。 翻译过来就是布局参数,通俗点说就是能获取到布局一些特定的属性,比如说布局的边距什么的。反正你正着想,在创建view时LayoutParams设置的属性,在自定义Viewgroup中都能拿到。 这个类系统有很多子类,包括如果你牛逼的话你可以依照谷歌的这种做法,可以自定义LayoutParams,所以具体情况再说。 二.demo 逼逼了这么多,还是应该拿个例子来说,比如说流式布局 流式布局可以用自定义viewgroup来实现,虽然它也可以用recyclerview来实现,但是它的性质和RelativeLayout这些布局一样,应该是一个viewgroup。 我就找了网上一个来说啊,因为我懒得写算法。 public class BerFlowLayout extends ViewGroup { //存储所有子View private List<List<View>> mAllChildViews = new ArrayList<>(); //每一行的高度 private List<Integer> mLineHeight = new ArrayList<>(); public BerFlowLayout(Context context) { super(context); } public BerFlowLayout(Context context, AttributeSet attrs) { super(context, attrs); } public BerFlowLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //父控件传进来的宽度和高度以及对应的测量模式 int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); int modeWidth = MeasureSpec.getMode(widthMeasureSpec); int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); int modeHeight = MeasureSpec.getMode(heightMeasureSpec); //如果当前ViewGroup的宽高为wrap_content的情况 int width = 0;//自己测量的 宽度 int height = 0;//自己测量的高度 //记录每一行的宽度和高度 int lineWidth = 0; int lineHeight = 0; //获取子view的个数 int childCount = getChildCount(); for(int i = 0;i < childCount; i ++){ View child = getChildAt(i); //测量子View的宽和高 measureChild(child, widthMeasureSpec, heightMeasureSpec); //得到LayoutParams MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); //子View占据的宽度 int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; //子View占据的高度 int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; //换行时候 if(lineWidth + childWidth > sizeWidth){ //对比得到最大的宽度 width = Math.max(width, lineWidth); //重置lineWidth lineWidth = childWidth; //记录行高 height += lineHeight; lineHeight = childHeight; }else{//不换行情况 //叠加行宽 lineWidth += childWidth; //得到最大行高 lineHeight = Math.max(lineHeight, childHeight); } //处理最后一个子View的情况 if(i == childCount -1){ width = Math.max(width, lineWidth); height += lineHeight; } } //wrap_content setMeasuredDimension(modeWidth == MeasureSpec.EXACTLY ? sizeWidth : width, modeHeight == MeasureSpec.EXACTLY ? sizeHeight : height); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { mAllChildViews.clear(); mLineHeight.clear(); //获取当前ViewGroup的宽度 int width = getWidth(); int lineWidth = 0; int lineHeight = 0; //记录当前行的view List<View> lineViews = new ArrayList<View>(); int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); int childWidth = child.getMeasuredWidth(); int childHeight = child.getMeasuredHeight(); //如果需要换行 if (childWidth + lineWidth + lp.leftMargin + lp.rightMargin > width) { //记录LineHeight mLineHeight.add(lineHeight); //记录当前行的Views mAllChildViews.add(lineViews); //重置行的宽高 lineWidth = 0; lineHeight = childHeight + lp.topMargin + lp.bottomMargin; //重置view的集合 lineViews = new ArrayList(); } lineWidth += childWidth + lp.leftMargin + lp.rightMargin; lineHeight = Math.max(lineHeight, childHeight + lp.topMargin + lp.bottomMargin); lineViews.add(child); } //处理最后一行 mLineHeight.add(lineHeight); mAllChildViews.add(lineViews); //设置子View的位置 int left = 0; int top = 0; //获取行数 int lineCount = mAllChildViews.size(); for (int i = 0; i < lineCount; i++) { //当前行的views和高度 lineViews = mAllChildViews.get(i); lineHeight = mLineHeight.get(i); for (int j = 0; j < lineViews.size(); j++) { View child = lineViews.get(j); //判断是否显示 if (child.getVisibility() == View.GONE) { continue; } MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); int cLeft = left + lp.leftMargin; int cTop = top + lp.topMargin; int cRight = cLeft + child.getMeasuredWidth(); int cBottom = cTop + child.getMeasuredHeight(); //进行子View进行布局 child.layout(cLeft, cTop, cRight, cBottom); left += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; } left = 0; top += lineHeight; } } /** * 与当前ViewGroup对应的LayoutParams */ @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(), attrs); } @Override protected LayoutParams generateDefaultLayoutParams() { return new MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } @Override protected LayoutParams generateLayoutParams(LayoutParams p) { return new MarginLayoutParams(p); } } 1.onMeasure 先看onMeasure,看看它怎么测量整体父布局的。这里循环处理子view,先获取到子view的大小 //子View占据的宽度 int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; //子View占据的高度 int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; 然后判断换不换行,如果这个子view的宽度加上前面累计起来的比父布局的宽度宽,那就加一行。 其实这里的onMeasure意图很容易看懂,它的作用就是根据子view来决定高度,所以为什么我之前说要先弄清楚你想做怎么样的效果,比如这里,我想做的效果就是流式布局的效果,那这个布局的高度肯定是根据有多少行来动态决定的吧,而这里的计算就是觉得这个高度的过程。 1.onLayout 这个他这里写得有点麻烦,应该是可以再缩短一些的。 如果累加的宽度+当前子view的宽度+间距 > 一行的宽度,则换行 if (childWidth + lineWidth + lp.leftMargin + lp.rightMargin > width) { } 换行就设置累计宽度为0: lineWidth = 0; mAllChildViews就是它存储的第一个装view的二维数组。 然后再对每一行进行操作 for (int i = 0; i < lineCount; i++) {...},然后对left 和top 进行叠加操作。 其实我觉得这里可以在最上面的循环中就直接child.layout对子View进行布局,不用两次循环。他这里的思路是第一次大循环来获取行数并保存二维数组,第二次大循环再设置子view位置。 3.MarginLayoutParams 这里写的 /** * 与当前ViewGroup对应的LayoutParams */ @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(), attrs); } @Override protected LayoutParams generateDefaultLayoutParams() { return new MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } @Override protected LayoutParams generateLayoutParams(LayoutParams p) { return new MarginLayoutParams(p); } 是为了设置子view和子view间通过margin设置的间距。 4.调用 如果在xml中写子布局,可以直接用,这时设置generateLayoutParams会默认调用3个种的这个方法,你不用去关系LayoutParams。 @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(), attrs); } 但是如果是动态去添加view,你就需要自己去写MarginLayoutParams,那么可以这样写。 ViewGroup.LayoutParams lp = new ViewGroup. LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); ViewGroup.MarginLayoutParams mlp = new ViewGroup.MarginLayoutParams(lp); mlp.setMargins(10,10,10,10); textView.setLayoutParams(mlp); 三.总结 最后做个小结吧。你可以看成自定义ViewGroup不难,它就要求你会用两个方法去测量和摆放,难的是什么呢?难的是你要怎么去写算法来完成你这个viewgroup的实现,也就是两个方法中具体的代码实现,还有就是这两个方法连起来的效果和与LayoutParams配合的效果,主要是onMeasure和onLayout的配合,要非常的注意细节,比如你在onLayout设置间距,但是在onMeasure没有去开辟这个间距所需要的空间,那就会出问题,这种写多就会清楚了。

资源下载

更多资源
Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册