Android 基础回顾2

一、Android四大组件

#非空判断
if(str!=null||str.length!=0)
#<uses-permission android:name="android.permission.CAMERA" /> 加相机权限
Activity
1、Activity是什么?
a:是android的四大组件之一
b:提供UI交互的场所
c:可以充满屏幕,也可以悬浮在其他activity之上
d:一个应用通常由多个activity组成
e:一个activity可以打开任一个activity

2、如何创建一个Activity
创建其子类(或现有子类),在其重写由于系统调用的回调方法,最重要的是
a) onCreate()
必须实现此方法, 系统会在创建您的 Activity 时调用此方法。应该在实现内初始化 Activity 的必需组件。 最重要的是,必须在此方法内调用setContentView(),以定义 Activity 用户界面的布局。
b)onPause()
系统将此方法作为用户离开 Activity 的第一个信号(但并不总是意味着 Activity 会被销毁)进行调用。 通常应该在此方法内确认在当前用户会话结束后仍然有效的任何更改(因为用户可能不会返回)。
步骤:
1)创建一个class,继承Activity方法(或其子类)
2)重写onCtreate()方法
3)在onCreate方法中实现setContentView();方法,设置布局( 也可以是一个View
4)在清单文件中声明:
<manifest ... >
  <application ... >
      <activity
android:name = "包名.类名" >
      ...
</activity >
      ...
  </application ... >
  ...
</manifest >

3、Activity的生命周期
一个完整的生命周期 :onCreate()->onStart()->onResume()
->ActivityRunning->返回键
->onPause->onStop()->onDestory
创建时的生命周期:
onCreate()->onStart()->onResume()
销毁一个Activity时的生命周期:
onPause->onStop()->onDestory
一个应用正在运行,这时点击Home键,应用到后台
onPause->onStop()
从后台再次运行:
onRestart()->onStart()->onResume()->ActivityRunning
可见的生命周期:
在onStart和onStop之间
前端生命周期
onResume和onPause之间
onStart()和onResume()的区别
onPause()和onStop()的区别
a):是否可见,onResume和onPause可见
b):什么时候Activity是前端运行的,在onResume和onPause的之间

onCreate(): 不可见,不可被终止
首次创建 Activity 时调用。 您应该在此方法中执行所有正常的静态设置— 创建视图、将数据绑定到列表等等。系统向此方法传递一个 Bundle 对象,其中包含 Activity 的上一状态,不过前提是捕获了该状态。
始终后接  onStart()
onStart(): 不可见,不可被终止
在 Activity 即将对用户可见之前调用。
如果 Activity 转入前台,则后接  onResume() ,如果 Activity 转入隐藏状态,则后接  onStop()
后接控件onResume() ,是一气呵成的,直接调用,绑定控件的操作需要在此周期
onResume() 可见,不可销毁
当前Activity即将进入前端,此时Activity正在处于Activity栈的顶端,获取用户焦点,此时优先级最高。此时可以进行动画等需要可见的操作
后接onPause()
onPause(),可见,可以被终止
当系统即将开始继续另一个 Activity 时调用。 此方法通常用于保存对持久性数据的未保存更改,停止动画,关闭网络连接,关闭数据库以及其他可能消耗 CPU 的内容,诸如此类。 不能做耗时操作,必须遵循不能大量耗时,如果有大量的耗时操作,可以选择在onStop的生命周期做。
后接onStop()
onStop(),不可见,可以被系统终止
此时的优先级很弱,系统如果发生内存不足,就会杀死此时的activity,如果没有被系统杀死,那么,从新启动时,会调用onRestart,如果被系统杀死,那么下次启动,重新启动
onStop和onStart是对立的,如果在onStart进行了绑定,此时应该解除绑定。
onRestart(),不可见,不可被杀死
当Activity进入onStop时再次调用时的生命周期
onDestory(),不可见,可被杀死
在 Activity 被销毁前调用。这是 Activity 将收到的最后调用。


4、两个Activity跳转的周期
A开启
A onCreate()->A onStart()->A onResume->A Running
A跳转到B
A onPause()->B onCreate()->B onStart()->B onResume()->B Running
B返回A
B onPause()->A onRestart()->A onStart()->A onResume()->A Running
B onStop()->B onDestory()

