您的位置:首页 > 产品设计 > UI/UE

扣丁学堂笔记第05天高级UI组件(一)

2016-03-21 18:22 176 查看
1.GridVIew

GridVIew常用属性与自定义适配器

常用属性

android:numColumns="auto_fit"列数设置为自动

android:columnWidth="90dp"每列的宽度,即item的宽度

android:stretchMode="columnWidth"缩放与列宽大小同步

android:verticalSpacing="10dp"两行之间的边距

android:horizontalSpacing="10dp"两列之间的边距

自定义适配器

在MainActivity.java中自定义一个适配器继承自BaseAdapter,static class MyAdapter extends BaseAdapter{},(注:这里之所以用static修饰,是因为内部类优先考虑定义成静态类,这样子相当于外部类,它不依赖于外部的对象,因而效率更高。)然后重写四个方法getCount()、getItem()、getItemId()、getView()。

定义一个整型数组来存放图片资源的id:int[] images = {R.drawable.p0,...,...};然后getCount()返回的是images.lenght; getItem()返回的是images[position]; getItemId()返回的是Position;

重点关注的是getView()方法。先在MyAdapter类中添加代码:private Context context;public MyAdapter(Context context){this.context = context;} 然后创建一个ImageView:ImageVIew iv = new ImageView(context); 然后调用setImageResoure()方法,参数images[position]; 然后return iv。

最后加载适配器.gridView.setAdapter(new MyAdapter(this));

GridView图文排列

简单的图片排列



MainActivity.java

package com.example.gridviewtest;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;

public class MainActivity extends Activity {

private GridView gridView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView = (GridView) findViewById(R.id.gridView1);
gridView.setAdapter(new MyAdapter(this));
}

static class MyAdapter extends BaseAdapter{

int[] images = {R.drawable.sample_0,
R.drawable.sample_1,
R.drawable.sample_2,
R.drawable.sample_3,
R.drawable.sample_4,
R.drawable.sample_5,
R.drawable.sample_6,
R.drawable.sample_7,
R.drawable.sample_0,
R.drawable.sample_1,
R.drawable.sample_2,
R.drawable.sample_3,
R.drawable.sample_4,
R.drawable.sample_5,
R.drawable.sample_6,
R.drawable.sample_7,};

private Context context;
public MyAdapter(Context context){
this.context = context;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return images.length;
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return images[position];
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ImageView iv = new ImageView(context);
iv.setImageResource(images[position]);

return iv;
}

}

}


activity_main.xml

<GridView
android:id="@+id/gridView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:gravity="center"
android:columnWidth="90dp"
android:horizontalSpacing="10dp"
android:verticalSpacing="10dp"
android:stretchMode="columnWidth"

android:numColumns="auto_fit" >
</GridView>


图文排列



实现代码基本同上,多定义一组字符串数组用来显示文字,返回的名称可以是图片的名称,也可以是文字的名称

在getView()方法里,因考虑到效率问题,本次不采用new一个ImageView和TextView的方法。在layout文件夹中新建一个item.xml文件,添加ImageView和TextView组件

在getView()方法里添加代码:LayoutInflater inflater = LayoutInflater.from(context); View view = inflater.infalte(R.layout.item,null);

然后通过view.findViewById()实例化ImageView和TextView;

然后调用setImageResource方法和setText方法放置资源文件;

最后返回view。

程序拓展:

可以为每个视图设置点击事件,setOnItemClickListener(new AdapterView.OnItemClickListener());其中onItemClick的四个参数:parent表示GridView,view表示item.xml中的布局LinearLayout,position表示位置,id表示编号

MainActivity.java代码

package com.example.gridviewtest2;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

private GridView gridView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

gridView = (GridView) findViewById(R.id.gridView1);
gridView.setAdapter(new MyAdapter(this));
gridView.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, "parent="+parent, Toast.LENGTH_SHORT).show();
}
});
}

static class MyAdapter extends BaseAdapter{

String[] names={"Android1","Android2","Android3","Android4","Android5","Android6","Android7","Android8"};
int[] images = {R.drawable.ic_launcher,
R.drawable.ic_launcher,
R.drawable.ic_launcher,
R.drawable.ic_launcher,
R.drawable.ic_launcher,
R.drawable.ic_launcher,
R.drawable.ic_launcher,
R.drawable.ic_launcher};

private Context context;
public MyAdapter(Context context){
this.context = context;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return names.length;
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return names[position];
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}

@Override
public View getView(int position, View view, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater = LayoutInflater.from(context);
View view1 = inflater.inflate(R.layout.item, null);
ImageView iv = (ImageView) view1.findViewById(R.id.imageview);
TextView tv = (TextView) view1.findViewById(R.id.textview);
iv.setImageResource(images[position]);
tv.setText(names[position]);

return view1;
}

}

}


