《Android编程权威指南》-读书笔记(十一) 完善CriminalIntent

《Android编程权威指南》-读书笔记(十一) 完善CriminalIntent

在上篇文章中,我们跟随本书作者,使用了单个的Fragment做了最简单的插入操作。本篇文章将跟随作者进行更深入的完善各种功能。

本章目标:

  • 使用ListFragment显示列表
  • fragment之间传递数据
  • 使用ViewPager来实现划屏显示
  • 对话框

使用ListFragment显示列表

如果是挑战,或者没有UI我会给出草图之类的UI。或手画或Axure原型。每次例子本书都给出了最终UI,所以这步基本都可以省了。本章在例子CriminalIntent中使用ListFragment。以达到如下的效果:

资源相关

在这个UI中所有的数据都是根据动态数据显示的,因为没有用到任何图片资源或者字符串资源。所以没有修改的地方。(目前的资源默认的为按钮文字,界面上出现的文字等)

数据相关

现在需要显示一串数据,书中新增了一个可以容纳多个Crime对象ArrayList类。它定义了2个私有变量

private static CrimeLab sCrimeLab;

private Context mAppContext;

s开头的变量是开发的命名约定。它代表了变量sCrimeLab是一个静态变量。

这个类的代码现阶段如下:

http://git.oschina.net/canglin/CriminalIntent/commit/2f5580a992c804949a14a921dae7535a6097532f

这个类里面定义了个一个get方法用来传入一个Context。而在18行sCrimeLab直接调用了构造函数,构造函数的参数却是getApplicationContext(),这是因为Context可能是一个Activity,也可能是一另一个Context对象,如Service。在应用的整个生命周期里,无法保证只要CrimeLab需要用到Context,Context就一定会存在。所以才使用getApplicationContext()。至于12行public 的构造函数我写错了,我将会在下个版本的Git镜像中做修正。

将一些Crime对象保存到CrimeLab中去。增加一个Crime的ArrayList列表,并添加Getter()方法。

然后在增加一个查询操作在CrimeLab中为getCrime(UUID id)。我更倾向于使用getCrimeById()这种命名法。

完成后的CrimeLab最干净版不包含模拟数据代码如下:

http://git.oschina.net/canglin/CriminalIntent/commit/e4a9e6fac36f7eca76e063b406e194338f3fa778

逻辑相关

下图是CriminalIntent应用的整体规划设计

这个应用是在容器视图中显示列表。我们要创建一个ListFragment和一个Activity,还有与ListFragment相匹配的layout。

Fragment

创建CrimeListFragment类扩展自ListFragment。HoneyComb系统版本引入了ListFragment类,相应的,支持库也引入了该类。

import android.support.v4.app.ListFragment;

ListFragment是通过ListView将列表项展示给用户。而ListView通过adapter来申请视图对象。

Adapter负责:

创建必要的视图对象;

用模型层数据填充视图对象;

将准备好的视图对象返回给ListView。

随意例子中采用了setListAdapter(ListAdapter)来为CrimeListFragment管理内置ListView设置adapter。(详情参看后面的代码链接,现在就可以打开它对比观看)

FragmentActivity

由于每一个ActivityFragment都有相似的代码,于是作者创建了一个SingleFragmentActivity抽象类用来减少以后的代码输入。在书中的例子都是在一个FragmentContainer动态添加一个Fragment,所以唯一不同的代码就是在事物添加Fragment之前动态创建的代码。

修改CrimeActivity扩展自SingleFragmentActivity。

创建CrimeListActivity扩展自SingleFramentActivity。

因为这2个类唯一的区别

都只是在23行而已。采用抽象的方法后,每个扩展自SingleFragmentActivity的类都必须@Override掉createFragment()。

视图相关

需要在res/layout/list_item_crime.xml中的如下:

代码如下:

http://git.oschina.net/canglin/CriminalIntent/commit/05a1da49e017dbdcef2d795d6da07eca41a3a006

在本章中只关注下面的类和layout资源文件。其他的删除掉都可以,不会影响应用的正常运行。

对象

Crime                列表子元素的对象