新的页面开启,必须在旧的页面onPause之后,所以不能太多的耗时操作

5、现场保护
Activity在不做任何保护时,切换横竖屏, 会先销毁,再创建 ,因为需要可能需要同名但放在不同的文件夹中的布局,需要重新加载(layout-land)
横竖屏切换重新执行生命周期导致一些控件输入的内容不能保存,所以需要现场保护

a:在安卓中,EditText如果添加了id,会形成自我保护 ,但EditText仅限于文本内容,CheckBox只会保护选中状态
b:现场保护
方法1:
保护现场:把数据放入Bundle
/**
* Activity自我保护的方法,切换横竖屏,或者内存不足,销毁Activity时
* 调用此方法,保存数据,保留到参数Bundle中
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Bundle类似于Map,储存的范围大于Map,可以存序列化对象啊
ColorStateList textColors = et.getTextColors();
int color = textColors.getDefaultColor();
outState.putInt("color", color);
}
恢复现场:从Bundle中取值
/**
* 重新恢复时调用(发生异常时)
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
int color = savedInstanceState.getInt("color",Color.BLACK);
//参数1,key;参数2,当key取不到值时的默认值
et.setTextColor(color);
}

方法2:
切换横竖屏不重新走生命周期
在清单文件中,activity标签内
android:configChanges="" 此标签指定的情况下不走生命周期
orientation 方向
screenSize 屏幕尺寸,API 14以上,认为横竖屏切换屏幕尺寸改变
keyboardHidden 软键盘弹出导致布局改变
方法3:
固定屏幕横竖
在清单文件中,activity标签内
android:screenOrientation
landscape 横屏 风景画
portrait 竖屏 肖像画

6、Intent 意图
安卓四大组件的纽带,开启Activity,发送广播,开启服务
分类:
1、显式意图 知名达意
2、隐式意图

7、显式方式Intent
方法1:
a:封装意图 当前activity的this,目标activity的class
Intent intent = new Intent(MainActivity.this, SecondAvtivity.class);
b:封装消息 键值对
intent.putExtra("count", "358742662");
intent.putExtra("password", 123456);
不能直接放置对象,必须是序列化的
序列化时增加id项
/**
* 防止在读取对象时因为类的改变而照成的无法读取的现象
*/
private static final long serialVersionUID = 1L;
c:开启意图
startActivity(intent);
d:获取Intent
Intent intent = getIntent();
e:取值
String username = intent.getStringExtra("count");
int password = intent.getIntExtra("pass", 000000); key 缺省值
StudentBean bean = (StudentBean) intent.getSerializableExtra("object");
获取对象时需要强转
方法2:封装Bundle进行传值,连续传值时比较方便 更多使用
bundle类似Map,键值对
放置数据
Intent intent = new Intent(MainActivity.this,SencondActivity.class);
Bundle bundle = new Bundle();
bundle.putString("userName", "Zeral");
bundle.putInt("password", 123456);
intent.putExtras(bundle);
startActivity(intent);
获取数据
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
if(bundle!=null) {
String uname = bundle.getString("username");
int pwd = bundle.getInt("password");
}
方法1和方法2
相同点:传值类型相同
不同点:putExtra是直接放到Intent中 putExtras先封装到Bundle中,再把Bundle放到intent上

方法3:借助Application方式传值
每个程序都会创建一个Application的对象, 对象是唯一的,单例模式
创建一个类继承Application,在清单文件下注册,重写onCreate()方法
onCreate() ,在程序创建时调用,优先于Activity
多个Activity需要初始化的数据,可以在onCreate()方法进行全局初始化工作,可以声明常量
其他activity中可以直接getApplication直接获取
MyApp myApp = (MyApp) getApplication();
在一个Activity中给MyApp中的变量赋值,在另一个Activity中获取到

8、跳转页面,并获取返回值 多用于请求系统应用、类时使用
请求页面:
startActivityForResult(intent,1001);
参数1:意图 参数2:请求码
服务端:
Intent intent = new Intent();
intent.putExtra("result", "heheheh");
setResult(RESULT_OK, );
参数1:结果码 参数2:返回结果
finish(); 结束当前Activity
请求端,重写:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==1001&&resultCode==RESULT_OK&&data!=null) {
//逻辑
}
}

二、Activity的启动模式及Intent跳转以及Android中的视频播放