activity_main.xml

<GridView
android:id="@+id/gridView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:numColumns="3"
android:horizontalSpacing="10dp"
android:verticalSpacing="10dp"
android:stretchMode="columnWidth"
android:columnWidth="60dp"
android:gravity="center" >
</GridView>


item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<ImageView
android:id="@+id/imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
></ImageView>
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

</LinearLayout>


2.ListView

ListView是安卓中最常用的一种视图组件,它以垂直列表的方式列出需要显示的列表项

ListView基本属性配置

android:cacheColorHint="#00000000"设置拖动背景为透明

android:dividerHeight="30px"item之间的高度

android:divider="@drawable/ic_launcher"item之间的背景或者说是颜色

android:fadingEdge="vertical"上边和下边有黑色的阴影,值为none就没有阴影

android:drawSelectorOnTop="false"点击某条记录不放,颜色会在记录的后面,成为背景色

android:scrollbars="horizontal|vertical"显示滚动条,并且会自动显示和隐藏

android:fastScrollEnable="true"快速滚动

android:listSelector="@color/pink"item选中时的颜色

android:entries="@array/citys"设置列表填充的内容

ListView_ListActivity和单选多选

ListActivity(继承Activity)提供了一个列表项的视图来显示数据,可以绑定指定的数据源。ArrayAdapter arrayAdapter = ArrayAdapter.createFromResource(this,R.array.name,android.R.layout.simple_list_item_1);

重写onListItemClick方法:Toas.makeText(this,(ListView)v.getText(),Toast.LENGTH_SHOW).show();

单选和多选模式

先在values写好一个array.xml资源文件,通过getResources()的getStringArray来绑定array资源,类型类String数组;

创建一个ArrayAdapter适配器实例(单选布局文件为android.R.layout.simple_list_item_single_choice,多选为android.R.layout.simple_list_item_multiple_choice),调用它的setChoiceMode方法(单选为ListView.CHOICE_MODE_SINGLE,多选为ListView.CHOICE_MODE_MULTIPLE).

arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="names">
<item>贝贝1</item>
<item>贝贝2</item>
<item>贝贝3</item>
<item>贝贝4</item>
<item>贝贝5</item>
<item>贝贝6</item>
<item>贝贝7</item>
<item>贝贝8</item>
<item>贝贝9</item>
<item>贝贝10</item>
<item>贝贝11</item>
</array>
</resources>


MainActivity.java

private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView1);

String[] arr = getResources().getStringArray(R.array.names);
//        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_single_choice,arr);
//        listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
//        listView.setAdapter(arrayAdapter);
//
ArrayAdapter<String> arrayAdapter1 = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice,arr);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setAdapter(arrayAdapter1);
}


ListView_SimpleAdapter

使用SimpleAdapter建立复杂的列表项

SimpleAdapter(Context context,List<? extends Map<String,?>> data,int resource,String[] from,int[] to)

参数:

context:SimpleAdapter关联的view运行的环境;

data:一个Map组成的List。在列表中的每个条目对应列表中的一行,每一个map中应包含所有在from参数中指定的键;

resource:一个定义列表项的布局文件的资源ID,布局文件中至少应包含在to中定义了的ID。

from:一个将被添加到map映射的键名;

to:将绑定的数据视图的ID,跟from参数对应,这里应该全是TextView。

1.准备数据,每个HashMap是一条记录

HashMap<String, String> title1 = new HashMap<>();

title1.put("title","title--1");

HashMap<String, String> title2 = new HashMap<>();

title2.put("title","title--2");

......(title3,4,5,6)

ArrayList<Map<String,String>> list = new ArrayList<>();

list.add(title1);

list.add(title2);

......(title3,4,5,6)

2.把数据填充到Adapter

SimpleAdapter sa = new SimpleAdapter(this,list,R.layoutlist_.item(自定义的布局文件),new String[]{"titlle"},new int[]{R.id.textView_title}(自定义textView组件的id) );

listView.setAdapter(sa);

SimpleAdapter补充

把上文HashMap<>改为HashMap<String,Object>后,不仅可以存放字符串还可以存放图片资源

title1.put("icon",R.drawable.icon);

SimpleAdapter sa = new SimpleAdapter(this,list,R.layoutlist_.item(自定义的布局文件),new String[]{"titlle","icon"},new int[]{R.id.textView_title,R.id.imageView_icon});

MainActivity.java

package com.example.simpleadaptertest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class MainActivity extends Activity {

private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView1);

