首页 文章 精选 留言 我的

精选列表

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

Android-- FragmentStatePagerAdapter分页(转载)

转载地址:http://blog.csdn.net/dreamzml/article/details/9951577 ViewPager ViewPager如其名所述,是负责翻页的一个 View。准确说是一个 ViewGroup,包含多个 View 页,在手指横向滑动屏幕时,其负责对 View 进行切换。为了生成这些 View 页,需要提供一个 PagerAdapter来进行和数据绑定以及生成最终的 View 页。 setAdapter() ViewPager 通过 setAdapter() 来建立与 PagerAdapter 的联系。这个联系是双向的,一方面,ViewPager 会拥有PagerAdapter 对象,从而可以在需要时调用 PagerAdapter 的方法;另一方面,ViewPager 会在 setAdapter() 中调用 PagerAdapter 的 registerDataSetObserver() 方法,注册一个自己生成的 PagerObserver 对象,从而在 PagerAdapter 有所需要时(如notifyDataSetChanged()或 notifyDataSetInvalidated() 时),可以调用 Observer 的 onChanged() 或 onInvalidated() 方法,从而实现 PagerAdapter 向 ViewPager 方向发送信息。 dataSetChanged() 在PagerObserver.onChanged(),以及 PagerObserver.onInvalide() 中被调用。因此当 PagerAdapter.notifyDataSetChanged() 被触发时,ViewPager.dataSetChanged() 也可以被触发。该函数将使用 getItemPosition() 的返回值来进行判断,如果为 POSITION_UNCHANGED,则什么都不做;如果为 POSITION_NONE,则调用 PagerAdapter.destroyItem() 来去掉该对象,并设置为需要刷新 (needPopulate = true) 以便触发PagerAdapter.instantiateItem() 来生成新的对象。 PagerAdapter PageAdapter是 ViewPager 的支持者,ViewPager 将调用它来取得所需显示的页,而 PageAdapter 也会在数据变化时,通知 ViewPager。这个类也是FragmentPagerAdapter以及FragmentStatePagerAdapter的基类。如果继承自该类,至少需要实现 instantiateItem(), destroyItem(), getCount() 以及 isViewFromObject()。 getItemPosition() 该函数用以返回给定对象的位置,给定对象是由 instantiateItem() 的返回值。 在 ViewPager.dataSetChanged() 中将对该函数的返回值进行判断,以决定是否最终触发 PagerAdapter.instantiateItem() 函数。 在 PagerAdapter 中的实现是直接传回POSITION_UNCHANGED。如果该函数不被重载,则会一直返回 POSITION_UNCHANGED,从而导致 ViewPager.dataSetChanged() 被调用时,认为不必触发 PagerAdapter.instantiateItem()。很多人因为没有重载该函数,而导致调用 PagerAdapter.notifyDataSetChanged() 后,什么都没有发生。 instantiateItem() 在每次 ViewPager 需要一个用以显示的 Object 的时候,该函数都会被 ViewPager.addNewItem()调用。 notifyDataSetChanged() 在数据集发生变化的时候,一般 Activity 会调用 PagerAdapter.notifyDataSetChanged(),以通知 PagerAdapter,而 PagerAdapter 则会通知在自己这里注册过的所有DataSetObserver。其中之一就是在 ViewPager.setAdapter() 中注册过的 PageObserver。PageObserver 则进而调用 ViewPager.dataSetChanged(),从而导致 ViewPager 开始触发更新其内含 View 的操作。 FragmentPagerAdapter FragmentPagerAdapter继承自 PagerAdapter。相比通用的 PagerAdapter,该类更专注于每一页均为 Fragment 的情况。如文档所述, 该类内的每一个生成的 Fragment 都将保存在内存之中,因此适用于那些相对静态的页,数量也比较少的那种;如果需要处理有很多页,并且数据动态性较大、占用内存较多的情况,应该使用 FragmentStatePagerAdapter。FragmentPagerAdapter 重载实现了几个必须的函数,因此来自 PagerAdapter 的函数,我们只需要实现 getCount(),即可。且,由于 FragmentPagerAdapter.instantiateItem() 的实现中,调用了一个新增的虚函数 getItem(),因此,我们还至少需要实现一个 getItem()。因此,总体上来说,相对于继承自 PagerAdapter,更方便一些。 getItem() 该类中新增的一个虚函数。函数的目的为生成新的Fragment 对象。重载该函数时需要注意这一点。在需要时,该函数将被 instantiateItem() 所调用。 如果需要向 Fragment 对象传递相对静态的数据时,我们一般通过 Fragment.setArguments() 来进行,这部分代码应当放到 getItem()。它们只会在新生成 Fragment 对象时执行一遍。 如果需要在生成 Fragment 对象后,将数据集里面一些动态的数据传递给该 Fragment,那么,这部分代码不适合放到 getItem() 中。因为当数据集发生变化时,往往对应的 Fragment 已经生成,如果传递数据部分代码放到了 getItem() 中,这部分代码将不会被调用。这也是为什么很多人发现调用 PagerAdapter.notifyDataSetChanged() 后,getItem() 没有被调用的一个原因。 instantiateItem() 函数中判断一下要生成的 Fragment 是否已经生成过了,如果生成过了,就使用旧的,旧的将被 Fragment.attach();如果没有,就调用 getItem() 生成一个新的,新的对象将被 FragmentTransation.add()。 FragmentPagerAdapter 会将所有生成的 Fragment 对象通过 FragmentManager 保存起来备用,以后需要该 Fragment 时,都会从 FragmentManager 读取,而不会再次调用 getItem() 方法。 如果需要在生成 Fragment 对象后,将数据集中的一些数据传递给该 Fragment,这部分代码应该放到这个函数的重载里。在我们继承的子类中,重载该函数,并调用 FragmentPagerAdapter.instantiateItem() 取得该函数返回 Fragment 对象,然后,我们该 Fragment 对象中对应的方法,将数据传递过去,然后返回该对象。 否则,如果将这部分传递数据的代码放到 getItem()中,在 PagerAdapter.notifyDataSetChanged() 后,这部分数据设置代码将不会被调用。 destroyItem() 该函数被调用后,会对 Fragment 进行FragmentTransaction.detach()。这里不是 remove(),只是 detach(),因此 Fragment 还在 FragmentManager 管理中,Fragment 所占用的资源不会被释放。 FragmentStatePagerAdapter FragmentStatePagerAdapter和前面的 FragmentPagerAdapter 一样,是继承子 PagerAdapter。但是,和 FragmentPagerAdapter 不一样的是,正如其类名中的 'State' 所表明的含义一样,该 PagerAdapter 的实现将只保留当前页面,当页面离开视线后,就会被消除,释放其资源;而在页面需要显示时,生成新的页面(就像 ListView 的实现一样)。这么实现的好处就是当拥有大量的页面时,不必在内存中占用大量的内存。 getItem() 一个该类中新增的虚函数。 函数的目的为生成新的Fragment 对象。 Fragment.setArguments() 这种只会在新建 Fragment 时执行一次的参数传递代码,可以放在这里。 由于 FragmentStatePagerAdapter.instantiateItem() 在大多数情况下,都将调用 getItem() 来生成新的对象,因此如果在该函数中放置与数据集相关的 setter 代码,基本上都可以在 instantiateItem() 被调用时执行,但这和设计意图不符。毕竟还有部分可能是不会调用 getItem() 的。因此这部分代码应该放到 instantiateItem() 中。 instantiateItem() 除非碰到 FragmentManager 刚好从 SavedState 中恢复了对应的 Fragment 的情况外,该函数将会调用 getItem() 函数,生成新的 Fragment 对象。新的对象将被 FragmentTransaction.add()。 FragmentStatePagerAdapter 就是通过这种方式,每次都创建一个新的 Fragment,而在不用后就立刻释放其资源,来达到节省内存占用的目的的。 destroyItem() 将 Fragment 移除,即调用FragmentTransaction.remove(),并释放其资源。 本文转自demoblog博客园博客,原文链接http://www.cnblogs.com/0616--ataozhijia/p/3653335.html如需转载请自行联系原作者 demoblog

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