#URL 统一资源定位符 地址
#URI 统一资源标识符 id
URI分为 scheme 协议
host 服务端
prot 端口号
path 之后的路径

1、任务和回退栈
任务:
任务是执行特定作业时与用户交互的一系列Activity 遵循先进后出原则
堆栈中的Activity永远 不会重新排列开启Activity进入任务,返回按钮则弹出任务
回退栈:
任务会依次进入到回退栈中,也遵循先进后出原则

2、Activity启动模式 4s
开发中作用:Activity复用,减少内存消耗,提高性能,避免用户多次点击返回按钮,无法退出
##Activity复用 :1,singleTop模式,当前Activity处于栈顶,再次调用,会复用
2,singleTask模式下,Activity已经存在,再次调用会复用
3,singleInstance模式下,Activity已经存在,再次调用会复用
##此方法在本Activity复用时调用:
可以通过此方法进行Activity刷新工作
protected void onNewIntent (Intent intent) {
super.onNewIntent(intent);
}

设置启动模式:
1)、在清单文件中,给指定的Activity设置启动模式,android:launchMode
a:standard
默认模式,每次启动的Activity都会创建一个实例,进入任务,遵循后进先出原则
b:singleTop
顶部单一模式,如果设置此模式的Activity在栈顶,重复调用本Activity,不会创建新 的Activity,如果不处于栈顶,那么和standrad模式一样
c:singleTask
任务栈中单一模式,如果设置此模式的Activity在任务存在,调用时,将该Activity复用, 并且遵循任务栈不可重复排列原则,将该Activity之上的Activity全部弹出
d:singleInstance
设置此模式的Activity会单独存在一个任务栈中,如果再次调用,会复用原来创建的任务栈,并且任务栈也遵循后进先出的原则
##返回时,先返回本任务栈的Activity

2)、在Java中,Intent跳转时, 仅限于本次页面跳转
与方法1的区别:在清单文件中可以设置4种,而java代码中只能3种
清单文件一旦设置,启动模式固定了,而java中可以根据不同的跳转设不同的启动模式
两者冲突,以Java中的启动模式为准
intent.setFalgs():
FLAG_ACTIVITY_SINGLE_TOP =singleTop
FLAG_ACTIVITY_SINGLE_TOP|FLAG_ACTIVITY_CLEAR_TOP =singleTask
不添加 =standard