CrimeLab                可以创建和获取一个Crime 列表。

Activity

CrimeListActivity            扩展自SingleFragmentActivity 创建CrimeListFragment 事物

SingleFragmentActivity

Fragment

CrimeListFragment            根据list_item_crime.xml 生成相应的View

Res/layout

Activity_fragment.xml        定义了容易视图

List_item_crime.xml        定义了列表子元素的视图

由于默认的Activity 不是CrimeListActivity

<activity android:name=".CrimeListActivity">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

这样设置后默认的将会是CrimeListActivity。

在例子初期做的很随意,为后面几个目标做准备,我将源代码做了一些调整,调整后代码如下:

http://git.oschina.net/canglin/CriminalIntent/commit/05a1da49e017dbdcef2d795d6da07eca41a3a006

使用fragment argment

我们学习过在Activity中是调用startActivity(Intent)来启动另外一个activity。现在在Fragment中还是调用startActivity(Intent)来启动Activity。

在点击ListFragment将会显示详细的信息。详细信息界面应该是在第8章中完成。

界面设置好后,资源文件的字符串最初是这个样子。因为增加了几个字符串,但是还没有在strings.xml中添加,效果如下图所示:

资源文件填写完成后

代码如下:

http://git.oschina.net/canglin/CriminalIntent/commit/918aed3dd490b12f39f00701e4806cada3ad0b63

到现在为止界面界面基本成型,里面所有的事件,以及数据处理,还有业务逻辑我都把它精简到了最低的程度。中间很多地方在本书中是要求加入一些非UI代码的,我都没有加入。至于列表的数据那一块,也只是为了让界面逻辑能够完整。

给CrimeFragment填充数据

使用之前学到的方法用Intent传递数据,在CrimeFragment的onCreate()中从Intent读取数据。

首先定义一个id

public static final String EXTRA_CRIME_ID =

"com.example.lijing.criminalintent.crime_id";

…..

然后在onCreate()中

UUID crimeId = (UUID)getActivity().getIntent().getSerializableExtra(EXTRA_CRIME_ID);

mCrime = CrimeLab.get(getActivity()).getCrime(crimeId);

数据在CrimeListFragment中startActivity()之

putExtra(CrimeFragment.EXTRA_CRIME_ID,c.getId());

完成后界面是这个样子:

代码发生如下变动:

http://git.oschina.net/canglin/CriminalIntent/commit/657c3d4164e08968dca123c3babec0ee80f97327

界面之间传递数据的改进

原先的代码如下

UUID crimeId = (UUID)getActivity().getIntent().getSerializableExtra(EXTRA_CRIME_ID);

在这段代码中crimeId是存储在CrimeActivity中的。现在将它由CrimeActivity的intent内的extra改为arguments bundle。每个fragment实例都可以附带一个Bundle对象。该bundle包含有key-value对,我们可以如同附加extra到Activity的intent中那样使用它们。一个key-value对即一个argument。

UUID crimeId = (UUID)getArguments().getSerializable(EXTRA_CRIME_ID);

并给fragment一个newInstance()来创建自己,并在这个静态方法里创建arguments。

总的来说就是由以前从Activity中获取参数,改成从自己的存储区里获取参数。而自己的存储区里的参数是在创建该fragment是写入的。

这是代码的改动:

http://git.oschina.net/canglin/CriminalIntent/commit/95d7da1d76c2ac316cdb1f1af823df3cb745e133

使用ViewPager来实现划屏显示

为了实现这个效果,我们需要创建一个ViewPager的activity,命名为CrimePagerActivity来取代CrimeActivity。本章采用了以代码的方式创建视图它包含以下步骤:

  • 为ViewPager创建资源ID;
  • 创建ViewPager实例并赋值给mViewPager;
  • 赋值资源ID给ViewPager,并对其进行配置;
  • 设置ViewPager为activity的内容视图。

创建独立资源ID(res/values/ids.xml)

定义独立资源ID与定义字符串资源ID并没有什么不同:在res/values目录下的XML文件中创建一个项目元素。创建一个名为res/values/ids.xml的Android XML 资源文件。

