首页 文章 精选 留言 我的

精选列表

搜索[多语言适配],共10000篇文章
优秀的个人博客,低调大师

是时候为各式设备适配完善的输入支持了

随着技术进步以及跨平台应用的普及,您的 Android 应用已经不再局限于在直板触屏设备运行了。更丰富的交互方式使得用户能够以更复杂的输入方式使用您的应用。所以作为开发者,是时候考虑为各种各样的设备提供强大的输入支持了。本文为您准备了关于更广泛、强大的输入支持的分享,欢迎您阅读。 如果您更喜欢通过视频了解此内容,请 点击此处 查看。 对于各种 Android 设备来说,输入 (input) 是决定用户应用体验的关键要素之一。开发者通常希望用户交互方式能尽可能简单直观,但是假如您新买了一个可折叠设备,附赠了一款键盘,而您喜欢的应用却不支持标准按键操作,这种体验将非常令人沮丧。 目前许多 Android 设备内置了非触摸输入 (non-touch input),比如 Chromebook 键盘,甚至一些设备将其作为标配提供。那么在诸如手机、可折叠设备、平板电脑、Chromebook、支持外接显示屏的 Chromebox、带内置显示器的 Chromebase、Android TV 等各种 Android 设备类型中,开发者应该如何确保不同的输入方式适用于自己的应用。 △ 多种 Android 设备 要知道并非所有的用户都使用手机触摸屏与您的应用交互,一部分用户可能使用的是键盘和触控笔等,甚至一部分用户有 无障碍 需求。那么每位开发者都有必要花些时间去思考,如何使应用为尽可能多的用户带来愉快的使用体验? 增强输入 (Enhanced input) △ 标准输入方式和增强输入方式 对于每种类型的输入设备,我们可以将应用的功能分为标准用例和增强用例两大类: 标准用例包括选择、文本输入、长按和右键点击等这些用户所期望的功能,处理此类用例的技术实现比较简单且在某些情况下可以自动执行。如果想要为应用提供更多独特和增强的支持,则需要开发者多加考虑。 在增强用例中,某些功能不只是有了更好,而可能是必需具备的,例如一款不支持游戏手柄的手机游戏和一款不支持标准复制和粘贴快捷键的文本编辑器,都是无法受到用户欢迎的。 在提供基础功能外,要考虑添加独特且能为用户提供支持的功能,这才是开发者让自己应用真正脱颖而出的方法。例如,如下所示的 eDJing 这款应用,它添加了对键盘打碟和触控板搓碟以及 MIDI DJ 控制器的支持,用户手中的手机或 Chromebook 就能够立即摇身一变成为 DJ 工作站。 △ eDJing 应用使用场景 Cubasis 是一款一流的数字音频工作站应用,它发布了基于 Chrome OS 操作系统优化的新版本,凭借大屏幕的优势以及 MIDI 控制器连接 Chromebook 的便利性,不仅增强了功能,还提升了应用实用性。 △ Cubasis 应用使用场景 绘图类应用则更加注重: 蓝牙和 USB 绘图板能够持续正常的工作,以及在 Chrome OS 操作系统中将低延迟触控笔 API 应用到绘图和绘画应用中。 △ 绘图类应用使用场景 简而言之,用户希望能在您的应用中获得独特、愉悦、直观的体验,而这种体验由您来打造! 键盘输入支持 键盘被内置在 Chromebook 中,或是成为用户在使用可拆卸设备、平板电脑、可折叠设备和电视过程中日常体验的一部分。好消息是大多数基本键盘输入通常可以直接使用,除非您正致力于构建自己的屏幕键盘或从头开始编写自己的文本输入视图。 发送键支持 (KEYCODE_ENTER) 开发者需要在标准的 EditText 视图中为 Enter 键创建一个新行。如果您的应用中有聊天功能、反馈表单、简报注册或任何需要发送文本的功能,那么默认的换行行为肯定不是您所期望的,不用担心的是您所预期的发送功能很容易实现。 △ 聊天发送文本 开发者需要在标准的 EditText 视图中为 Enter 键创建一个新行,此处显示了按下 Enter 键的代码,完整代码如下所示: override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean { when (keyCode) { KEYCODE_ENTER -> { // 撤销 onKeyUp 并监听 KEYCODE_ENTER sendMessage() return true // 如果应用已处理按键事件则确保返回 true } } // 如果没有处理事件,则交回系统处理 return super.onKeyUp(keyCode, event) // 如果没有则将事件传递给 super } 媒体键支持 (Media key) 如果您的应用希望支持媒体播放,则还需要包含媒体键支持。为此请将 Enter 键代码中的 KEYCODE_ENTER 替换为您希望支持的媒体键代码即可,比如这里使用了 MEDIA_NEXT 和 MEDIA_PREV。此外请不要忘记使用 SPACE 以便用空格键来控制播放和暂停。完整代码如下所示: override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean { when (keyCode) { KEYCODE_SPACE, KEYCODE_MEDIA_PLAY_PAUSE -> { playOrpauseMedia(); return true } KEYCODE_MEDIA_NEXT -> {nextTrack(); return true } KEYCODE_MEDIA_PREV -> {prevTrack(); return true } } // 如果没有处理事件,则交回系统处理 return super.onKeyUp(keyCode, event) } 游戏键支持 (KEYCODE_W|A|S|D) 对于游戏应用,您可能希望包括对箭头键和 W、A、S、D 四个按键的支持,这同样很简单。您只需在 Android 文档中找到正确的 键代码,并监听这些按键即可。完整代码如下所示: when (keyCode) { KEYCODE_W, DPAD_UP -> { goUp(); return true } KEYCODE_A, DPAD_LEFT -> { goLeft(); return true } KEYCODE_S, DPAD_DOWN -> { goDown(); return true } KEYCODE_D, DPAD_RIGHT -> { goRight(); return true } } 需要注意的是在提供键盘支持时通常要监听 onKeyUp,这样您就不必担心在按住某个键时,将会发送重复的 onKeyDown 事件。另外如果您想确保实现毫秒级的时间响应,您可以监听 onKeyDown 并自行处理重复的按键事件。完整代码如下所示: override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { when (keyCode) { KEYCODE_F -> { shootFireball() return true } } return super.onKeyUp(keyCode, event) } 更多相关信息请访问: ChromeOS.dev 快捷键支持 (Ctrl+) 除了基本键盘按键,还需要考虑的是配置基于 Ctrl 的快捷键,复制、粘贴、撤消、重做等,很常见的快捷键适用于许多应用。出色的键盘支持将会帮助您的应用实现更多的功能,一些应用甚至更进一步将高级功能放在用户触手可及的地方,比如用户在使用 eDJing 应用时,只需按住 Ctrl 键就可以用触控板搓碟。 如下展示了用于撤消的 Ctrl+Z 快捷键的代码,这部分代码类似于前面的 onKeyUp 和 onKeyDown 代码,但使用了 dispatchKeyShortcutEvent 来指示元键组合。请注意此时按下 Alt、Ctrl 或 Shift 键即可触发此操作。完整代码如下所示: override fun dispatchKeyShortcutEvent(event: KeyEvent): Boolean { return when (event.getKeyCode()) { KEYCODE_Z -> { undoAction() // [Ctrl]+z, [Shift]+z, 或 [Alt]+z 触发 true } else -> { super.dispatchKeyShortcutEvent(event) } } } 如果您只希望响应特定的元键组合,可以使用 Meta_Alt_On,也可以使用类似 isShiftPressed() 或 isCtrlPressed() 的方法。完整代码如下所示: when { event.isCtrlPressed && event.isShiftPressed -> { redoAction(); true // [Ctrl]+[Shift]+z 触发 } event.isCtrlPressed -> { undoAction(); true //[Ctrl]+z 触发 } else -> { // 交给系统处理 super.dispatchKeyShortcutEvent(event) } } 根据此处代码,只有在同时按下 Ctrl+Z 时才会执行撤消操作,同样只有在同时按下 Ctrl+Shift+Z 时才会执行重做操作,并不会用到 Alt。 鼠标/触控板输入支持 与键盘一样,大多数鼠标和触控板输入通常不需要任何额外的代码就可以工作。但开发者还是有必要使用鼠标测试应用的所有功能,查看是否有任何疏漏。 △ 鼠标 右键点击支持 右键点击是最常见的疏漏之一。触控的一个常见范例是在屏幕上长按以执行基于上下文的操作,但长按鼠标点击并不直观。如果要支持右键点击,此处有几种方案可供选择。此处显示了添加上下文菜单的代码,完整代码如下所示: registerForContextMenu(myView) // 首先为上下文菜单注册一个或多个视图,这将自动处理长按和右键点击两种操作。 ... override fun onCreateContextMenu(menu, view, menuInfo) { super.onCreateContextMenu(menu, view, menuInfo) menuInflater.inflater(R.menu.myContextMenu, menu) // 然后撤销 overrideonCreateContextMenu 并扩展正确的菜单布局,同一菜单可用于多个视图。 } override fun onCreateContextMenu(item: MenuItem): Boolean { return when(item.itemId){ R.id.myMenuItemId -> { menuItemAction(); true } else -> { return super.onContextItemSelected(item) } // 最后,设置 onContextItemSelected 指示选中特定菜单项时需要执行的操作。 } } 对于上下文菜单之外的其他右键点击行为,可以用 onContextClickListener 设置视图,只需使用它调用在长按用例中使用的相同方法即可。对应代码如下所示: myView.setOnContextClickListener { performContextAction() true } 悬停响应支持 用户在使用鼠标或触控板时,通常希望界面能够以某种方式做出响应。例如当鼠标光标悬停在可点击的视图上时会产生视觉反馈,如图所示,可能是指针图标发生了变化,又或者出现一些其他视觉指示,这些都可以被用户直观感受到。此处显示了指针悬停在视图上时的代码,完整代码如下所示: myView.setOnHoverListener { view, motionEvent -> //为视图设置 onHoverListener when (motionEvent.action) { ACTION_HOVER_ENTER -> { view.pointerIcon = PointerIcon.getSystemIcon( appIicationContext, PointerIcon.TYPE_HAND ) view.setBackgroundColor(Color.BLUE) true } // 监听 HOVER_ENTER 事件并执行相应的操作。根据代码显示指针图标将变为手形且背景颜色将变为蓝色。 ACTION_HOVER_EXIT -> { resetUI(); } else -> { false } // 不要忘记设置当 HOVER_EXIT 发生时重置图标和背景颜色。 } } 指针捕获支持 指针捕获是另一个常见的鼠标和触控板增强功能,不但对于一些游戏至关重要,并且还可以为某些应用添加特定功能。应用能够通过指针捕获功能捕获鼠标光标,使光标不出现在屏幕上,这样无需将光标移动到屏幕边缘就可以接收相对的指针事件。像 Minecraft: 教育版等第一人称视角游戏就是很好的案例。 △ Minecraft: 教育版 要支持指针捕获,可以先调用 requestPointerCapture,然后再调用 releasePointerCapture 释放捕获的指针。在代码中可以添加 OnCapturedPointerListener 使用接收的指针数据,并利用指针位置的相对变化来实现一些很棒的功能。完整代码如下所示: view.requestPointerCapture() ... view.releasePointerCapture() ... view.setOnCapturedPointerListener { _, motionEvent -> // 计算自从上次 motionEvent 事件后的坐标增量 mouseChangeX = motionEvent.x mouseChangey = motionEvent.y // 计算自从上次 motionEvent 事件后的位移 val totalDistance = hypot(mouseChangeX, mouseChangeY) doSomethingCool(totalDistance) } 手势支持 此外 Android API 还提供了高级指针处理,可以添加手势、双指张合和缩放支持等,如下图所示。 如果您希望了解更多 Android API 的相关信息,请参阅 Android 开发者网站获取入门指南——使用轻触手势。 触笔输入支持 如果您已经在应用中添加对指针的出色支持,那么对于大多数用例来说触控笔通常能够按预期正常工作。关于触控笔的一些增强功能非常值得关注,比如部分设备支持触控笔倾斜和按压,这有助于您在绘画或绘图应用添加一些出色的控件和功能。此外还有低延迟触控笔 API 可让您在绘画或绘图应用中获得最低延迟的显示响应,并提供可配置的描边预测,为您打造用笔在纸上绘图的体验。如需了解实际效果,请在受支持的 Chromebook 或 Android 设备上查看类似于 Concepts 的应用。 △ Concepts 应用对触控笔支持 如需 了解实现细节,请参阅 Android 开发者网站有关 AXIS_PRESSURE 和 AXIS_TILT 的文档。 低延迟触控笔 API 库和演示版应用,请参阅 GitHub。 在 Android 模拟器中使用触控笔 我们与 Microsoft 合作将主机触控笔支持引入 Android 模拟器中,如果您正在优化应用以提供更高级的触控笔支持,那么您将可以在支持的主机上使用 Android 模拟器测试精确的倾斜和按压控制。 Microsoft Surface Duo 开发者体验团队与 Google 合作开展了一项支持高级输入开发和测试的工作,比如多点触控分析和触控笔支持。那么在模拟器中运行应用时如何使用触控笔测试应用? △ 在模拟器中测试触控笔 如图所示,显示的是 Surface Studio 上运行的 Microsoft Duo 2 模拟器,此刻有两款应用在同时运行: 右侧窗格是示例应用,该示例允许您测试触控笔按压灵敏度、笔方向、擦除笔尖和其他触控笔按钮;左侧窗格是 Microsoft OneNote 应用,使用模拟器可以在 OneNote 画布上绘制、做笔记或擦除。 我们非常兴奋,在支持触控的 PC 上,Android 模拟器现在也可以支持多点触控,这让您可以测试需要使用多个手指的手势与应用进行交互,比如双指张合、缩放和其他触摸交互。 △ 在 Google 地图中使用手势操作 这款内置 Android Studio 的可折叠模拟器正在运行 Google 地图,只需使用两个手指就可以放大和缩小地图。而且这些模拟器更新的不仅是只支持使用两个手指,如果您的硬件允许,可以支持多达 10 个触摸点。 您看到的所有这些变化都不是 Surface Duo 模拟器所特有的,它们也适用于其他可折叠模拟器。Microsoft 也一直在利用这些模拟器更新来开发和优化自己的应用,例如在包括 Surface Duo、大屏幕和其他可折叠设备等多种设备类型上测试触控笔的交互。 手柄输入支持 如果您有一款游戏应用则需要添加游戏手柄支持。使用相应的键代码,确定要对 onKeyUp 还是 onKeyDown 执行操作。 △ 游戏手柄 游戏手柄方向键与键盘箭头键的键代码是相同的,只需监听 KEYCODE_DPAD 事件即可同时处理这两者。游戏手柄按钮也有自己的键代码,您可以监听这些按钮就像这里为 X 按钮进行的设置一样。完整代码如下所示: when (keyCode) { BUTTON_X -> { engageNitro(); return true } DPAD_UP, KEYCODE_W -> { goForward(); return true } DPAD_LEFT, KEYCODE_A -> { turnLeft(); return true } ... } MIDI 输入支持 当涉及到专门的硬件时,需要针对设备和用例提供支持。MIDI 支持对于音乐和创意工具来说尤其重要,它允许广泛的、富有表现力的输入信号,从对压力敏感的钢琴键盘到具有滑块、旋钮、键盘等许多不同输入触发器的设备,都能提供支持。 如果您希望使用或了解更多 MIDI 相关的信息,Android Media Samples 库中提供了一些便捷的开源示例,可以帮助您开始使用 MIDI。请查看 MidiSynth 项目,特别是该项目中的 Synth Engine 模块。注意,从 Android 29 开始您还可以使用 NDK MIDI API。 回顾 大屏幕的 Android 设备已经出现而且愈发普及,在 Android 上提供出色的输入支持一直很重要,而对于可折叠设备、平板电脑和 Chrome 操作系统来说尤为重要。请思考您应用的输入处理以及如何增加互动、解锁新功能并提升应用体验。期待各位开发者投入精力构建精彩的 Android 应用,并为其添加了出色的输入处理! 欢迎您 点击这里 向我们提交反馈,或分享您喜欢的内容、发现的问题。您的反馈对我们非常重要,感谢您的支持!

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

ios7适配--navgationbar遮住下面view的处理

3 down vote favorite Have you guys stumbled up on this issue ? Basically in iOS 7 Navigation Controller is rendered over the sub-view I navigated to. In iOS 6 view I navigate to is enclosed between navigation bar and footer. In iOS 7 it looks like sub-view is rendered full-screen, under navigation bar and footer. As result user don't see it. Here is how I navigate to subview BRSMyListSubViewController*tagsInfoVC =[[BRSMyListSubViewController alloc] initWithCheckinsList:self.checkinsList selectedTag:[self tagByIndexPath:indexPath]];[self.navigationController pushViewController:tagsInfoVC animated:YES]; Here is how I initialize it inviewDidLoad self.navigationItem.leftBarButtonItem =[[UIBarButtonItem alloc] initWithTitle:@"Settings" style:UIBarButtonItemStyleBordered target:self action:@selector(settings:)]; self.navigationItem.rightBarButtonItem =[[UIBarButtonItem alloc] initWithTitle:@"Logout" style:UIBarButtonItemStyleBordered target:self action:@selector(logout:)]; For what it's worth I should also mention that sub-view is defined in XIB using Autolayout. Here is source of my XIB:http://pastebin.com/6RR0zYu4 And finally here is how it looks in iOS 6 And in iOS 7 Any thoughts ? ios cocoa-touch ios6 uinavigationcontroller ios7 share | edit | flag editedAug 29 at 18:47 asked Aug 29 at 4:09 ruslan 3,422 1 15 55 add comment 1 Answer active oldest votes up vote 5 down vote accepted Well, I figured it out. In your sub-view (BRSMyListSubViewControllerin my case), inviewDidLoad, you need to set one of these two self.edgesForExtendedLayout =UIRectEdgeNone; self.automaticallyAdjustsScrollViewInsets = NO; OR self.edgesForExtendedLayout =UIRectEdgeNone; self.extendedLayoutIncludesOpaqueBars = YES; Interestingly enough in root view controller these value are set to defaultUIRectEdgeAll,NOandYESrespectively but itstableViewis NOT under navbar and footer. I don't know why it's so illogical. It's also strange thatedgesForExtendedLayouthas to be mixed with one of two other properties even though it's clearly responsible for the behavior. share | edit | flag editedAug 29 at 6:11 answered Aug 29 at 5:29 ruslan 3,422 1 15 55 upvote flag Thank you for putting the answer, it really helped me.–titicacaSep 12 at 6:11 欢迎加群互相学习,共同进步。QQ群:iOS: 58099570 | Android: 572064792 | Nodejs:329118122 做人要厚道,转载请注明出处! 本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sunshine-anycall/p/3338688.html ,如需转载请自行联系原作者

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

【移动开发】Android中强大的适配功能----Fragment(碎片)总结

作为大多数刚接触Android应用开发的人来说,在一个强大的Activity类中,就可以完成丰富多彩的UI工作,但是杂乱的屏幕分辨率,使得本来好不容易写好的UI,变得不堪入目。。。该怎么办那? 查阅了好多资料,才发现,原来我out了!早在Android在3.0版本就引入了Fragment(碎片)功能,它非常类似于Activity,可以像Activity一样包含布局,通过将Activity 的布局分散到frament 中,可以在运行时修改activity 的外观,并且由activity 管理的back stack 中保存些变化,很巧妙的解决了不同分辨率手机上UI差异变化的问题。总结一下吧! 一.Fragment介绍: 官方文档:http://developer.android.com/guide/components/fragments.html Fragment是我们在单个Activity上要切换多个UI界面时,要显示的不同内容。模块化这些UI面板可以提供给其他Acitivity来使用,因此我们可以简单地把Fragment看成类似于TextView控件一样,可以被任意的Activity进行加载。 1.静态加载: 首先,在Layout下建立两个xml fragment1.xml: 1 2 3 4 5 6 7 8 9 10 11 12 13 <? xml version = "1.0" encoding = "utf-8" ?> < LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "vertical" android:background = "#000000" > < TextView android:id = "@+id/textView1" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "我是Fragment1" /> </ LinearLayout > fragment2.xml: 1 2 3 4 5 6 7 8 9 10 11 12 <? xml version = "1.0" encoding = "utf-8" ?> < LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "vertical" android:background = "#0000ff" > < TextView android:id = "@+id/textView1" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "我是Fragment2" /> </ LinearLayout > 之后建立两个类: FragmentFirst类: 1 2 3 4 5 6 7 8 9 10 11 12 13 package com.zhf.android_fragmentdemo; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class FragmentFirst extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment1, container, false ); } } FragmentSecond类: 1 2 3 4 5 6 7 8 9 10 11 12 13 package com.zhf.android_fragmentdemo; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class FragmentSecond extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment2, container, false ); } } 最后一步就是在activity_main.xml中应用这两个布局文件: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android" android:layout_width= "match_parent" android:layout_height= "match_parent" android:orientation= "horizontal" > <fragment android:id= "@+id/fragment1" android:name= "com.zhf.android_fragmentdemo.FragmentSecond" android:layout_width= "0dip" android:layout_height= "match_parent" android:layout_weight= "1" /> <fragment android:id= "@+id/fragment2" android:name= "com.zhf.android_fragmentdemo.FragmentFirst" android:layout_width= "0dip" android:layout_height= "match_parent" android:layout_weight= "1" /> </LinearLayout> 主类MainActivity中不用添加其他代码,直接加载activity_main.xml即可。 效果图: ok!简单三步就将fragment加载进去了,当然这只是fragment的一小部分功能,它的强大之处其实在于:Activity能够根据自身情况来动态的加载fragemnt,使你的UI界面变得更加多样可变! 2.动态加载:(重点) 首先,现将activity_main.xml中多余部分去掉: 1 2 3 4 5 6 < LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:id = "@+id/main_layout" android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "horizontal" > </ LinearLayout > 其次,就是在MainActivity类中动态添加这两个Fragment类: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package com.zhf.android_fragmentdemo; import android.app.Activity; import android.os.Bundle; import android.view.Display; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main2); Display display = getWindowManager().getDefaultDisplay(); if (display.getWidth() > display.getHeight()) { FragmentFirst fragmentFirst = new FragmentFirst(); getFragmentManager().beginTransaction() .replace(R.id.main_layout, fragmentFirst).commit(); } else { FragmentSecond fragmentSecond = new FragmentSecond(); getFragmentManager().beginTransaction() .replace(R.id.main_layout, fragmentSecond).commit(); } } } 运行一下,效果出来了,为了体现出动态,大家可以试着把手机自动转屏打开,转一下屏试试! ----转屏之后---> 注:动态加载过程步骤 1.获取到FragmentManager,在Activity中可以直接通过getFragmentManager得到。 2.调用beginTransaction方法开启一个事务。 3.向容器内加入Fragment,一般使用replace方法实现,需要传入容器的id和Fragment的实例。 4.提交事务,调用commit方法提交。 介绍完这两种方式,大家是不是已经对其有了一些感性的认识,这里注意一下Fragment是在3.0版本引入的,如果你使用的是3.0之前的系统,需要先导入android-support-v4的jar包才能使用Fragment功能,这里可能需要继承FragmengActivity(现在建立低版本项目时,ADT会自动将libs下的android-support-v4.jar构建到项目路径) 接下来我们具体挖掘一下生命周期及其Fragment中一些主要方法的介绍! 二.Fragment类的生命周期 复写fragment中的方法,测试一下它的生命周期看看它与Activity的异同。 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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 package com.zhf.android_fragmentdemo; import android.app.Activity; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; /** * Fragment的生命周期 * 注意: 方法中的排列次序即为fragment全过程:启动时方法调用次序 + 退出时方法调用次序 * @author ZHF * */ public class FragmentFirst extends Fragment { /**Fragment和Activity建立关联的时候调用**/ @Override public void onAttach(Activity activity) { super .onAttach(activity); System.out.println( "onAttach" ); } @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); System.out.println( "onCreate" ); } /**为Fragment加载布局时调用**/ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { System.out.println( "onCreateView" ); return inflater.inflate(R.layout.fragment1, container, false ); } /**当Activity中的onCreate方法执行完后调用**/ @Override public void onActivityCreated(Bundle savedInstanceState) { super .onActivityCreated(savedInstanceState); System.out.println( "onActivityCreated" ); } @Override public void onStart() { super .onStart(); System.out.println( "onStart" ); } @Override public void onResume() { super .onResume(); System.out.println( "onResume" ); } @Override public void onPause() { super .onPause(); System.out.println( "onPause" ); } @Override public void onStop() { super .onStop(); System.out.println( "onStop" ); } /**Fragment中的布局被移除时调用**/ @Override public void onDestroyView() { super .onDestroyView(); System.out.println( "onDestroyView" ); } @Override public void onDestroy() { super .onDestroy(); System.out.println( "onDestroy" ); } /**Fragment和Activity解除关联的时候调用**/ @Override public void onDetach() { super .onDetach(); System.out.println( "onDetach" ); } } 打印结果: 1.运行一下: 2.返回退出: 3.Home键退出: 4.再次进入: 通过打印的结果,我们应该可以清楚的了解到其实fragment和Activity的生命周期还是很相似的 (Activity生命周期博客:http://smallwoniu.blog.51cto.com/blog/3911954/1246732) 官网截图: 三.Fragment中有几个重要的回调方法 方法 描述 onAttach() Fragment和Activity建立关联的时候调用 onCreateView() 为Fragment加载布局时调用 onActivityCreated() 当Activity中的onCreate方法执行完后调用 onDestroyView() Fragment中的布局被移除时调用 onDetach() Fragment和Activity解除关联的时候调用 只有掌握了Fragment中这几个重要的方法,在使用的过程中才能更加灵活的与Activity配套使用,动态加载以适应不同屏幕分辨率的状况! ok! 因为本人也是刚接触Fragment时间不长,这里也是查阅了许多的资料,简单总结了一番,方便以后查阅,希望能帮助到刚接触fragment的人。 在下一篇博客中我会使用Fragment+ViewPager写一个动态加载数据库的综合的案例,欢迎大家查阅! 附件:http://down.51cto.com/data/2363603 本文转自zhf651555765 51CTO博客,原文链接:http://blog.51cto.com/smallwoniu/1308365,如需转载请自行联系原作者

资源下载

更多资源
腾讯云软件源

腾讯云软件源

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

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

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

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册