3、Intent页面跳转
显式意图:
需要用到Intent的一个属性 ComponentName(组件名)
ComponentName是Intent的七大属性之一,用来组件间跳转,形成显式意图,可以进行 跨程序挑转页面
底层都是封装的ComponentName
1:
Intent intent = new Intent((当前组件.this,目标组件.class);
2:
Intent intent = new Intent();
intent.setClass(当前组件.this, 目标组件.class);
3:
Intent intent = new Intent();
ComponentName componentName = new ComponentName(当前组件.this,目标组件.class);
intent.setComponent(componentName);
4:跳转到其他应用
Intent intent = new Intent();
/**
* 参数1 目标程序包名
* 参数2 目标activity的全路径(包名+类名)
* 要跳转的程序必须安装在手机上了,不必须是开启状态
*/
ComponentName componentName = new ComponentName("com.zjf.activity","com.zjf.activity.MainActivity");
intent.setComponent(componentName);
startActivity(intent);
隐式意图:
利用动作表示你要做的事
给定目标的参数,根据参数去匹配具体的组件
如果清单文件中的activity没有<intent-filter>的存在,那么要打开此activity,只能显式 意图。如果有,可以使用隐式意图。
隐式意图匹配的过程,就是Intent与清单文件<intent-filter>进行匹配的过程。发出的Intent匹配的是所有有<intent-filter>的组件。
隐式意图匹配成功:是intent中包含的Action和Category还有Data,type和intent-filter中包含的Action和Category还有Data,type完全相符,即匹配成功。
intent-filter中包含的Action和Category还有Data type
在目标activity的清单文件中设置 action,category(附加条件 但 必须加默认
Action:
一个Intent setAction, 只能携带一个Action(java中set多数是=赋值,多次设置,只能保留最后一次的内容)
一个intent-filter可以有多个action, 只有intent的action在intent-filter中包含,就能匹配成功
Category:
addCategory(在java中,add是添加,一般内部都是一个集合,调用此方法,会把数据添加到集合中), 所以可以携带多个Category
Intent中可以包含多个Category,如果Intent中的category都被清单文件的intent-filter包含,就算匹配成功。
为什么加默认的?
Intent中会 自动携带一个category,如果想要intent-filter匹配成功,必须要在intent-filter中携带默认的category
Data:
scheme:协议
Uri.parse("http://www.123321.com") 把字符串改成Uri
Intent中setData(URI); Intent中携带的数据中的协议与intent-filter中的data中的scheme相同即可
mimeType:
!!!data和type同时使用时,intent需要使用 setDataAndType(); 单独使用,会使另一个为空(看源码)
位于在Data中
Intent设置setType()一个intent中只能有一个type,如果多次设置,以最后一次为准
Intent中的类型只要在intent-filter中存在就可以匹配成功
#在清单文件中有多个意图过滤器,匹配原则为 完全全部匹配一个即可


4、Intent的七大属性:
ComponentName: 组件间跳转,显示意图底层封装
Extra: 携带的数据intent.putExtra(key,vaule);
Flags: java代码设置启动模式(三种)
隐式意图的一部分:在于intent-filter匹配的过程中,这四种都是需要考虑的因素
Action Category Data Type

5、利用隐式意图打开系统相关的Activity
a:打电话
intent.setAction(Intent. ACTION_CALL );
intent.setData(Uri.parse(" tel :13525425260"));
权限:
<uses-permission android:name="android.permission.CALL_PHONE" />
b:拨号界面
intent.setAction(Intent. ACTION_DIAL );
intent.setData(Uri.parse("tel:13525425260"));
c:发信息
intent.setAction(Intent. ACTION_SENDTO );
intent.setData(Uri.parse(" smsto :123213"));
intent.putExtra(" sms_body ", "你说的啥?");
d:设置页面
android.provider.Settings中的动作
内部有很多常量,而且这些常量可以打开不同的设置:例如wifi,时间,音量
intent.setAction( Settings.ACTION_WIFI_SETTINGS ); wifi
intent.setAction(Settings. ACTION_SETTINGS ); setting页面
e:照相机
权限:
<uses-permission android:name="android.permission.CAMERA"/>
intent.setAction( MediaStore . ACTION_IMAGE_CAPTURE );
f:打开本地存在的音频视频图片等
#DownLoad 外置共有文件夹
Uri.fromFile(file),把文件转成uri
Uri.parse(" file///具体路径 ") 把路径转成uri

intent.setAction(Intent. ACTION_VIEW) ;
File div = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File file = new File(div, "ml.mp4");
intent.setDataAndType(Uri.fromFile(file), "vedio/mp4"); //image/**.png
break;
g:HOME界面
intent.setAction( Intent.ACTION_MAIN );
intent.addCategory( Intent.CATEGORY_HOME );
h:打开QQ
//uin=17473540 和那个QQ号进行聊天
String url="mqqwpa://im/chat?chat_type=wpa&uin=17473540";
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);

6、安卓中播放视频的手段
a:利用隐式意图,打开本地视频
缺点,需要调用其他应用 只能打开本地视频
b:MediaPlayer 多媒体播放器
在安卓中进行视频播放,底层使用的大部分是mediaplayer
缺点:需要配特殊的控件使用,使用繁琐
优点:可以播放网络视频,音乐
c:VideoView 视频播放控件
底层也是MediaPlayer,对MediaPlayer进行了封装
优点:使用极其方便,并且可以播放网络和本地视频
缺点:无法播放音乐

三、Handler以及异步任务

#private ProgressDialog dialog;
dialog = new ProgressDialog(MainActivity.this);
dialog.setMessage("努力下载中……");
dialog.show();
dialog.dismiss();
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 将进度条设置成长条
dialog.setMax(100);设置最大值

#int totlesize = connection.getContentLength();获取总长度

#URLEncoder.encode(String);

#压缩图片:第四参数
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;//有返回值
options.inSampleSize = 10;//压缩倍数
Bitmap bitmap = BitmapFactory.decodeByteArray(result, 0, result.length,options);

#ANR
application not responding,应用程序无响应
造成原因,在android中,一个应用默认是一个进程,称之为主线程或者UI线程,它主要负责与用户界面交互逻辑。要求它实时保持较高的反应。如果在主线程中做了耗时操作,(I/O,网络请求),那么会出现卡顿,甚至无响应。

Activity中,耗时操作时间5秒,broadcastRecelver中,10秒
注意:此说只是理论
则可以开启子线程分担耗时操作,最好不多于5条
子线程中不能更新UI(除了进度条 progressBar.setProgress())

1、android的线程使用原则
线程不能随便开启
1、线程可控性差;
2、线程会消耗系统性能;
主线程不能进行耗时操作(原因#ANR)且有明确规定(3.0之后,网络请求必须写在子线程中否则会报错 NetWorkOnMainThreadException)

2、Handler的使用 os包
先在主线程中声明
Handler handler = new Handler() {
//接收此handler对象收的信
public void handleMessage(android.os.Message msg) {
int what = msg.what;
if(what==250) {
Bitmap bitmap = (Bitmap)msg.obj;
imageView.setImageBitmap(bitmap);
}
};
};
在子线程中设置Message,并通过handler发送回主线程
Message message = new Message();
message.what = 250; // what是一个携带int的常量,不影响接收
message.arg1 = 100; //属性并不需要全部都写
// message.arg2 = 998;
message.obj = bitmap; //对象不能过大
handler.sendMessage(message); //发送到声明handler的方法内

2、异步任务 AsyncTask
AsyncTask较传统的线程不同的是,在安卓中,使用的是线程加handle结合的一个类
使用一异步任务,不要自己再写handler message,直接在异步任务类的指定方法中进行UI的更
新。
* 异步任务在使用过程的注意事项
* 1、创建异步任务对象,必须在主线程
* 2、异步任务对象只能使用一次
* 3、对象正在执行时,不能再次开启
* 4、异步任务对象开启方法只能在主线程中执行
* 5、不能手动调用异步任务的四个方法
开启异步任务
new MyTask().execute(path); //可变参数(String[])


/**
* 1、创建一个类继承AsyncTask
* 2、填充泛型<Object>
* 泛型1,一般是网址String;泛型2:进度类型Integer;泛型3:结果,不固定(此处Bitmap)
* 3、实现方法
* 通常实现四个方法,开启异步任务时,下面的方法依次进行
*/
class MyTask extends AsyncTask<String, Integer, Bitmap>{
@Override
protected void onPreExecute() {
// 开启异步任务第一个执行的方法
// 在此方法进行准备工作,例如,集合初始化,Dialog弹出提示框,此方法在主线程中执行
super.onPreExecute();
}
@Override
protected Bitmap doInBackground(String... params) {
// 此方法当onPreExecute执行完毕之后主动调用
// 也是异步任务的核心所在,执行在子线程中,可以进行耗时操作
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
// 此方法不会主动调用,但是可以在doInBackground中调用publishProgress调用
// 此方法执行在主线程中
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Bitmap result) {
// 在doInBackGround之后调用,并获取其return的值
// 也是最后一个执行的方法,执行在主线程中,可以进行UI更新
super.onPostExecute(result);
}
}

3、关闭一个正在下载的异步任务
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
mTask.cancel(true);//mayInterruptIfRunning
/**
* true 尝试去关闭正在运行 的线程 暴力关闭
* flase 不去尝试,都能实现不再调用onPostExecute(); 柔和关闭
*/
return super.onKeyDown(keyCode, event);
}
在AsyncTask中重写:
@Override
protected void onCancelled(List<Bitmap> result) {
// 如果调用调用异步任务的cancel方法,关闭后回调此方法,在此可以给用户一些提示
super.onCancelled(result);
if( isCancelled() ) {
Toast.makeText(MainActivity.this, "关闭异步任务了", Toast.LENGTH_SHORT).show();
}
}

四、ListView的使用

#在异步任务中设置局部变量,将外部需要改变的控件传入,即可在异步任务中修改控件值

1、Adapter
ArrayAdapter
SimpleAdapter
BaseAdapter
SimpleCursorAdapter
PagerAdapter
……
2、ListView extends AdapterView
A view that shows items in a vertically scrolling list. The items come from the  ListAdapter  associated with this view.
android:entries 直接添加一个数据
android:divider 在item之间的间隔
android:dividerHeight 间隔高度
android:footerDividersEnabled 是否有足部间隔 false->无
android:headerDividersEnabled 是否有头部高度 false->无

使用 android:entries填充数据,数据固定,不容易动态操作

3、ListView配合三要素显示,并且添加头视图,足视图,空视图
头视图足视图不一定必要添加 空视图都必要添加
//添加 头视图和足视图
//直接显示最为重要的内容
// view的来源1 :创建一个ImageView控件
ImageView imageView = new ImageView(this);
// 动态创建控件的宽高
// LayoutParams是一个包装类,布局参数, 导包时 ,看设置本属性的控件 要添加到的控件的类型
imageView.setLayoutParams( new AbsListView .LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT,
AbsListView.LayoutParams.WRAP_CONTENT)); //也可以直接写常量值
imageView.setImageResource(R.drawable.ic_launcher);
imageView.setScaleType(ScaleType.FIT_XY);