以代码的方式创建内容视图(CrimePagerActivity.java)

mViewPager = new ViewPager(this);

mViewPager.setId(R.id.viewPager);

setContentView(mViewPager);

然后我们使用FragmentStatePagerAdaper为我们的代理,负责管理与ViewPager的对话并协同工作。

代码如下:

http://git.oschina.net/canglin/CriminalIntent/commits/master

到这里在详细信息界面就实现了拖动。

现在程序有一个Bug就是,当我点击一个详细信息的时候,详细信息界面中显示的永远是第一条。现在我们通过设置setCurrnetItem(index)是当前详细页面的信息是选中的选项。

有关ViewPager.OnPageChangeListener

在本书的例子中,当页面发生改变的时候将标题设置给CrimePagerActivity。在我的代码中我貌似将显示标题的位置拿掉了。

https://developer.android.com/reference/android/support/v4/view/ViewPager.OnPageChangeListener.html#onPageScrollStateChanged(int)

这个是官方的api地址

这个方法必须重写3个抽象的方法,如果现在不知道写什么可以将3个方法复制进去就可以了。

mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

public void onPageScrollStateChanged(int state) {}

public void onPageScrolled (int position, float positionOffset, int positionOffsetPixels) {}

public void onPageSelected (int position) {

Crime crime = mCrimes.get(position);

if (crime.getTitle() != null) {

setTitle(crime.getTitle());

}

}

});

就像这个样子,但是这段代码在现在的程序里,是不会有界面改变的。所以在这里特别强调一下。

完成后代码如下:

http://git.oschina.net/canglin/CriminalIntent/commits/master

对话框

在我们CrimeFragment对应的详细信息界面里有一个时间设置按钮。现在我们就按照书中的要求完善这个按钮的对话框。

作者采用将AlertDialog封装在DialogFragment的方法来显示对话框,因为有如下优点:

  • 使用FragmentManager管理对话框,可以使用更多配置选项来显示对话框;
  • 发生旋转时封装在fragment中的AlertDialog不会消失

在屏幕上显示DialogFragment时,托管activity的FragmentManager会调用onCreateDialog()。在onCreateDialog里我们需要返回一个AlertDialog.Builder。

在显示对话框的时候要注意。要将DialogFragment添加给FragmentManager管理并放置到屏幕上,可以调用fragment的show方法。

Public void show (FragmentManager manager, String tag)

Public void show(FragmentTransactiong transaction, String tag)

String参数是用来队列中的DialogFragment。在FragmentManager和FragmentTransaction的选择上,书中选择了FragmentManager因为传入这个参数,事物可以自动创建提交。

最简单的界面效果如下:

现阶段代码如下:

http://git.oschina.net/canglin/CriminalIntent/commit/ddf4b0365937ea287d0f64f7b437c1822f8745b0

对话框之间的数据交互,在本章已经简单介绍过了。书中在这里是继续完成了的。本着达到目标最简单的代码原则,这些代码先不提交到Git。

在每个小段落最后都会有当前阶段的Git代码地址。

小结:

到现在为止,基本上Android的一些最基本的界面,最基本的业务逻辑,数据逻辑都已经完成了。每个阶段的代码都是尽量的删减到最少,为了方便在Git中查看修改的过程,避免不必要的误导。

时间: 2024-10-12 07:40:08

《Android编程权威指南》-读书笔记(十一) 完善CriminalIntent的相关文章

Android编程权威指南-读书笔记(二)-第一个小程序

Android编程权威指南-读书笔记(二) -第一个小程序 第一个例子介绍 应用名为GeoQuiz.用户通过单击True或False按钮来回答屏幕上的问题,GeoQuiz可即时反馈答案正确与否. 这个例子为我们简单介绍了几个基本组件的使用,以及基本的事件监听.让我们对基本组件的使用和事件的监听有一个基本的了解. 这篇文章分为2个部分,第一部分就是创建简单的UI.第二个部分就是对这个UI增加代码来响应一些操作. (注:所有不明白或者不理解的东西其实都不重要,后面都会有更详细的介绍.) 本章的目标

