ListView分页功能(2) 自定义View实现分页功能
2016-07-16 08:00
381 查看
ListView分页功能(2) 自定义View实现分页功能
(1)自定义View 继承ListView实现OnScrollListener;
(2)设置一个回调接口,用于客户加载数据, 客户实现这个接口
(3)提供一个方法,通知数据加载完成
(3) 通过onScroll()和onScrollStateChanged()判断是否滑到底部,
进行加载新数据。
自定义ListView:
package com.example.listviewpagedemo;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.LinearLayout;
import android.widget.ListView;
public class MyListView extends ListView implements OnScrollListener{
private LinearLayout footLayout;
private boolean isLoading;//加载完成了
private int bottomIndex = 0;
public MyListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView(context);
}
public MyListView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyListView(Context context) {
this(context, null);
}
/**
* 初始化View
* @param context
*/
private void initView(Context context) {
LayoutInflater inflater = LayoutInflater.from(context);
footLayout = (LinearLayout) inflater.inflate(R.layout.footer, null);
this.addFooterView(footLayout);
//设置监听
this.setOnScrollListener(this);
footLayout.setVisibility(View.GONE);
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
try {
//拉到了最底部,并停止了滚动, 加载新的数据
if(isBottom && scrollState == SCROLL_STATE_IDLE){
if(!isLoading){
Log.i("tag", "onScrollStateChanged>>>isbottom");
footLayout.setVisibility(View.VISIBLE);
//加载新的数据
mListener.onLoad();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
boolean isBottom = false;
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
/**
*拉到了最低端
*/
if(firstVisibleItem + visibleItemCount >= totalItemCount) {
Log.i("tag", "onScroll=-====isBottom = true;");
bottomIndex = firstVisibleItem + visibleItemCount ;
isBottom = true;
}else {
isBottom = false;
}
}
/**
*数据加载完了
*/
public void doComplete() {
footLayout.setVisibility(View.GONE);
isLoading = false;
this.setSelection(bottomIndex);
}
private onLoadListener mListener;
public void setOnLoadListener(onLoadListener mListener) {
this.mListener = mListener;
}
public interface onLoadListener {
public void onLoad();
}
}
MainActivity.java
使用Thread+Handler 加载和更新数据数据
(1)实现自定义Listview中定义的OnLoadListener接口,用于回调加载数据。
(2)创建一个子线程用来加载数据,通过handler发送一个空消息,通知数据
加载完成, handler中使用Adapter.notifyDataChanged() 通知数据更新(footerVie消失)
注意:MyListView 调用doComplete() 通知listview数据加载完了的位置,我第一次是在子线程中调用lv.doComplete() 通知, 但是一直自动闪退,未找到错误,
最后发现使用 是listview设置adapter是在Handler中, 而开始子线程启动时,listview的适配器还未设置,
所以将lv.doComplete() 通知listview数据加载完成放在了Handler中。
package com.example.listviewpagedemo;
import java.util.ArrayList;
import java.util.List;
import com.example.listviewpagedemo.MyListView.onLoadListener;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
public class MainActivity extends Activity implements onLoadListener {
/*
* 底部刷新加载布局
*/
LinearLayout footLayout ;
MyListView lv;
ArrayAdapter<String> adapter;
List<String> datas = new ArrayList<String>();;
boolean isLoadOver = false;
/**
* 加载完了完数据通知根性
*/
Handler handler = new Handler() {
public void handleMessage(Message msg) {
if(msg.what == 1){
if(adapter == null){
adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1,datas);
lv.setAdapter(adapter);
}else {
adapter.notifyDataSetChanged();
}
}
lv.doComplete();
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initView();
initDatas();
}
/**
* 初始化数据
*/
private void initDatas() {
new Thread(new Runnable(){
@Override
public void run() {
try {
Thread.sleep(2000);
//加载数据
for (int i = 0; i < 20; i++) {
datas.add("项目展示" + datas.size());
}
lv.doComplete();
handler.sendEmptyMessage(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
/**
* 初始化view
*/
private void initView() {
lv = (MyListView)findViewById(R.id.listView1);
lv.setOnLoadListener(this);
}
@Override
public void onLoad() {
try {
//加载数据
initDatas();
/*//加载数据
for (int i = 0; i < 20; i++) {
datas.add("项目展示" + datas.size());
}
lv.doComplete();
handler.sendEmptyMessage(1);*/
} catch (Exception e) {
e.printStackTrace();
}
}
}
(1)自定义View 继承ListView实现OnScrollListener;
(2)设置一个回调接口,用于客户加载数据, 客户实现这个接口
(3)提供一个方法,通知数据加载完成
(3) 通过onScroll()和onScrollStateChanged()判断是否滑到底部,
进行加载新数据。
自定义ListView:
package com.example.listviewpagedemo;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.LinearLayout;
import android.widget.ListView;
public class MyListView extends ListView implements OnScrollListener{
private LinearLayout footLayout;
private boolean isLoading;//加载完成了
private int bottomIndex = 0;
public MyListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView(context);
}
public MyListView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyListView(Context context) {
this(context, null);
}
/**
* 初始化View
* @param context
*/
private void initView(Context context) {
LayoutInflater inflater = LayoutInflater.from(context);
footLayout = (LinearLayout) inflater.inflate(R.layout.footer, null);
this.addFooterView(footLayout);
//设置监听
this.setOnScrollListener(this);
footLayout.setVisibility(View.GONE);
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
try {
//拉到了最底部,并停止了滚动, 加载新的数据
if(isBottom && scrollState == SCROLL_STATE_IDLE){
if(!isLoading){
Log.i("tag", "onScrollStateChanged>>>isbottom");
footLayout.setVisibility(View.VISIBLE);
//加载新的数据
mListener.onLoad();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
boolean isBottom = false;
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
/**
*拉到了最低端
*/
if(firstVisibleItem + visibleItemCount >= totalItemCount) {
Log.i("tag", "onScroll=-====isBottom = true;");
bottomIndex = firstVisibleItem + visibleItemCount ;
isBottom = true;
}else {
isBottom = false;
}
}
/**
*数据加载完了
*/
public void doComplete() {
footLayout.setVisibility(View.GONE);
isLoading = false;
this.setSelection(bottomIndex);
}
private onLoadListener mListener;
public void setOnLoadListener(onLoadListener mListener) {
this.mListener = mListener;
}
public interface onLoadListener {
public void onLoad();
}
}
MainActivity.java
使用Thread+Handler 加载和更新数据数据
(1)实现自定义Listview中定义的OnLoadListener接口,用于回调加载数据。
(2)创建一个子线程用来加载数据,通过handler发送一个空消息,通知数据
加载完成, handler中使用Adapter.notifyDataChanged() 通知数据更新(footerVie消失)
注意:MyListView 调用doComplete() 通知listview数据加载完了的位置,我第一次是在子线程中调用lv.doComplete() 通知, 但是一直自动闪退,未找到错误,
最后发现使用 是listview设置adapter是在Handler中, 而开始子线程启动时,listview的适配器还未设置,
所以将lv.doComplete() 通知listview数据加载完成放在了Handler中。
package com.example.listviewpagedemo;
import java.util.ArrayList;
import java.util.List;
import com.example.listviewpagedemo.MyListView.onLoadListener;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
public class MainActivity extends Activity implements onLoadListener {
/*
* 底部刷新加载布局
*/
LinearLayout footLayout ;
MyListView lv;
ArrayAdapter<String> adapter;
List<String> datas = new ArrayList<String>();;
boolean isLoadOver = false;
/**
* 加载完了完数据通知根性
*/
Handler handler = new Handler() {
public void handleMessage(Message msg) {
if(msg.what == 1){
if(adapter == null){
adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1,datas);
lv.setAdapter(adapter);
}else {
adapter.notifyDataSetChanged();
}
}
lv.doComplete();
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initView();
initDatas();
}
/**
* 初始化数据
*/
private void initDatas() {
new Thread(new Runnable(){
@Override
public void run() {
try {
Thread.sleep(2000);
//加载数据
for (int i = 0; i < 20; i++) {
datas.add("项目展示" + datas.size());
}
lv.doComplete();
handler.sendEmptyMessage(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
/**
* 初始化view
*/
private void initView() {
lv = (MyListView)findViewById(R.id.listView1);
lv.setOnLoadListener(this);
}
@Override
public void onLoad() {
try {
//加载数据
initDatas();
/*//加载数据
for (int i = 0; i < 20; i++) {
datas.add("项目展示" + datas.size());
}
lv.doComplete();
handler.sendEmptyMessage(1);*/
} catch (Exception e) {
e.printStackTrace();
}
}
}
相关文章推荐
- Android App中自定义View视图的实例教程
- Android中自定义View实现圆环等待及相关的音量调节效果
- Android开发使用自定义view实现ListView下拉的视差特效功能
- 自定义图表控件--同时显示柱状图和折线图
- android自定义View的用法
- android自定义控件实例
- 自定义view的自定义属性的引用
- 自定义带圆点ViewPager
- android 自定义View onMeasure
- Android中inflate和merge结合使用
- android在自定义View的xml中设置自定义的成员属性
- View与ViewGroup--实现QQ左滑删除
- 自定义android进度条
- android基础之自定义view
- 关于自定义View的一些总结
- 自定义创建View
- 自定义Android圆点指示器
- 【Android】自定义View实现信封红蓝边/收货地址线条
- 自定义View(一)
- Android自定义组件:一个波浪形的组件