listView.addHeaderView(imageView); // 添加头视图的方法

//添加足视图 显示广告
Button button = new Button(this);
button.setLayoutParams( new LayoutParams ( LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT) );
button.setText("加载更多");
listView.addFooterView(button);
// 空视图 的主要作用,自动显示隐藏,当添加对象没有数据,显示,有数据时会隐藏(同时隐藏显示头足视图)
//view的来源2 :直接将布局文件转化成View
//from(Context)相当于实例化,inflate方法 参数1,要转化的布局,参数2,父布局视图
View view = LayoutInflater .from(this).inflate(R.layout.emptyview, (ViewGroup) listView.getParent());
// 把以上三个操作写在setAdapter之上
listView.setAdapter(adapter);

4、ListView结合SimpleAdapter使用
本地数据的图文混排,而且数据一般是来源于本地,且 只能对CheckBox,ImageView TextView进行绑定
SimpleAdapter :
参数1:context;
参数2:数据;list中放map
参数3:一个样式布局;
参数4:数据来源(map的key);
参数5:数据添加到哪里(对应样式布局中的控件的id); 参数4 参数5的顺序一一对应

for (int i = 1; i <= 7; i++) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", "吴迪" + i);
map.put("imgId",
getResources().getIdentifier("p" + i, "drawable",
getPackageName()));
data.add(map);
}
//SimpleAdapter simpleAdapter = new SimpleAdapter(context, data, resource, from, to);
SimpleAdapter simpleAdapter = new SimpleAdapter(this, data,
R.layout.item_layout, new String[] { "imgId", "name" },
new int[] { R.id.imageView, R.id.txt });