android开发权威指南读书笔记

第17章 Fragment 1.在res目录下增加 layout-sw600dp 目录,用于存放7英寸及以上尺寸屏幕的布局文件.10英寸以上平板用 sw720dp.如果是更小的屏幕,如 480*800 则要用 sw480dp 2.在布局文件中直接以<fragment> 标签方式嵌入时候,要标明class属性,即 类似  class = "com.abc.MyFragment"   也可以用 android:name ,与class属性完全相同 3.通过fragment.ge

《Android编程权威指南》-读书笔记(三)Git初探

<Android编程权威指南>-读书笔记(三)Git初探 版本控制-Git 为什么要使用版本控制 什么是版本控制?我为什么要关心它呢?版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统.在本书所展示的例子中,我们仅对保存着软件源代码的文本文件作版本控制管理,但实际上,你可以对任何类型的文件进行版本控制. 如果你是位图形或网页设计师,可能会需要保存某一幅图片或页面布局文件的所有修订版本(这或许是你非常渴望拥有的功能).采用版本控制系统(VCS)是个明智的选择.有了它你就

《Android编程权威指南》-读书笔记(五)-挑战练习

<Android编程权威指南>-读书笔记(五) -挑战练习 为了巩固学习,为了建立信心.开始进行如下挑战: 挑战练习一:为TextView添加监听器 书中给出了提示,TextView,Button都是View的子类,都可以设置OnClickListener()直接加入如下代码: mQuestionTextView.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ mCurr

《Android编程权威指南》-读书笔记(四)-GeoQuiz功能扩展

<Android编程权威指南>-读书笔记 -GeoQuiz功能扩展 从现在开始,这本书开始扩展应用.在这次扩展中我们将会学习以下知识点: 创建一个新类 更新视图层 更新控制层 Git代码的修改和提交 Android Studio 在设备中运行该应用 给按钮添加图片资源 功能:下图是GeoQuiz应用对象图解.应用的对象按模型.控制器和视图的类别被分为三部分.Android应用是给予模型-控制器-视图(Model-View-Controller,简称MVC)的架构模式进行设计的. 创建一个类 T

IDA.Pro权威指南 读书笔记

http://www.pediy.com/kssd/pediy12/142766.html 标 题:IDA.Pro权威指南 读书笔记[Made By C_lemon] 作 者:Dstlemoner 时 间:2011-11-14 11:56:17 链 接:http://bbs.pediy.com/showthread.php?t=142766    IDA为反汇编 和逆向破解的 静态分析利器 ! 虽然是利器,但是你不会用的话~那就另当别论了. →     唉.对于刚入门的新手来说,看前人走过的路程

Hadoop权威指南读书笔记

本书中提到的Hadoop项目简述 Common:一组分布式文件系统和通用I/O的组件与接口(序列化.javaRPC和持久化数据结构). Avro:一种支持高效.跨语言的RPC以及永久存储数据的序列化系统. MapReduce:分布式数据处理模型和执行环境,运行于大型商业集群. HDFS:分布式文件系统,运行于大型商用机集群. Pig:一种数据流语言和运行环境,用以检索非常大的数据集.Pig运行在MapReduce和HDFS的集群上. Hive:一个分布式.按列存储的数据仓库.Hive管理HDFS

Android编程权威指南

Code download: www.bignerdranch.com/solutions/AndroidProgramming.zip Android编程权威指南,布布扣,bubuko.com

电子书 Android编程权威指南 第2版.pdf

Big Nerd Ranch是美国一家专业的移动开发技术培训机构.本书主要以其Android训练营教学课程为基础,融合了几位作者多年的心得体会,是一本完全面向实战的Android编程指南.全书共34章,详细介绍了8个Android 应用.通过这些精心设计的应用,读者可掌握很多重要的理论知识和开发技巧,获得前沿的开发经验. 如果你熟悉Java语言,或者了解面向对象编程,那就立刻开始Android编程之旅吧!作者简介Bill PhillipsBig Nerd Ranch骨灰级讲师.他在Big Ner