HashMap<String, Object> data1 = new HashMap<String, Object>();
data1.put("icon", R.drawable.ic_launcher);
data1.put("info", "我是内容1");
HashMap<String, Object> data2 = new HashMap<String, Object>();
data2.put("icon", R.drawable.ic_launcher);
data2.put("info", "我是内容2");
HashMap<String, Object> data3 = new HashMap<String, Object>();
data3.put("icon", R.drawable.ic_launcher);
data3.put("info", "我是内容3");
HashMap<String, Object> data4 = new HashMap<String, Object>();
data4.put("icon", R.drawable.ic_launcher);
data4.put("info", "我是内容4");

ArrayList<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
list.add(data1);
list.add(data2);
list.add(data3);
list.add(data4);

SimpleAdapter sa = new SimpleAdapter(this, list, R.layout.list_item,
new String[]{"icon","info"},new int[]{R.id.iv_images,R.id.tv_info});

listView.setAdapter(sa);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}


activity_man.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.simpleadaptertest.MainActivity" >

<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ListView>

</RelativeLayout>


list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ImageView
android:id="@+id/iv_images"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/tv_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>


ListView_自定义适配器

使用BaseAdapter实现更加灵活的列表

由于BaseAdapter是一个抽象类,因此需要自己写一个类继承它

public int getCount()

public Object getItem(int position)

public long getItemId(int position)

public View getView(int position,View convertView,ViewGroup parent)

具体代码:

创建一个MyAdapter继承BaseAdapter实现其4个方法,定义一个字符串数组和一个整型数组用来存放文字和图片资源。getCount返回titles.length,getItem返回titles[position],getItemId返回position,重点是getView方法。

这里需要一个构造方法(因为需要用它来实例化LayoutInflater),private Context context; public My Adapter(Context context){this.context = context;}

在getView方法添加代码:

LayoutInflater inflater = LayoutInflater.from(context);

View view = inflater.inflate(R.layout.list_item,null);

通过view的FindViewById实例化textView和imageView;

然后调用setText和setImageResource方法加载资源;

最后return view。

MainActivity.java代码

package com.example.baseadaptertest;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {

private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView1);
listView.setAdapter(new MyAdapter(this));
}

static class MyAdapter extends BaseAdapter{

int[] icons = {R.drawable.ic_launcher,
R.drawable.ic_launcher,
R.drawable.ic_launcher,
R.drawable.ic_launcher,
R.drawable.ic_launcher,
R.drawable.ic_launcher};
String[] titles = {"我是标题1","我是标题2","我是标题3","我是标题4",
"我是标题5","我是标题6",};
String[] infos = {"我是内容1","我是内容2","我是内容3","我是内容4",
"我是内容5","我是内容6",};

private Context context;
public MyAdapter(Context context){
this.context = context;
}
public int getCount() {
// TODO Auto-generated method stub
return titles.length;
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return titles[position];
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.list_item, null);
ImageView iv = (ImageView) view.findViewById(R.id.img);
TextView title = (TextView) view.findViewById(R.id.title);
TextView info = (TextView) view.findViewById(R.id.info);
iv.setImageResource(icons[position]);
title.setText(titles[position]);
info.setText(infos[position]);
return view;
}

}

}


activity_main.xml

<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ListView>


list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >

<ImageView
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"/>
<TextView
android:id="@+id/info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"/>

</LinearLayout>
</LinearLayout>


ListView_使用convertView优化对象的创建

重复使用convertView

public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if(convertView == null){
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.list_item, null);
}

System.out.println(position+"--------"+convertView);

ImageView iv = (ImageView) convertView.findViewById(R.id.img);
TextView title = (TextView) convertView.findViewById(R.id.title);
TextView info = (TextView) convertView.findViewById(R.id.info);
iv.setImageResource(icons[position]);
title.setText(titles[position]);
info.setText(infos[position]);
return convertView;
}


ListView_ViewHolder优化

使用ViewHolder提供在容器中查找组件的效率

实现步骤:

创建一个ViewHolder类,用于保存第一次查找的组件,避免下次重复查找;

在if语句中new一个ViewHolder对象,再实例化组件后定义为viewHolder.tv_icon;再添加convert.setTag(viewHolder);

如果convertView不为空,viewHolder = (ViewHolder)convertView.getTag();

viewHolder.tv_title.setText(titles[position]);

public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder viewHolder;
if(convertView == null){
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.list_item, null);
viewHolder = new ViewHolder();
viewHolder.iv = (ImageView) convertView.findViewById(R.id.img);
viewHolder.title = (TextView) convertView.findViewById(R.id.title);
viewHolder.info = (TextView) convertView.findViewById(R.id.info);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}

viewHolder.iv.setImageResource(icons[position]);
viewHolder.title.setText(titles[position]);
viewHolder.info.setText(infos[position]);
return convertView;
}


static class ViewHolder{
ImageView iv;
TextView title;
TextView info;
}


ListView刷新分页

新建一个News外部类,定义title和context变量;