5、SimpleAdapter与ViewBinder结合使用
ViewBinder:在外部给控件赋值, 只能使用在SimplAdapter,SimpCursorAdapter
simpleadapter加载外部(网络)资源,使用ViewBinder
simpleAdapter.setViewBinder(new ViewBinder() {
public boolean setViewValue(View view, Object data,
String textRepresentation) {
//参数1,控件本身,参数2,map中的对应的数据,参数3 安全数据(永远不会为空)
if(view instanceof TextView) {
……
}
return true; //返回true,则不通过数据源填充数据
}
});
listView.setOnItemClickListener(new OnItemClickListener()……;
监听:
// 方法3在ViewGroup中取值 推荐(当使用ViewBinder改变数据后,监听中不能在数据源中取值了)
String txt = null;
View view2 = ((ViewGroup) view).getChildAt(1);
if (view2 instanceof TextView) {
TextView textView = (TextView) view2;
txt = textView.getText().toString();
}

6、ListView结合BaseAdapter使用
1、listview优化
(初始化后,第二次加载item时(移除第几个)时,convertView不为空)
1、ListView写成固定长宽,防止多次调用加载
2、(自身优化,默认只加载一屏幕大小)
3、复用convertView
4、自定义ViewHolder,防止重复查找控件
2、实现完全自定义Adapter
优势:能实现完全自定义
缺点:实现起来复杂
注意:
getCount添加非空判断,getView需要return convertView getItem,建议改返回值类型



五、ListView的优化

##listview比较有用的属性
         android:cacheColorHint="#00000000"  //设置拖动背景色为透明  
         android:dividerHeight="30px"         //listview item之间的高度
         android:divider="@drawable/ic_launcher"    //listview item之间的背景或者说是颜色
         android:fadingEdge="vertical"         //上边和下边有黑色的阴影      值为none的话就没有阴影
        android:scrollbars="horizontal|none"   //只有值为horizontal|vertical的时候,才会显示滚动条,并且会自动影藏和显示
        android:fastScrollEnabled="true"        //快速滚动效果,配置这个属性,在快速滚动的时候旁边会出现一个小方块的快速滚动效果,自动隐藏和显示,
        android:scrollbarStyle="outsideInset"  //四个值的含义如下
        1>outsideInset :  该ScrollBar显示在视图(view)的边缘,增加了view的padding. 如果可能的话,该ScrollBar仅仅覆盖这个view的背景.
        2>outsideOverlay :  该ScrollBar显示在视图(view)的边缘,不增加view的padding,该ScrollBar将被半透明覆盖
        3>insideInset :该ScrollBar显示在padding区域里面,增加了控件的padding区域,该ScrollBar不会和视图的内容重叠.
    

    4>insideOverlay : 该ScrollBar显示在内容区域里面,不会增加了控件的padding区域,该ScrollBar以半透明的样式覆盖在视图(view)的内容上.

首先是 stackFromBottom属性 ,这只该属性之后你做好的列表就会显示你列表的最下面,值为true和false
android :stackFromBottom="true"  
         
第二是 transciptMode属性 ,需要用ListView或者其它显示大量Items的控件实时跟踪或者查看信息,并且希望最新的条目可以自动滚动到可视范围内。通过设置的控件transcriptMode属性可以将Android平台的控件(支持ScrollBar)自动滑动到最底部。
android:transcriptMode="alwaysScroll"   

第三 cacheColorHint属性 ,很多人希望能够改变一下它的背景,使他能够符合整体的UI设计,改变背景背很简单只需要准备一张图片然后指定属性 android:background="@drawable/bg",不过不要高兴地太早,当你这么做以后,发现背景是变了,但是当你拖动,或者点击list空白位置的时候发现ListItem都变成黑色的了,破坏了整体效果。
如果你只是换背景的颜色的话,可以直接指定android:cacheColorHint为你所要的颜色,如果你是用图片做背景的话,那也只要将android:cacheColorHint指定为透明(#00000000)就可以了

第四 divider属性 ,该属性作用是每一项之间需要设置一个图片做为间隔,或是去掉item之间的分割线
android:divider="@drawable/list_driver"  其中  @drawable/list_driver 是一个图片资源,如果不想显示分割线则只要设置为android:divider="@drawable/@null" 就可以了

第五 fadingEdge属性 ,上边和下边有黑色的阴影
android:fadingEdge="none" 设置后没有阴影了~

第六 scrollbars属性 ,作用是隐藏listView的滚动条,
android:scrollbars="none"与setVerticalScrollBarEnabled(true);的效果是一样的,不活动的时候隐藏,活动的时候也隐藏

第七 fadeScrollbars属性 ,android:fadeScrollbars="true"  配置ListView布局的时候,设置这个属性为true就可以实现滚动条的自动隐藏和显示。

第八 fastScrollEnabled属性  ,
很多开发者不知道ListView列表控件的快速滚动滑块是如何启用的,这里Android开发网告诉大家,辅助滚动滑块只需要一行代码就可以搞定,如果你使用XML布局只需要在ListView节点中加入  android:fastScrollEnabled="true" 这个属性即可,而对于 Java 代码可以通过myListView.setFastScrollEnabled(true); 来控制启用,参数false为隐藏。 还有一点就是当你的滚动内容较小,不到当前ListView的3个屏幕高度时则不会出现这个快速滚动滑块,同时该方法仍然是AbsListView的基础方法,可以在ListView或GridView等子类中使用快速滚动辅助。

第九 drawSelectorOnTop属性
When set to true, the selector will be drawn over the selecteditem. Otherwise the selector is drawn behind the selected item. Thedefault value is false.
android:drawSelectorOnTop="true" 点击某一条记录,颜色会显示在最上面,记录上的文字被遮住,所以点击文字不放,文字就看不到
android:drawSelectorOnTop="false"点击某条记录不放,颜色会在记录的后面,成为背景色,但是记录内容的文字是可见的


1.ListView什么只会在加一屏的数据
2.ListView要写成定值 或者 充满父容器
3.convertView复用
4.ViewHolder类使用,防止多次findViewbyId
一。ListView数据分页展示
触发加载更多数据:
1.点击足视图 Button加载更多
2.ListView闲置状态 ListView滑动底部
必备条件!接口自带分页功能!
//ListView的滚动监听
listView.setOnScrollListener(new OnScrollListener() {
//判断当前状态
//状态改变的收才会调用
/*
* 参数2: scrollState改变后的状态
* 滚动状态
* 抛
* 闲置
* (non-Javadoc)
* @see android.widget.AbsListView.OnScrollListener#onScrollStateChanged(android.widget.AbsListView, int)
*/
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
public static int SCROLL_STATE_IDLE = 0;
public static int SCROLL_STATE_TOUCH_SCROLL = 1;
public static int SCROLL_STATE_FLING = 2;
//到底 并且闲置
if (isBottom && scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
//加载下一页数据
currentPager++;
getDataFromHttp();
}
}
//滚动监听 此方法会频繁调用
/**
* firstVisibleItem: 第一条可见的条目
* visibleItemCount: 可见的总条目
* totalItemCount : 总共的条目
*/
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
isBottom= (firstVisibleItem+visibleItemCount) == totalItemCount;
}
});
二。多套item布局使用
1.BaseAdapter需要额外重写两个方法
getViewTypeCount
getItemViewType(int position)
2.BaseAdapter ViewHolder可能创建多个
3.BaseAdapter getView() 需要判断类型,在进行赋值和convertView使用!
4.多套item布局 数据源一定要进行分类!
1.定义一个标签!
2.根据类型去区分
三。ListView常见问题
1.内部事件处理
现象: 当Item中包含Button,并且做了监听事件!ListView单条点击事件不生效!
原因: Button消费了原本属于Item点击事件!
解决方法:
item的单条布局的最外层 添加一个属性!
android:descendantFocusability="blocksDescendants"
阻止事件,如果点中单条!那么事件不给子控件使用!
四。ExpandableListView

