Android 官网Train阅读记录——2
来源:互联网 发布:汇编语言编程事例讲解 编辑:程序博客网 时间:2024/05/21 06:33
LZ阅读的是中文翻译版本:http://hukai.me/android-training-course-in-chinese/basics/activity-lifecycle/recreating.html,试验机系统版本7.1。
1.5 使用Fragment建立动态的UI
1.5.1 创建Fragment
创建Fragment要继承自Fragment,一般,为了兼容低版本,要继承v4包中的Fragment。
有两种方式向Activity的视图中添加Fragment:
1、直接在Activity的布局xml文件中通过标签(fragment)的方式,通过android:name属性指明引用的是哪个Fragment,其值是要引用的Fragment的全类名。
2、在Activity的代码中通过FragmentManager添加。
1.5.2 建立灵活动态的UI
在小屏幕的设备上,如手机,通常需要替换Fragment来达到较好的user experience,而大屏幕,如平板,或者是横屏的设备上,则可以一次横放两个,甚至更能多的Fragment。
所以,如果一个App要适配不同尺寸的设备,就要通过 Android 官网Train阅读记录——1提到的各种适配方法来适配了。
如果一个新闻app想同时运行在手机和平板上,并保持很好的用户体验,达到在手机上单屏单窗,在平板上单屏双窗的效果,就需要为同一个Activity建立两个xml布局文件,例如:
其中在手机上的布局文件名为res/layout/news.xml,而在平板上的布局文件名为res/layout-large/news.xml。
在前一个布局文件中可以只有一个FrameLayout作为动态替换Fragment的容器,而在后面的文件中,可以固定的添加两个<Fragment>标签。
在Activity的代码中可以动态的通过查询FrameLayout容器是否存在,判断该设备是小屏幕还是大屏幕,这样在不同的布局中做不同的操作,就可以达到在手机上单屏单窗,在平板上单屏双窗的效果。
如果要让Fragment想Activity一样存入backstack,必须手动调用addToBackStack方法,此方法由FragmentTransaction所有,并且需要在FragmentTransaction调用commit之前调用才行。
1.5.3 Fragments之间以及Fragment和Activity之间的交互
Fragments之间不提倡直接进行交互,这样耦合性严重,可复用性差。所以,Fragments之间的交互通常通过Fragment与Activity之间的交互来完成。
Fragment和Activity之间的交互:
Activity可以通过Fragment的setArguments方法向Fragment传递消息。
Fragment可以通过自定义回调接口,让包含它的Activity实现,来完成向Activity传递消息。Fragment通过onAttach方法或者getActivity方法获取Activity的引用然后转换成相应的接口对象,这样在Fragment中调用接口的方法,通过向该方法传递参数,以达到向Activity传递消息的目的。
Fragment可以向ActionBar中添加Menu Item,实现方式为:复写onCreateOptionsMenu方法,并在onCreate方法中调用setHasOptionsMenu(true),来达到目的,然后通过复写onOptionsItemSelected方法监听按钮的点击事件。
1.6 数据保存
1.6.2 保存到文件
数据可以保存到internal storage或者external storage,保存到external storage需要WRITE_EXTERNAL_STORAGE权限。
保存到internal可以
File file = new File(context.getFilesDir(), filename);或者
String filename = "myfile";String string = "Hello world!";FileOutputStream outputStream;try { outputStream = openFileOutput(filename, Context.MODE_PRIVATE); outputStream.write(string.getBytes()); outputStream.close();} catch (Exception e) { e.printStackTrace();}保存到internal的文件在app卸载的时候,会被系统随之移除。
保存到external之前需要验证external storage是否可用
/* Checks if external storage is available for read and write */public boolean isExternalStorageWritable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { return true; } return false;}/* Checks if external storage is available to at least read */public boolean isExternalStorageReadable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { return true; } return false;}
保存到external分两种:
不想让文件随app卸载而被系统移除可以
File file = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), albumName);
其中DIRECTORY_PICTURES表示该目录存放的是照片,其他还有音乐,铃声等等类型,具体可以自行查阅。
要让文件随app卸载而被系统移除可以
File file = new File(context.getExternalFilesDir( Environment.DIRECTORY_PICTURES), albumName);
若文件是保存在internal storage的,可以用下面的方式删除文件
myContext.deleteFile(fileName);
1.6.3 保存到数据库
通过实现BaseColumns接口,创建包含表名和列名的类,其他的关于表的创建、增删改查操作使用该类即可
public final class FeedReaderContract { // To prevent someone from accidentally instantiating the contract class, // give it an empty constructor. public FeedReaderContract() {} /* Inner class that defines the table contents */ public static abstract class FeedEntry implements BaseColumns { public static final String TABLE_NAME = "entry"; public static final String COLUMN_NAME_ENTRY_ID = "entryid"; public static final String COLUMN_NAME_TITLE = "title"; public static final String COLUMN_NAME_SUBTITLE = "subtitle"; ... }}
1.7 与其他应用的交互
1.7.1 Intent的发送
拨号
Uri number = Uri.parse("tel:5551234");Intent callIntent = new Intent(Intent.ACTION_DIAL, number);看网页
Uri webpage = Uri.parse("http://www.android.com");Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);创建日历事件
Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30);Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30);calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());calendarIntent.putExtra(Events.TITLE, "Ninja class");calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");
PackageManager packageManager = getPackageManager();List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);boolean isIntentSafe = activities.size() > 0;如果接受Intent的app不止一个,强制用户选择
Intent intent = new Intent(Intent.ACTION_SEND);...// Always use string resources for UI text. This says something like "Share this photo with"String title = getResources().getText(R.string.chooser_title);// Create and start the chooserIntent chooser = Intent.createChooser(intent, title);startActivity(chooser);
1.7.3 Intent过滤
如果要让其他app能够调用我们自己写的app,我们需要为被调用的Activity添加Intent-filter。若Activity中的intent-filter满足以下Intent对象的标注,系统就能够把特定的Intent发送给Activity:
Action:一个想要执行的动作的名称。通常是系统已经定义好的值,如ACTION_SEND或ACTION_VIEW。在Intent-filter中通过<action>标签指定它的值,值的类型必须为字符串。
Data:Intent附带数据的描述。在Intent-filter中通过<data>指定它的值,可以使用一个或者多个属性,我们可以只定义MIME type或者是只指定URI prefix,也可以只定义一个URI scheme,或者是它们综合使用。
Category:提供一个附加的方法来标识这个Activity能够handle的Intent。通常与用户的手势或者是启动位置有关。系统有支持几种不同的Category,但是大多数都很少用到。而且,所有的implicit intents都默认是CATEGORY_DEFAULT类型的。在Intent-filter中用<category>指定它的值。
例子
<activity android:name="ShareActivity"> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain"/> <data android:mimeType="image/*"/> </intent-filter></activity>一个Intent-filter可以有多个action、category或者data。一个Activity可以有多个Intent-filter。
在Activity中Handle发送过来的Intent
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Get the intent that started this activity Intent intent = getIntent(); Uri data = intent.getData(); // Figure out what to do based on the intent type if (intent.getType().indexOf("image/") != -1) { // Handle intents with image data ... } else if (intent.getType().equals("text/plain")) { // Handle intents with text ... }}返回Result
// Create intent to deliver some kind of result dataIntent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri");setResult(Activity.RESULT_OK, result);finish();
- Android 官网Train阅读记录——2
- Android 官网Train阅读记录——1
- Android 官网Train阅读记录——3
- Android 官网Train阅读记录——4
- Android 官网Train阅读记录——5
- Android 官网Train阅读记录——6
- Android 官网Train阅读记录——7
- Android——api阅读记录
- Android官方文档阅读记录
- Android api阅读记录02
- Android API阅读记录03
- 阅读干货—HTTP记录与内容摘要
- x264阅读记录-2
- Uva299——Train Swapping
- ML—决策树(train,matlab)
- Android学习记录—《第一行代码》阅读笔记(4)
- Android学习记录-《第一行代码》阅读笔记(2)
- android 文档阅读记录-添加fragment
- java构造器
- .pch文件不能智能索引
- 剑指Offer 1.二维数组中的查找
- 一步一步教你将开源项目上传到jcenter
- 查看tomcat项目的下的真实的名字
- Android 官网Train阅读记录——2
- 一个简单的servlet-cookie和session
- PHP SOCKET编程
- NGUI源码分析(六) UIProgressBar和UISlider
- RxJava2.0的生动形象的分析
- JavaScript学习笔记5 面向对象之理解对象
- cocos2dx游戏开发学习笔记(四)之Hello World
- 交叉编译找不到creat_pthread
- 清除Ubuntu的DNS缓存