Android SufaceView 背景设置透明

之前没有接触过SurfaceView,现在项目需求用到了,发现SurfaceView在绘制(Canvas画图)的时候背景变黑了。尝试了下在xml将其设置为背景透明,没有起作用。便用了个比较笨的办法,即首先获取程序的背景,然后在绘制surfaceview之前先把背景绘制上去。这个方法实在是很笨。今天看了下文档,发现在代码里设置如下就可以背景透明了。记录下。 mSurfaceView.setZOrderOnTop(true); mSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT); 看来以后开发还是要多看看google的文档。可以少走很多弯路啊 本文转自java豆子博客园博客,原文链接:http://www.cnblogs.com/error404/archive/2013/02/05/2892709.html,如需转载请自行联系原作者

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

android闹钟——原代码

手机当中肯定是有闹钟的,这是不用说的,要不然就不是手机了。对吧。 下面我根据广播的方式写了一个闹钟,大家请看图: 下面让我们看一下原代码的是如何写的, packagecom.smart; importjava.util.Calendar; importandroid.app.Activity; importandroid.content.BroadcastReceiver; importandroid.content.Context; importandroid.content.Intent; importandroid.content.SharedPreferences; importandroid.media.MediaPlayer; publicclassAlarmReceiverextendsBroadcastReceiver{ /** *通过广播进行扫描,是否到达时间后再响起闹铃 * **/ @Override publicvoidonReceive(Contextcontext,Intentintent){ SharedPreferencessharedPreferences=context.getSharedPreferences("alarm_record",Activity.MODE_PRIVATE); Stringhour=String.valueOf(Calendar.getInstance().get(Calendar.HOUR_OF_DAY)); Stringminute=String.valueOf(Calendar.getInstance().get(Calendar.MINUTE)); Stringtime=sharedPreferences.getString(hour+":"+minute,null);//小时与分, if(time!=null){//判断是否为空,然后通过创建, MediaPlayermediaPlayer=MediaPlayer.create(context,R.raw.llb); mediaPlayer.start();//开始 } } } packagecom.smart; importandroid.app.Activity; importandroid.app.AlarmManager; importandroid.app.AlertDialog; importandroid.app.PendingIntent; importandroid.content.Context; importandroid.content.DialogInterface; importandroid.content.Intent; importandroid.content.SharedPreferences; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; importandroid.widget.TextView; importandroid.widget.TimePicker; publicclassMainextendsActivityimplementsOnClickListener{ privateTextViewalarmRecord; privateSharedPreferencessharedPreferences; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); ButtonaddAlarm=(Button)findViewById(R.id.addAlarm); alarmRecord=(TextView)findViewById(R.id.alarmRecord); addAlarm.setOnClickListener(this); sharedPreferences=getSharedPreferences("alarm_record",Activity.MODE_PRIVATE); AlarmManageraManager=(AlarmManager)getSystemService(Context.ALARM_SERVICE); Intentintent=newIntent(this,AlarmReceiver.class); PendingIntentpendingIntent=PendingIntent.getBroadcast(this,0,intent,0); aManager.setRepeating(AlarmManager.RTC,0,60*1000,pendingIntent); } @Override publicvoidonClick(Viewv){ Viewview=getLayoutInflater().inflate(R.layout.llb,null);// finalTimePickertimePicker=(TimePicker)view.findViewById(R.id.timepicker); timePicker.setIs24HourView(true);// newAlertDialog.Builder(this).setTitle("设置闹铃时间").setView(view).setPositiveButton("确定",newDialogInterface.OnClickListener(){ //设置标题 @Override publicvoidonClick(DialogInterfacedialog,intwhich){ //按钮事件触发方法 StringtimeStr=String.valueOf(timePicker.getCurrentHour())+":"+String.valueOf(timePicker.getCurrentMinute()); alarmRecord.setText(alarmRecord.getText().toString()+"\n"+timeStr); sharedPreferences.edit().putString(timeStr,timeStr).commit(); } }).setNegativeButton("取消",null).show(); } } 本文转自 llb988 51CTO博客,原文链接:http://blog.51cto.com/llb988/515862,如需转载请自行联系原作者

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

将XML文件写入android

----formshow newpath := '/storage/sdcard0/DCIM/100ANDRO/GRJKDAGLGXYSF'; if not TDirectory.Exists (newpath) then begin TDirectory.CreateDirectory (newpath); //Create a folder end; newpath := newpath + '/'; ----存入本机 var filename:string; newfile:Tfilestream; begin filename := 'update_sf_' + formatdatetime('yyyy-MM-dd',now) + gxyglkId; newfile := TFile.Create (newpath + filename); newfile.Free; clientdatasetlocal.SaveToFile(newpath + filename,dfXML); end; ---创建文件 var newpath:string; newfile:Tfilestream; begin newpath := '/storage/sdcard0/DCIM/100ANDRO/GRJKDAGLF'; if TFile.Exists (newpath + '/update.xml') then begin ShowMessage ('File exists'); end else begin newfile := TFile.Create (newpath + '/update.xml'); //Create a file (stream) newfile.Free; //Clear Stream // SpeedButton5Click (Self); //Close the window // TotalWork (path, True); //Update the list end; ---创建文件路径 var newpath:string; begin newpath := '/storage/sdcard0/DCIM/100ANDRO/GRJKDAGLF'; showmessage(newpath); if TDirectory.Exists (newpath) then begin ShowMessage ('Folder Exists!'); end else begin TDirectory.CreateDirectory (newpath); //Create a folder ShowMessage ('Folder created!'); // SpeedButton5Click (Self); //Close the window // TotalWork (path, True); //Update the list end; 本文转自鹅倌51CTO博客,原文链接:http://blog.51cto.com/kaixinbuliao/1535172,如需转载请自行联系原作者

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

Android笔记:Fragment相关问题

这两天在使用Fragment做播放器里的播放列表和歌词显示两个界面的替换与更新时发现了很多问题,在此记录下问题及解决方法: 1.多个Fragment在replace后(并且都加入了后退栈ft.addToBackStack(null)),通过点击按钮事件移除顶层的fragment(使用remove方法),返回后的fragment的oncreatview方法有执行,但是页面仍然没法自行更新数据,页面空白,UI控件都消失了。 解决:不用remove方法,改用通过popBackStack()方法直接将栈顶的fragment弹出,然后直接恢复到要返回的那个fragment。 1 getSupportFragmentManager().popBackStack(); 2.使用popBackStack()方法后,页面控件恢复了,但是数据并没有同步更新。 解决:这个问题困扰了很久,后来讲replace方法改成了add方法,并且在add之前将原先的fragment隐藏掉hide。这样在点击按钮收回播放列表的fragment后,返回的歌词fragment的显示进度是同步的了。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // 打开播放列表 private void btnClick_playinglist() { FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); Fragment fragment = new PlayingListFragment(); if (isOpenPlayingList) //播放类表是否已打开 { getSupportFragmentManager().popBackStack(); mPlaying_img_openlist.setImageResource(R.drawable.icon_playing_img_openlist); isOpenPlayingList = false ; } else { ft.hide(mFragment); ft.add(R.id.playing_fragment_layout, fragment); ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); ft.addToBackStack( null ); mFragment = fragment; mPlaying_img_openlist.setImageResource(R.drawable.icon_playing_img_openlist_press); isOpenPlayingList = true ; } ft.commit(); } 3.通过按钮点击可以正常弹出顶层的播放列表fragment了,同时歌词界面的fragment仍然同步更新。但是用按钮点击打开播放列表fragment,然后用back键返回,第一次正常,多次后歌词fragment就开始变成空白。将fragment的背景颜色修改成红色,异常界面就是红色。由此可见,通过back键返回的fragment仍然没有恢复和更新。 解决:这个不清楚具体原因,应该是使用back返回键和通过调用popBackStack()方法来移除fragment的机制不一样所导致的。这个找不到具体的解决办法,只能先采用规避方法,通过重写back监听方法,进而调用popBackStack()解决了这个问题。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 //重写监听back键按钮 @Override public void onBackPressed() { getSupportFragmentManager().popBackStack(); if (isOpenPlayingList) //判断播放列表是否打开 { mPlaying_img_openlist.setImageResource(R.drawable.icon_playing_img_openlist); isOpenPlayingList = false ; } else { super .onBackPressed(); } } 本文转自 glblong 51CTO博客,原文链接:http://blog.51cto.com/glblong/1252393,如需转载请自行联系原作者

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

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

优质分享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等操作系统。

用户登录
用户注册