1.继承关系
ListView -- AbsListView -- AdapterView
2.属性
android:childDivider Drawable or color that is used as a divider for children.
android:childIndicator Indicator shown beside the child View.
android:childIndicatorEnd The end bound for a child's indicator.
android:childIndicatorLeft The left bound for a child's indicator.
android:childIndicatorRight The right bound for a child's indicator.
android:childIndicatorStart The start bound for a child's indicator.
android:groupIndicator Indicator shown beside the group View.
android:indicatorEnd The end bound for an item's indicator.
android:indicatorLeft The left bound for an item's indicator.
android:indicatorRight The right bound for an item's indicator.
android:indicatorStart The start bound for an item's indicator.
3. 指示器的状态图片 state_expanded 是否是展开状态
<item android:drawable="@drawable/bottom" android:state_expanded="true"></item>
<item android:drawable="@drawable/right"></item>
4. ExpandableListView使用特定的Adapter
BaseExpandableListAdapter
5. ExpandableListView需要数据类型的问题
组 的数据 List<String>
子 的数据 List<List<String>>



六. ExpandableListView的监听事件
(1).修改Adapter返回值
覆写BaseExpandableListAdapter的isChildSelectable()的返回值为true;
(2).绑定监听器
调用ExpandableListView对象的setOnChildClickListener()方法,为其绑定监听器
listView.setOnChildClickListener(new OnChildClickListener() {@Overridepublic boolean onChildClick(ExpandableListView parent, View v,int groupPosition, int childPosition, long id) {Intent intent = new Intent(getActivity(), PlayActivity.class);intent.setData(Uri.parse(adapter.getList().get(groupPosition).videos.get(childPosition).url));startActivity(intent);return true;}});

七、lrucache工具类:

八、GridView extends AbsListView
显示需要三要素,相当于多行的listview
一行中有一列的gridview,相当于listview
使用和listview是完全一样的
setOnItemClickListener();

android:numColumns="3" 一行有几列
列数不建议写固定的值 总体适配效果不好
auto_fit 自适应,调整列数,配合下一个属性使用
android:columnWidth="90dp" 每列有多宽
android:horizontalSpacing="" 水平间隙
android:verticalSpacing="" 垂直间隙








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值