学习内容
- Google Android Training
http://developer.android.com/training/index.html - Github托管
https://github.com/kesenhoo/android-training-course-in-chinese - 中文阅读地址
http://hukai.me/android-training-course-in-chinese/index.html
以下是仅对我个人有意义的笔记
1. Android入门基础:从这里开始
1.1.建立第一个App
1.1.1. 创建Android项目
- 下载安装Android Studio和SDK Manager
- 下载和安装地址(有空补上)
1.1.2. 执行Android程序
从命令行安装运行应用程序(MacOS)
$ chmod +x gradlew $ ./gradlew assembleDebug
- 了解 Managing AVDs with AVD Manager
http://developer.android.com/tools/devices/managing-avds.html 命令行运行apk
adb install app/build/outputs/MyFirstApp-debug.apk
1.1.3. 建立简单的用户界面
- 介绍button和edittext一些基础的控件
Button用法
xml设置
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_send" android:onClick="sendMessage" />
java设置
/** Called when the user clicks the Send button */ public void sendMessage(View view) { // Do something in response to button }
1.1.4. 启动其他的Activity
- Intent的基础使用 跳转+传值
- Toolbar
1.2. 添加ActionBar(这边可以用ToolBar代替,目前使用较多的是ToolBar了)
1.2.1. 建立ActionBar
- 这里要注意就是使用ActionBar需要使用同一个主题,如果是自定义的,必须要继承同一个主题theme.holo
1.2.2. 添加Action按钮
- 先建立自定义的ActionBar的xml文件,在里面设置样式和文字和id,在activity里面实现 onCreateOptionsMenu()方法,用于绑定xml,实现onOptionsItemSelected()设置各个id的处理事件
啊,原来是有系统处理好的返回系统的(up button),具体实现如下(由于系统已经知道 MainActivity 是 DisplayMessageActivity 的父 activity,当用户按下向上按钮时,系统会导航到恰当的父 activity - 你不需要去处理向上按钮的事件。)
在manifest里面给activity设定一个父类属性(MainActivity就是主界面)
android:parentActivityName="com.example.myfirstapp.MainActivity" >
在Activity里面写
getActionBar().setDisplayHomeAsUpEnabled(true);
1.2.3. 自定义ActionBar的风格
- 这些主题即可以被应用到 app 全局,也可以通过在 manifest 文件中设置 元素 或 元素的 android:theme 属性,对单一的 activity 进行设置。(也就是说,可以混着用,达到上下不一致的效果)
- 在value文件夹下设置一个themes.xml文件,里面设置style属性,然后在manifest里面设置application的属性
- 如果加tab的话,就在drawable下设置一个actionbar_tab_indicator.xml载里面设置tab按钮的样式和个数。然后布置到themes.xml里面,最后在manifest.xml引用themes
1.2.4. ActionBar的覆盖层叠
hide()和show()过程需要调整布局大小(不好,导致界面卡顿或者性能降低),所以叠加模式(overlay mode)比较好(就是点一下显示,点一下隐藏的那种半透明bar)。
<item name="android:windowActionBarOverlay">true</item> <!-- 兼容支持库 --> <item name="android:windowActionBarOverlay">true</item>
指定布局的顶部边距(actionBarSize这个是可以自定义的吗?还是就是ActionBar的高度?)
android:paddingTop="?attr/actionBarSize">
1.3. 兼容不同的设备
1.3.1. 适配不同的语言
res/
values/
strings.xml
values-es/
strings.xml
values-fr/
strings.xml
1.3.2. 适配不同的屏幕(这里只讲到xhdpi,现在已经到了xxxhdpi了)
写两个不同尺寸的layout(和适配语言其实差不多道理,但是要是里面的控件不一样怎么办?)
res/ layout/ main.xml layout-large/ main.xml
1.3.3. 适配不同的系统版本(不是很懂啊)
- 运行时检查版本(这个感觉有点高级的样纸)
1.4. 管理Activity的生命周期
- 完整的生命周期展示 http://developer.android.com/shareables/training/ActivityLifecycle.zip
- Create(出生)start(可以活动)resumed(正在活动的)paused(暂停)stop(停下来)destroyed(销毁了,不存在了)
1.4.1. 启动与销毁Activity
- 除非程序在onCreate()方法里面就调用了finish()方法,系统通常是在执行了onPause()与onStop() 之后再调用onDestroy() 。在某些情况下,例如我们的activity只是做了一个临时的逻辑跳转的功能,它只是用来决定跳转到哪一个activity,这样的话,需要在onCreate里面调用finish方法,这样系统会直接调用onDestory,跳过生命周期中的其他方法。
1.4.2. 暂停与恢复Activity
1.4.3. 停止与重启Activity
1.4.4. 重新创建Activity
- 转屏会重建activity,显示的数据能一样是因为instance state保存了当前界面的数据onSaveInstanceState
- 一般会出现这种情况的场景:(通常来说,跳转到其他的activity或者是点击Home都会导致当前的activity执行onSaveInstanceState,因为这种情况下的activity都是有可能会被destory并且是需要保存状态以便后续恢复使用的,而从跳转的activity点击back回到前一个activity,那么跳转前的activity是执行退栈的操作,所以这种情况下是不会执行onSaveInstanceState的,因为这个activity不可能存在需要重建的操作)
1.5. 使用Fragment建立动态的UI
1.5.1. 创建一个Fragment
1.5.2. 建立灵活动态的UI
- 就是在做移除或者替换操作的时候,先在FragmentTransaction加上一个放入栈内的标志,然后在commit,方便用户返回之前的操作)
1.5.3. Fragments之间的交互(所有 Fragment 之间的交互应通过与之关联的 Activity 来完成。两个 Fragment 之间不应直接交互。)
- 用接口传递message
- Fragment定义接口:interface xxx 里面有yyy方法,当符合操作的时候调用这个接口的方法把数据传出去
- Activity实现接口:implement Fragment的接口,然后写实现,在这个方法里面做什么操作
- 传递给新的Fragment(在创建的时候用bundle或者直接在new的时候,放入这个参数)
1.6. 数据保存
1.6.1. 保存到Preference
- 多个(需要指定名字)和一个(默认为该app下的那个文件)Preferences
- MODE_PRIVATE、MODE_WORLD_READABLE、MODE_WORLD_WRITEABLE区分是否可以被其他app读取信息。
写:
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE); SharedPreferences.Editor editor = sharedPref.edit(); editor.putInt(getString(R.string.saved_high_score), newHighScore); editor.commit();
读:
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE); int defaultValue = getResources().getInteger(R.string.saved_high_score_default); long highScore = sharedPref.getInt(getString(R.string.saved_high_score), default);
1.6.2. 保存到文件(我感觉这个好像用到的比较少)
- Internal storage+ External storage :现在基本都是内置不可拆卸的了,所以大概也就没有这个区分了(需要确认一下是不是真的没有这个区分了,我毛估估是没有了)。
- 保存到internal storage
- getFilesDir() : 返回一个File,代表了我们app的internal目录。用File()+openFileOutput() + FileOutputStream操作
- getCacheDir() : 缓存,内存不够的时候里面的会被删掉。用getCacheDir()+ createTempFile()操作
- 保存到External Storage:先要用 getExternalStorageState()查询一下是否可用,如果MEDIA_MOUNTED则可用。
- Public files :卸载时候保留。用getExternalStoragePublicDirectory()获取文件夹名,这个方法会需要带有一个特定的参数来指定这些public的文件类型,以便于与其他public文件进行分类。参数类型包括DIRECTORY_MUSIC 或者 DIRECTORY_PICTURES.
- Private files: 卸载时不保留。getExternalFilesDir()来获取相应的目录,并且传递一个指示文件类型的参数。
- 查询是否有剩余空间 getFreeSpace() or getTotalSpace()
- 删除
1.6.3. 保存到数据库
- 这里的增删改查,我建议还是使用具体库的时候看一下教程,一般不会使用原生的这种
1.7. 与其他应用的交互
1.7.1. Intent的发送
- 这一部分展示了,在app内如何调用系统级别的API
1.7.2. 接收Activity返回的结果
- startActivityFotResult()
- 读取联系人数据
1.7.3. Intent过滤()
- Intent Filter,设置category、action、data
2.如果任何的两对action与data是互相矛盾的,就应该创建不同的intent filter来指定特定的action与type。