在MainActivity中定义一个初始化数据方法:private void initData(),先在外部定义一个index,然后再initData方法里添加一个for循环(先在方法外new一个类为News名称为news的Vector容器),在for循环里添加代码:News n = new News(); n.title = "title--"+index; n.context ="context--"+index; index++; news.add(n);

在onCreate()添加代码:initData();

新建一个MyAdapter继承自BaseAdapter,实现其4个方法,getCount返回news.size()(news的总数); getItem返回news.get(position); getItemId返回position;getView方法采用ViewHolder优化的代码,注意viewHolder.tv_title.setText(n.title)之前要加一句代码:News n = news.get(position);

News.java

package com.example.myadapterdemo;

public class News {
String title;
String context;
}


MainActivity.java

package com.example.myadapterdemo;

import java.util.Vector;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {

private ListView listView;
private Vector<News> news = new Vector<News>();
private MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView1);
initData();
adapter = new MyAdapter();
listView.setAdapter(adapter);

}

private int index = 1;
private void initData(){
for(int i=0;i<10;i++){
News n = new News();
n.title = "title--"+index;
n.context = "context"+index;
index++;
news.add(n);
}
}

class MyAdapter extends BaseAdapter{

//    	private Context context;
//    	public MyAdapter(Context context){
//    		this.context = context;
//    	}

@Override
public int getCount() {
// TODO Auto-generated method stub
return news.size();
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return news.get(position);
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder vh;
if(convertView==null){
//				LayoutInflater inflater = LayoutInflater.from(context);
//				convertView = inflater.inflate(R.layout.list_item, null);
convertView = getLayoutInflater().inflate(R.layout.list_item, null);
vh = new ViewHolder();
vh.textView = (TextView)convertView.findViewById(R.id.tv_title);
vh.textView2 = (TextView) convertView.findViewById(R.id.tv_content);
convertView.setTag(vh);
}else{
vh = (ViewHolder) convertView.getTag();
}
News n = news.get(position);
vh.textView.setText(n.title);
vh.textView2.setText(n.context);
return convertView;
}

class ViewHolder{
TextView textView;
TextView textView2;
}
}
}


activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.myadapterdemo.MainActivity" >

<ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" > </ListView>

</RelativeLayout>


list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>

</LinearLayout>


调用listView的addFooterView方法为列表添加加载数据提示

首先新建一个loading的xml文件,添加一个小的进度条和一个小的textview;

然后在onCreate添加代码:View footerView = getLayoutInflater().inflate(R.layout.loading,null);addFooterView传入footerView参数;

loading.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">

<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@android:attr/progressBarStyleSmall"/>

<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="正在玩命加载中..."
android:textAppearance="?android:attr/textAppearanceSmall" />

</LinearLayout>


MainActivity.java

View footerView = getLayoutInflater().inflate(R.layout.loading, null);
listView.addFooterView(footerView);


创建一个线程,再次加载一遍数据

class loadDataThread extends Thread{
@Override
public void run() {

initData();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
adapter.notifyDataSetChanged();//这句会报错,因为子线程不能直接访问UI线程的组件
}
}


让MainActivity实现onScrollListener监听事件,重写两个方法,onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)和onScrollStateChanged(AbsListView view, int scrollState)。先定义一个可视的最后一个item的索引:visibleLastIndex,在onScroll方法添加代码:visibleLastIndex
= firstVisibleItem+visibleItemCount-1;然后再onScrollStateChanged方法添加代码:if(adapter.getCount()==visibleLastIndex&&scrollState==SCROLL_STATE_IDLE){ new loadDataThread().start(); }

为了解决线程之间的通信问题,引入了Handler机制:先定义一个静态的常整型变量DATE_UPDATE,在子线程中发送此标记提醒主线程,子线程已完成更新操作,这里新建一个Handler对象,重写它的handleMessage方法:使用switch语句,如果case DATE_UPDATE,调用notifyDataSetChanged方法。

private int visibleLastIndex;
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
visibleLastIndex = firstVisibleItem+visibleItemCount-1;

}

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(adapter.getCount()==visibleLastIndex&&scrollState==SCROLL_STATE_IDLE){
new loadDataThread().start();
}

}


class loadDataThread extends Thread{
@Override
public void run() {

initData();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//    		adapter.notifyDataSetChanged();
//通过handler给主线程发送一个标记
handler.sendEmptyMessage(DATE_UPDATE);
}
}


private static final int DATE_UPDATE = 0x1;//十六进制的一


//线程之间通信的机制Handler
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch(msg.what){
case DATE_UPDATE:
adapter.notifyDataSetChanged();
break;
}
};
};


由于是采用实现接口的方式,别忘了在onCreate方法添加listView.setOnScrollListener(this);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: