android高级控件
目标内容:1、ListView列表控件 2、自定义适配器Adapter 3、ListView 4、ListView实现图文混排 5、ListView集合网络HTTP操作
*强调一下线性布局,水平时,左右对其生效!垂直时,上下对其生效!
GridView组件;以网格方式排列视图,与矩阵类似(相册)
android:numColums = "auto_fit";//最大的列数(自动分配)
android:verticalSpacing = "10dp";//列与列之间的间隙
android:horizontalSpacing = "10dp";//行与行之间的间隙
android:columnWidth = "90dp";每一列的列宽定成90dp,那么不管显示多大的图片或文件都是这么宽
android:stretMode="columnWidth";//缩放拉伸与列宽大小同步
1、ListView列表控件(android最重要的控件)———Item:条目
- 是一个视图组,用于展示列表的数据;在复杂控件中(Composite)
- MVC架构
- M:模型层 —- javaBean —- personList(personList是存储person对象的集合)
- V:视图层 —- jsp —-ListView
- C:控制层 —- servlet —-Adapter
- 适配器
adapter = new ArrayAdapter<String>(Context,textViewResourceId,Objects); //Context通常是上下文,用MainActivity.this; //textViewResourceId是选择样式,通常用android。R.layout.simple_list_item_multiple_choice;设置多选,跟下面listview设置的多选相对应。 //Objects表示对象,即内容对象!这里面是一个集合,可以自己写的获取集合的方法;也可以从资源文件里面找自己写在xml文件中的资源 //设置listView的选中模式listView.setChoiceMode(choiceMode); listView.setChoiceMode(listView.CHOICE_MODE_MULTIPLE);//多选模式,可以设置单选CHOICE_MODE_SINGLE
- ListView事件
listView.setOnItemClickListener(new OnItemClickListener(){});
adapter.notifyDataSetChanged();一旦适配器有数据就通知listView更新数据
BaseAdapter自定义适配器
class MyAdapter extends BaseAdapter{
//必须定义的方法;系统调用;获取listView中有多少元素
@Override
public int getCount(){
//return 50;
//return listView.size();
}
//必须定义的方法;由系统调用,获取一个View对象,作为ListView的条目;ListView的每个条目都是View对象
@Override
public int getView(int position,View convertView,ViewGroup parent){
//position:本次getView方法调用所返回的View对象,在listView中是处于第几个条目,那么position就等于几,从0开始
TextView tv =new TextView(MainActivity.this);//所有控件都是View的子类,创建什么都行
Person p =personList.get(position);
tv.setText(p.toString());
tv.setTextSize(18);
return tv;
}
@Override
public int getItem(){
return null;
}
@Override
public int getItemId(){
return 0;
}
}
ListView对象的填充:只要是view都能用ListView来填充;
- 代码写布局适用于界面的微调,而整体设计布局用布局文件来做
- 把每个条目都当成一个View,并写一个布局文件:buju.xml,就完成了布局嵌套;
把布局文件填充成一个View对象
- 三种填充写法:
- 第一种:View v = View.inflate(MainActivity.this,R.layout.buju,null);
- 第二种:获取布局填充器对象
-
LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
//使用布局填充器填充布局文件
View v2 = inflater.inflate(R.layout.Item_listview,null); - 第三种:
//getSystemService();获取很多的系统管理器 LayoutInflater inflater2 = (LayoutInflater)getSystemService(LAOUT_INFLATER_SERVICE);
//案例代码: class MyAdapter extends BaseAdapter{ //必须定义的方法;系统调用;获取listView中有多少元素 @Override public int getCount(){ //return 50; //return listView.size(); } //必须定义的方法;由系统调用,获取一个View对象,作为ListView的条目;ListView的每个条目都是View对象 @Override public int getView(int position,View convertView,ViewGroup parent){ //position:本次getView方法调用所返回的View对象,在listView中是处于第几个条目,那么position就等于几,从0开始 Person p =personList.get(position); //把布局文件填充成一个View对象 View v = View.inflate(MainActivity.this,R.layout.buju,null); //findViewById前面用v对象,否则默认找的是主Activity界面了 TextView tv_name = (TextView)v.findViewById(R.id.tv_name); return v; } @Override public int getItem(){ return null; } @Override public int getItemId(){ return 0; } }
ListView优化
- 以上代码是,向上、向下滚动就重新新建了view,而没有使用缓存技术
public int getView(int position,View convertView,ViewGroup parent){}中的convertView就是缓存
//代码改进
class MyAdapter extends BaseAdapter{
//必须定义的方法;系统调用;获取listView中有多少元素
@Override
public int getCount(){
//return 50;
//return listView.size();
}
//必须定义的方法;由系统调用,获取一个View对象,作为ListView的条目;ListView的每个条目都是View对象
@Override
public int getView(int position,View convertView,ViewGroup parent){
//position:本次getView方法调用所返回的View对象,在listView中是处于第几个条目,那么position就等于几,从0开始
Person p =personList.get(position);
View v = null;
//判断条目是否有缓存
if(convertView == null){
//把布局文件填充成一个View对象
v = View.inflate(MainActivity.this,R.layout.buju,null);
}else if(){
v = convertView;
}
//findViewById前面用v对象,否则默认找的是主Activity界面了
TextView tv_name = (TextView)v.findViewById(R.id.tv_name);
return v;
}
@Override
public int getItem(){
return null;
}
@Override
public int getItemId(){
return 0;
}
}
理解每一个参数代表什么!不能死记!!!!
ArrayAdapter :数组适配器
- 传的参数是一个String[] 数组,所以当需求是只处理一种数据时,推荐使用这个;并且ArrayAdapter只能处理一种数据。
- ArrayAdapter adapter = new ArrayAdapter(this,R.layout.zidingyibuju,R.id.tv_name,String[]);
SimpleAdapter:简单适配器
比ArrayAdapter强大一点,传的参数是一个List
ListView和ScrollView冲突
public boolean dispatchTouchEvent(MotionEvent ev) {
if(ev.getAction() == MotionEvent.ACTION_MOVE){
//先让哪个控件先执行,//就设置直接调用哪个
listView.dispatchTouchEvent(ev);
}
if(is_scroll_move){
scrollView.dispatchTouchEvent(ev);
}
return super.dispatchTouchEvent(ev);
}
启动activity的OnCreate中设置:
Private Boolean is_move;
Private Boolean is_scroll_move;
listView.setOnScrollListener(new OnScrollListener()){
public void onScrollStateChanged(AbsListView view,int scrollState ){
if(is_move && ScrollState==OnScrollListener.SCROLL_STATE_IDLE)
//表示用户从ListView滑动到底端
is_scroll_move =true;
}
public void onScroll(AbsListView view,int firstVisibleItem,int visibleItemCount,int totalItemCount){
is_move = (firstVisibleItem + visibleItemCount == totalItemCount);
}
});