****************第一讲-资源的使用****************
一、一个Android应用程序通常是由以下几个组件构成的
活动(Activity)
服务(Service)
内容提供器(Content Provider)
广播接收器(Broadcast Receiver)
意图(Intent)
1.Activity
活动(Activity)是最基本的Android应用程序组件
在应用程序中,一个活动通常就是一个单独的屏幕
每个活动都通过继承活动基类而被实现为一个独立的活动类
活动类将会显示由视图控件组成的用户接口,并对事件做出响应
它负责定义用户在屏幕上的体验。
注意:每个activity在使用前必须在mainfest进行注册
2.服务(Service)
服务是Android应用程序中具有较长的生命周期但是没有用户界面的程序
Service运行在后台,并且可以与其他程序进行交互。
Service跟Activity的级别差不多,但是不能独立运行,需要通过某一个Activity来调用。
如果应用程序要求在没有界面显示的情况还能正常运行此时就需要用到Service。
service可以在很多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放
3.内容提供器(ContentProvider)
Android应用程序可以使用文件或SQLite数据库来存储数据(如联系人列表)。
Content Provider提供了一种多应用间数据共享的方式。
一个应用程序可以通过实现一个ContentProvider的抽象接口将自己的数据暴露出去。
Android设置了一些预先配置好的内容提供器,也可以编写自己的内容提供器。
4.广播接收器(BroadcastReceiver)
它负责将指定的事件消息通知给Android应用程序,例如Android设备上电池电量,或者接收到一个来电的事件。
实际上,如果出于某些原因,需要将应用程序数据结构中某个状态的变化通知给其他的应用程序
甚至可以发送属于自己的事件广播。
5.意图(Intent)
Intent是Android系统独有的消息传递机制
Intent是利用消息实现应用程序间的交互机制,能够在程序运行的过程中连接两个不同的组件
Intent描述了应用中一次操作的动作、数据以及附加数据,向Android表达某种请求或者意愿
6.Android 体系结构
应用层 :运行在虚拟机上的程序
应用框架层 :提供Android平台基本的管理功能和组件重用机制
系统运行库层:C库 wibkit SQLite等
Linux核心层 :设备相关的驱动程序(基于IEEE802.1的WiFi驱动 MTDflash内存驱动 BinderIPC驱动—提供进程间的通信功能)
7.Android系统的特征
访问手机硬件
使用网络进行数据传输
后台服务
位置服务和Google地图
SQlite 数据存储
多媒体支持
共享数据和进程间通信
使用Wigget和动态壁纸增强屏幕
Google云信息
优化的内存和进程管理
二、Android应用程序框架
了解目录框架结构
1.src文件夹是项目的所有包及源文件(.java);
2.res文件夹中则包含了项目中所有的资源,,比如:程序图标(drawable)、布局文件(layout)、常量(values)等;
3.gen文件夹中的文件时Android项目自动生成的
4.assets文件夹中包含应用系统需要使用到的诸如mp3、视频类的文件.
5.libs文件夹下面存放的是项目中用到的第三方的库文件。
****androidManifest****重点项目配置文件,要求对里面的配置内容 熟练掌握-参考ppt26
1.manifest根标签,该标签带有一个package属性,
package属性用来声明应用程序包
xmlns:android属性包含了命名空间的声明
android:versionCode versionName版本信息
2.<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18"/> 最低和目标版本需求
3.<uses-permission android:name="android.permission.INTERNET" />
权限声明
4.application标签
1.子标签用来定义各种组件的声明
//activity注册
<activityandroid:name=".SelectCtiyActivity"</activity>
//首次进入加载activity
<intent-filter>
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" />
</intent-filter>
//服务注册
<serviceandroid:name="com.way.weather.WeatherUpdateService" >
//广播注册
<receiverandroid:name="com.way.weather.WeatherWidget">
三、资源文件-res文件件
res/anim动画文件
res/drawable图片文件
res/layout布局文件
res /values各种XML资源文件如下
String.xml:字符串文件
Arrays.xml:数组文件
Colors.xml:颜色文件
Dimens.xml:尺寸文件
Styles.xml:样式文件
res /xml任意的xml文件
res /raw直接复制到设备中的原生文件
res /menu菜单文件
pt:物理点
dp:非密度制像素
px:屏幕像素
sp:缩放比例无关
如何访问
(1)res目录存放Android程序能通过R资源类直接访问
(2) 在xml中使用资源的完整语法格式为:
例:@string/name
assets目录存放Android程序不能直接访问的资源(原生文件),如MP3文件,必须通过AssetManager类访问。
*************************************************
****************第二讲-activity,Framgment******
一、activity概念
Activity是一个应用程序组件,提供了一种用户可以交互的屏幕,如拨打电话,拍照,发送电子邮件,或查看地图。
通常一个应用程序包括多个Activity,只有一个Activity被指定为“主”的Activity。
activity遵守基本的“后进先出”的堆栈机制(详细解释下)
二、创建 Activity
1.要创建一个Activity,我们必须创建Activity的一个子类。
2.在mainfest配置文件中注册
3.实现父类的各个事件的回调方法
4.加载布局,修改事件。是一个用户可交互的界面
setContentView(R.layout.activity_main);
findViewById
setOnClickListener
//注册一个activity并声明为程序的主入口
<activityandroid:name=".ExampleActivity"android:icon="@drawable/app_icon">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
三、显式启动一个activity
1.
Intentintent = new Intent(this, HostActivity.class);
startActivity(intent);
2.
Intentintent = new Intent(this, HostActivity.class);
startActivityForResult(intent,1);
//启动的activity被销毁后回调到这个方法
@Override
protectedvoid onActivityResult(int requestCode, int resultCode, Intent data) {
//TODO Auto-generated method stub
super.onActivityResult(requestCode,resultCode, data);
}
//新启动的activity销毁前,设置返回结果
setResult(resultCode,data)
3.finish()方法关闭ActivityfinishActivity()关闭以前启动的Activity
4.传递数据
Intent intent =new Intent()
intent.putExtra(key,value);
startActivity(intent);
四、重点中的重点-activity的生命周期
1.书本62页 图3.4 Activity 生命周期必须牢记
oncreate();
onstart();
onresume();
activtity running
onpause()返回当前activity调用onResum()
onStop()--onrestart()--start()
onDestroy()
2.创建activity的各个生命周期回调函数,打印相关日志来测试(i v d w d)
3.参考63页 表3.2 Activity 生命周期函数
五、Framgment
1.activity占据整个屏幕,Framgment占据屏幕一部分
Fragment允许将Activity拆分成多个完全独立封装的可重用的组件,每个组件有它自己的生命周期和UI布局
我们可以将Fragment设计成Activity的一个模块或者一个可重用的组件。也就是说,多个Activity可以共用一个Fragment。
Fragment 不需要注册,只有嵌入到一个Activity时,它才能够存在,生命周期依赖于嵌入的Activity
2.生命周期
依附于主activity
参考书本69页 图3.11 Activity 的生命周期对Fragment 生命周期的影响
Fragment 生命周期开始于onAttach与父Activity绑定》结束于调用onDetach
Activity 被放进Activity栈用返回按钮就可回到它,
当切换或者一处Fragement 需要调用addBackStack()方法
3.静态的使用Fragment
这是使用Fragment最简单的一种方式,把Fragment当成普通的控件,直接写在Activity的布局文件中。
(1)每个Fragment都有自己单独的类和布局和生命周期
(2)类要继承自Fragment
publicclass ContentFragment extends Fragment
(3)布局通过类里面父类方法的onCreateView里面进行加载
@Override
publicView onCreateView(LayoutInflater inflater, ViewGroup container,
BundlesavedInstanceState) {
returninflater.inflate(R.layout.fragment_content, container, false);
}
布局是一个普通的layout文件
(4)把写好的Fragment加载在主activity的布局里面就可以直接使用了。
<fragment
android:id="@+id/id_fragment_title"
android:name="com.example.test2.TitleFragment"
android:layout_width="fill_parent"
android:layout_height="45dp"/>
4.动态加载Fragment
使用<FrameLayout>作为动态加载fragment的容器 --区别 <fragment>
<FrameLayout
android:id="@+id/content_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/bottom_layout"
/>
主activity在合适的地方加载fragment布局
FragmentManager fm =getSupportFragmentManager();
FragmentTransaction transaction =fm.beginTransaction();
transaction.replace(R.id.content_fragment, newTitleFragment());
transaction.remove(R.id.content_fragment, new TitleFragment());
transaction.add(R.id.content_fragment,new TitleFragment());
transaction.commit();
Fragment常用的三个类:
android.app.Fragment 主要用于定义Fragment
android.app.FragmentManager 主要用于在Activity中操作Fragment
android.app.FragmentTransaction 保证一些列Fragment操作的原子性,熟悉事务这个词,一定能明白~
a、获取FragmentManage的方式:
getFragmentManager() // v4中,getSupportFragmentManager
b、主要的操作都是FragmentTransaction的方法
FragmentTransaction transaction =fm.benginTransatcion();//开启一个事务
transaction.add()
往Activity中添加一个Fragment
transaction.remove()
从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈(回退栈后面会详细说),这个Fragment实例将会被销毁。
transaction.replace()
使用另一个Fragment替换当前的,实际上就是remove()然后add()的合体~
transaction.hide()
隐藏当前的Fragment,仅仅是设为不可见,并不会销毁
transaction.show()
显示之前隐藏的Fragment
detach()
会将view从UI中移除,和remove()不同,此时fragment的状态依然由FragmentManager维护。
attach()
重建view视图,附加到UI上并显示。
transatcion.commit()//提交一个事务
注意:常用Fragment的哥们,可能会经常遇到这样Activity状态不一致:Stateloss这样的错误。主要是因为:commit方法一定要在Activity.onSaveInstance()之前调用。
上述,基本是操作Fragment的所有的方式了,在一个事务开启到提交可以进行多个的添加、移除、替换等操作。
值得注意的是:如果你喜欢使用Fragment,一定要清楚这些方法,哪个会销毁视图,哪个会销毁实例,哪个仅仅只是隐藏,这样才能更好的使用它们。
其中transaction 有add remove replace方法支持我们动态加载,加载前后要开启和提交事务。
注意:
Fragment是在3.0版本开始才添加的,所以最低版本小于11时,使用支持包android-support-v4.jar里面的Fragment,
(1)使用包:iandroid.support.v4.app.Fragment;而不是: android.app.Fragment;
(2)Activity必须是继承FragmentActivity
导包:android.support.v4.app.FragmentActivity;
(3) 动态加载时是getSupportFragmentManager而不是getFragmentManager
Fragement 需要使用Activity的引用就必须使用getActivity方法来返回它所嵌入的Activity的引用
***********************************************
************第一讲(常用布局)*************
一、android ui概述
1.Android应用程序中所有的用户界面都是由View和ViewGroup组成的。
2.View是Android可视界面元素的基础类,所有的控件都是由View派生而来的,它给用户提供了一个可以交互的对象。
3.一个ViewGroup中是一个特殊的View,即可以包含其他View。ViewGroup是的布局和视图容器的基类。
--》查看源码中布局和控件类的父类全部都是View
二、布局管理
1.简介
布局定义了UI界面中各个view的排列方式,把view按照一定的排列顺序组合在一起,组成一个完整的界面。
一个Layout定义了用户界面的视觉架构,可以用两种方式来创建布局。
第一种也是简单常用的一种是,在xml文件中声明UI控件。这种方式是将需要显示的控件先在布局文件中进行声明,然后在程序中通过setContentView(R.layout.XXX)方法将布局呈现在Activity中。--》重点掌握
第二种是在程序中通过代码直接实例化布局及其组件。界面中的组件及布局需要动态改变时推荐使用这种方式。
--》提升技能
Android常用的布局有线性布局(LinearLayout),相对布局(RelativeLayout),绝对布局(AbsolutelyLayout),网格布局(GridLayout)等。
--》重点掌握 线性布局(LinearLayout)相对布局(RelativeLayout)网格布局(GridLayout)另外几种布局作为提升技能
2.线性布局(LinearLayout)
该布局中的元素之间成线性排列,水平排列或者垂直排列,方向由“android:orientation”属性控制,属性值有垂直(vertical)和水平(horizontal)两种。
其它常用属性讲解
(1)android:layout_width="wrap_content"
android:layout_height="wrap_content"
必填项
属性值:wrap_content内容包裹 fill_parent填充父类 match_parent匹配父类
(2)文本类显示
android:text文本
android:textColor 字体颜色
android:textSize 字体大小 单位为sp
(3)布局盒子模型
android:layout_marginBottom 离某元素底边缘的距离
android:layout_marginLeft 离某元素左边缘的距离
android:layout_marginRight 离某元素右边缘的距离
android:layout_marginTop 离某元素上边缘的距离
对应的
android:paddingLeft
android:paddingRight
android:paddingBottom
android:paddingTop
表示元素本身内容距离自己的布局边框的距离
android:layout_weight线性布局专有 用来跟兄弟布局通过比重值来平分父布局里面的间距大小,这时通常layout_width和layout_height会有一个失效,失效的属性不能删掉同时属性值要置为0dp
注意布局属性中 通畅包含两类 一类是带layout 一类是不带layout
带layout_表示元素本身在父布局中的位置
不带layout表示元素所包含的内容再自己的哪个位置
例如: android:layout_gravity="center"
android:gravity="center"
可以通过 在 父子布局中使用不同的属性达到同一种效果。
3.相对布局(RelativeLayout)
线性布局并不能满足我们所有的布局需求。如果我们需要在一行或者一列显示多个控件,而且有控件靠在父控件的最左边或最右边,这时RelativeLayout可以很灵活的调整多个控件的位置
关键布局属性
第一类:属性值为true或false
android:layout_centerHrizontal 水平居中
android:layout_centerVertical 垂直居中
android:layout_centerInparent 相对于父元素完全居中
android:layout_alignParentBottom 贴紧父元素的下边缘
android:layout_alignParentLeft 贴紧父元素的左边缘
android:layout_alignParentRight 贴紧父元素的右边缘
android:layout_alignParentTop 贴紧父元素的上边缘
第二类:属性值必须为id的引用名“@id/id-name”
android:layout_below 在某元素的下方
android:layout_above 在某元素的的上方
android:layout_toLeftOf 在某元素的左边
android:layout_toRightOf 在某元素的右边
android:layout_alignTop 本元素的上边缘和某元素的的上边缘对齐
android:layout_alignLeft 本元素的左边缘和某元素的的左边缘对齐
android:layout_alignBottom 本元素的下边缘和某元素的的下边缘对齐
android:layout_alignRight 本元素的右边缘和某元素的的右边缘对齐
可以演示几个重要属性,比如在父类的底部。在父类正中间。在某个空间的正上方 正下方。
手写演示出书本上的布局
4.网格布局GridLayout
Android4.0以后新增GridLayout网格布局,它是所有布局管理器中最为灵活的一种。所以16版之前的SDK不支持GridLayout,要想使用网格布局必须在AndroidManifest.xml中把Android的最低版本声明为16,即android:minSdkVersion="16"。其实是对线性布局的一种封装。
重要属性
父元素:
android:columnCount 排版元素数量-超过就换行
android:orientation 水平/垂直排列
子元素:
android:layout_column 跳过多少个元素后排列
<Button
android:layout_column="3"
android:text="/" />
android:layout_rowSpan 跨多少行
android:layout_columnSpan 跨多少列
==其它布局 了解即可不常用-演示书中案例
5.单帧布局 FrameLayout
单帧布局是最简单的布局形式。所有添加到这个布局中的视图都会放置于这块区域的左上角,都以层叠的方式显示。第一个添加的控件被放在最底层,最后一个添加到框架布局中的视图显示在最顶层,上一层的控件会覆盖下一层的控件。
6.绝对布局AbsoluteLayout
绝对定位AbsoluteLayout,又可以叫做坐标布局,可以直接指定子元素的绝对位置,这种布局简单直接,直观性强,但是由于手机屏幕尺寸差别比较大,使用绝对定位的适应性会比较差。
android:layout_x="25dp"
android:layout_y="25dp"
通过坐标定义元素位置,坐标单位仍未dp
7.多种布局可以组合使用来构建出一个复杂布局,灵活运用。
实现计算机的布局(可以有很多种布局方法来达到同一种目的)
*******************************
************第二讲(常用控件)*
一、简介
Android提供了一个标准的widget组件来帮助创建简单的UI界面。这些widget组件都定义在android.widget包中,他们几乎都是View的子类。使用widget组件有两种方式:xml布局文件和代码段中。我们推荐使用xml布局文件的方式,因为这种方式简单易用,易于维护
二、
1.按钮(Button)--》简单演示
2.文本框 (TextView)--》简单演示
3.编辑框(EditText) --》简单演示
4.单项框(RadioGroup、RadioButton)
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RadioButton
android:id="@+id/radioMale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="男" />
<RadioButton
android:id="@+id/radioFemale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="女" />
</RadioGroup>
//单选框
RadioGroupgroup = (RadioGroup)this.findViewById(R.id.radioGroup);
group.setOnCheckedChangeListener(newOnCheckedChangeListener() {
@Override
publicvoid onCheckedChanged(RadioGroup group, int checkedId) {
RadioButtonrb = (RadioButton)MainActivity.this.findViewById(checkedId);
Log.i("",rb.getText().toString());
}
});
5.复选框
<CheckBox
android:id="@+id/checkBoxA"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="A、紧急制动,靠边停车"
android:textSize="16sp"/>
<CheckBox
android:id="@+id/checkBoxB"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="B、牢牢地握住转向盘,保持直行"
android:textSize="16sp"/>
<CheckBox
android:id="@+id/checkBoxC"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="C、立即松开加速踏板"
android:textSize="16sp"/>
<CheckBox
android:id="@+id/checkBoxD"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="D、轻踩制动踏板"
android:textSize="16sp"/>
6.自动提示(AutoCompleteText)
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="账号 :"
android:textSize="16dp"/>
<AutoCompleteTextView
android:id="@+id/countries_list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="16dp"/>
//自动提示
String[]COUNTRIES = new String[] {"11234", "11345","11534", "11678", "11290"};
ArrayAdapter<String>adapter = newArrayAdapter<String>(this,android.R.layout.simple_dropdown_item_1line,COUNTRIES);
AutoCompleteTextViewtextView = (AutoCompleteTextView)findViewById(R.id.countries_list);
textView.setAdapter(adapter);
7.图片视图(ImageView)
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:src="@drawable/ic_launcher"
android:layout_gravity="center_horizontal"/>
8.进度条(ProgressBar)
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@android:style/Widget.ProgressBar.Large"
/>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@android:style/Widget.ProgressBar.Horizontal"
/>
//进度条
ProgressBarprogressBar1 = (ProgressBar) findViewById(R.id.progressBar01);
ProgressBarprogressBar2 = (ProgressBar) findViewById(R.id.progressBar02);
//进度结束
p1=(ProgressBar)findViewById(R.id.p1);
p1.setVisibility(View.GONE);
//进行了40%
progressBar2.setProgress(40);
9.拖动条(SeekBar)
//拖动条
SeekBarseekBar = (SeekBar) findViewById(R.id.seekBar);
seekBar.setOnSeekBarChangeListener(newOnSeekBarChangeListener() {
@Override
publicvoid onStopTrackingTouch(SeekBar seekBar) {
Log.i("","停止");
}
@Override
publicvoid onStartTrackingTouch(SeekBar seekBar) {
Log.i("","开始");
}
@Override
publicvoid onProgressChanged(SeekBar seekBar, int progress,
booleanfromUser) {
Log.i("","进度为:"+progress);
}
});
seekBar.getProgress();获取当前进度
10.列表视图和适配器-ListView Adapter -->重点、难点
ListView控件是一个显示可滚动的项目列表。ListView使用adapter将把源数据转成成ListView项目并自动插入到列表中。这些数据源可以是数组,也可以是从数据库中查询的数据。
例如:联系人列表,通话记录,还有qq的聊天界面。这些需要动态实时更新的数据列表。
ListView需要两个布局文件
(1)一个是Activity的界面布局文件
用来定义整个listView的布局和大小
<ListView
android:id="@+id/listView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
(2)另外一个是ListItem的布局文件。
用来定义 listview里面每个条目自己的布局
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/itemImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:src="@drawable/ic_launcher" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20sp"
android:layout_toRightOf="@+id/itemImage"
android:orientation="vertical" >
<TextView
android:id="@+id/contactsname"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5sp"
android:text="小李"
android:textSize="18sp"/>
<TextView
android:id="@+id/contactsnum"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5sp"
android:text="0123456789"
android:textSize="10sp"/>
</LinearLayout>
</RelativeLayout>
(3)适用SimpleAdapter来实现listview
最后的显示效果和数据切换就要在代码中实现,并且要适用adapter类对动态数据进行管理
private ListViewlistView;
@Override
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView= (ListView) findViewById(R.id.listView);
//下面是模拟出来的静态数据,此部分数据根据应用实际情况可以从网络和数据库获取都行。最终要被放置在adapter中
//adapter再与listview进行绑定即可
Listcontacts = new ArrayList<HashMap<String,String>>();
for(inti=0; i<8; i++){
HashMap<String,String>hashMap = new HashMap<String,String>();
hashMap.put("contactsname","小王");
hashMap.put("contactsnum","0123456789");
contacts.add(hashMap);
}
//创建SimpleAdapter
SimpleAdapteradapter = new SimpleAdapter(this, contacts,R.layout.listview_item,
newString[]{"contactsname","contactsnum"}, newint[]{R.id.contactsname,R.id.contactsnum});
//listview与adapter绑定
listView.setAdapter(adapter);
//listview 条目点击事件
listView.setOnItemClickListener(newOnItemClickListener() {
@Override
publicvoid onItemClick(AdapterView<?> parent, View view,
intposition, long id) {
Log.i("","第"+(position+1)+"行被点击");
}
});
}
(4)实现数据的动态更新,只需修改contacts里面的数据,然后adapter.notifyDataSetChanged()刷新adapter即可
主界面新增加出发 新增和删除条目的按钮,重点看代码实现
findViewById(R.id.add).setOnClickListener(newOnClickListener() {
@Override
publicvoid onClick(View v) {
HashMap<String,String>hashMap = new HashMap<String,String>();
hashMap.put("contactsname","小王");
hashMap.put("contactsnum","0123456789");
contacts.add(hashMap);
//通知刷新界面
adapter.notifyDataSetChanged();
}
});
findViewById(R.id.remove).setOnClickListener(newOnClickListener() {
@Override
publicvoid onClick(View v) {
HashMap<String,String>hashMap = new HashMap<String,String>();
hashMap.put("contactsname","小王");
hashMap.put("contactsnum","0123456789");
contacts.remove(0);
//通知刷新界面
adapter.notifyDataSetChanged();
}
});
10.adapter进阶应用
ListView展示数据需要三个要素:视图,数据和适配器。Android许多控件都需要用到Adapter的实现类才能把数据展示在界面上。Adapter本身只是一个接口,它是数据和视图之间的桥梁。常用的Adapter接口的实现类有ArrayAdapter、SimpleAdapter、SimpleCursorAdapter和BaseAdapter。
--了解
ArrayAdapter支持泛型操作,最为简单,只能展示一行字。
SimpleAdapter有最好的扩充性,可以自定义出各种效果。
SimpleCursorAdapter可以适用于简单的纯文字型ListView,它需要Cursor的字段和UI的id对应起来。如需要实现更复杂的UI也可以重写其他方法。可以认为是SimpleAdapter对数据库的简单结合,可以方便地把数据库的内容以列表的形式展示出来。
本章重点掌握BaseAdapter的用法
--应用场景:当我们的列表项比较复杂,比如包含了其它的按钮,我们不紧要捕获条目的单击事件还要捕获条目上某些按钮和其它部分的事件,这是我们用到BaseAdapter
(1)首先,主界面listview布局不变,修改我们的item布局 在每个条目上增加一个下载按钮。
在listview的案例中修改 新增按钮
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:focusable="false"
android:text="down" />
注意:android:focusable="false"如果没有本行,会发现listView的每一行没有焦点了,这是因为Button抢夺了listView的焦点,只要布局文件中将Button设置为没有焦点按钮和ListView的每一行都可以触发单击事件。
(2)创建自定义adapter 继承自BaseAdapter
实现自己的构造方法
privateLayoutInflater mInflater;
privateList<Map<String, Object>> mData;
privateContext mContext;
publicMyAdapter(Context context,List<Map<String, Object>> mData) {
this.mInflater= LayoutInflater.from(context);
this.mContext= context;
this.mData=mData;
}
注意:主要是传入mContext上下文和mData绑定数据
(3)实现四个父类的抽象方法
getCount():listView在开始绘制的时候,系统首先调用getCount()函数,根据它的返回值得到listView的长度,然后根据这个长度,调用getView()逐一绘制每一行。如果getCount()返回值是0的话,列表将不显示同样return1,就只显示一行。
getItem(int position):该方法的返回值决定第position处的列表项的内容。
getItemId(int position):该方法的返回值决定地position处的列表项的ID。
getView(int position, View convertView,ViewGroup parent):系统在绘制列表的每一行的时候将调用此方法。getView()有三个参数,position表示将显示的是第几行,covertView是从布局文件中inflate来的布局。
重点是实现getCount和getView方法 难点是getView
publicint getCount() {
returnmData.size();
}
@Override
publicView getView(int position, View convertView, ViewGroup parent) {
ViewHolderholder;
//创建view
if(convertView==null){
holder= new ViewHolder();
convertView= mInflater.inflate(R.layout.listview_item, null);
holder.img= (ImageView) convertView.findViewById(R.id.itemImage);
holder.title= (TextView) convertView.findViewById(R.id.contactsname);
holder.time= (TextView) convertView.findViewById(R.id.contactsnum);
holder.download= (Button) convertView.findViewById(R.id.button);
convertView.setTag(holder);
}
else{
holder= (ViewHolder) convertView.getTag();
}
//动态给每个item view 进行数据绑定,包括了按钮点击事件
holder.img.setBackgroundResource((Integer)mData.get(position).get("img"));
holder.title.setText((String)mData.get(position).get("title"));
holder.time.setText((String)mData.get(position).get("time"));
finalint printposition = position;
holder.download.setOnClickListener(newOnClickListener(){
@Override
publicvoid onClick(View v) {
Toast.makeText(mContext, "第"+(printposition+1)+"行的按钮被单击",Toast.LENGTH_LONG).show();
}
});
//返回
returnconvertView;
}
//定义界面实体类
privatefinal class ViewHolder{
publicImageView img;
publicTextView title;
publicTextView time;
publicButton download;
}
11.对话框 (Dialog)
对话框是一个小窗口,提示作出决定或输入其它信息的用户。
给出书上的案例代码,重点掌握
(1)确认对话框
AlertDialog.Builderbuilder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("你确定要离开吗?");
builder.setPositiveButton("确定",
newDialogInterface.OnClickListener() {
publicvoid onClick(DialogInterface dialog,
intwhichButton) {
displayToast("你选择了确定");
}
});
builder.setNegativeButton("取消",
newDialogInterface.OnClickListener() {
publicvoid onClick(DialogInterface dialog,
intwhichButton) {
// 这里添加点击确定后的逻辑
displayToast("你选择了取消");
}
});
builder.create().show();
(2)日期对话框
Calendarmycalendar = Calendar.getInstance(Locale.CHINA);
Date mydate = new Date(); // 获取当前日期Date对象
mycalendar.setTime(mydate);// //为Calendar对象设置时间为当前日期
year = mycalendar.get(Calendar.YEAR); //获取Calendar对象中的年
month =mycalendar.get(Calendar.MONTH);// 获取Calendar对象中的月
day = mycalendar.get(Calendar.DAY_OF_MONTH);// 获取这个月的第几天
datePickerDialog= new DatePickerDialog(MainActivity.this,
Datelistener,year, month, day);
datePickerDialog.setIcon(R.drawable.ic_launcher);
datePickerDialog.setTitle("日期选择窗口");
datePickerDialog.show();
privateDatePickerDialog.OnDateSetListener Datelistener = newDatePickerDialog.OnDateSetListener() {
@Override
publicvoid onDateSet(DatePicker view, int myyear, int monthOfYear,
intdayOfMonth) {
year= myyear;
month= monthOfYear;
day= dayOfMonth;
updateDate();
}
privatevoid updateDate() {
displayToast("当前日期:" + year + "-" + (month + 1) + "-"+ day);
}
};
其它的几种对话框,把书上源码发给大家了解即可。
12.ActionBar
ActionBar位于Activity的顶部,可用来显示activity的标题、Icon、Actions和一些用于交互的View。它也可被用于应用的导航。
ActionBar 是在Android3.0(API 11)中加入到SK中的,想在低版本中使用ActionBar有两种选择:使用http://actionbarsherlock.com 或使用SupportLibrary v7。
(1)如果你不想要Action bar,把Activity的主题设置为Theme.Holo.NoActionBar就可以了
<activityandroid:theme="@android:style/Theme.Holo.NoActionBar">
或者使用Action bar的 hide()方法,如下:
ActionBaractionBar = getActionBar();
actionBar.hide();
(2)使用ActionBar
Actions即ActionBar中的每个交互项,可以在代码中创建Action,也可以在XML文件中指定(位于res/menu)。在menu资源文件中定义Action的方法如下:
<menuxmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_refresh"
android:orderInCategory="100"
android:showAsAction="always"
android:icon="@drawable/ic_action_refresh"
android:title="Refresh"/>
<item
android:id="@+id/action_settings"
android:title="Settings">
</item>
</menu>
在Activity中创建ctionBar的Action代码位于onCreateOptionsMenu()
@Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.mainmenu, menu);
return true;
}
如果一个Action被单击,对于activity中的onOptionsItemSelected()将被调用
Override
public boolean onOptionsItemSelected(MenuItemitem) {
switch (item.getItemId()) {
// action with ID action_refresh wasselected
case R.id.action_refresh:
Toast.makeText(this, "Refreshselected", Toast.LENGTH_SHORT)
.show();
break;
// action with ID action_settings wasselected
case R.id.action_settings:
Toast.makeText(this, "Settingsselected", Toast.LENG
.show();
break;
default:
break;
}
return true;
}
13.拓展使用第三方框架实现 上拉加载,下来刷新功能。
***********/********************///
************第三讲(事件处理)*
在讲解常用控件的时候,已经把事件处理的方法融入了进去。
*******************************