Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> ListView常用拓展

ListView常用拓展

編輯:關於Android編程

一、實現ListView下拉刷新

第一步:添加頂部下拉加載界面,即ListView的header頭布局 1、創建layout布局文件head_layout 2、創建一個自定義ListView文件,繼承ListView, 3、將布局文件加載到ListView中  
LayoutInflater inflater=LayoutInflater.from(context);
    headView=inflater.inflate(R.layout.head_layout,null);
    this.addHeaderView(headView );
\
    4、設置Header隱藏 通過設置listview的header布局的上邊距的方法,這樣通過將header的上邊距設置成負值,我們就可以實現動態的隱藏和現實header了,就實現了動態顯示出來的效果。 我們需要將header布局的上邊距設置為其長度的負值,所以我們還要獲取其高度。我們需要在構造方法中測量其高度。   通知父布局占了多大地方
ViewGroup.LayoutParams p=headview.getLayoutParams();
if(p== null){
    p=new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams. WRAP_CONTENT);
}
int width=ViewGroup. getChildMeasureSpec(0,0,p.width);
int height;
int tempHeight=p. height;
if(tempHeight> 0){
    height=MeasureSpec.makeMeasureSpec(tempHeight,MeasureSpec. EXACTLY);
}
else {
    height=MeasureSpec.makeMeasureSpec( 0,MeasureSpec. UNSPECIFIED);
}
headview .measure(width,height);
ViewGroup.getChildMeasureSpec(int spec, int padding, int childDimension); spec:父View的詳細測量值(即MeasureSpec) padding:view當前尺寸的的內邊距和外邊距(padding,margin) childDimension:child在當前尺寸下的布局參數寬高值(LayoutParam.width,height)  
headViewHeight=headView .getMeasuredHeight();

//設置headVeiw上邊距
private void topPadding(int headViewHeight ) {
    headView.setPadding(headView .getPaddingLeft(), headViewHeight , headView.getPaddingRight(), headView.getPaddingBottom());
    headView.invalidate();
}
第二步:監聽onScrollListener,來判斷當前是否顯示在listview的最頂部,並獲得滑動狀態
public void onScrollStateChanged(AbsListView view, int scrollState) {
    this.scrollState =scrollState;
}
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    this.firstVisibleItem = firstVisibleItem;
}

第三步,.因為頂部下拉加載界面是跟隨手勢滑動狀態不斷改變界面顯示的所以我們需要監聽onTouch事件,來改變當前狀態以及界面顯示;
int firstVisibleItem; //當前界面第一個可見item位置
boolean isRemark;//標記,當前是在ListView的最頂端並且按下
int startY;//開始的Y值
int scrollState;//當前滾動狀態
int state;//當前的狀態
final int NONE=0;//正常狀態
final int PULL=1;//提示拉伸狀態
final int RELESE=2;//提示釋放狀態
final int REFRESH=3;//正在刷新
//1、判斷當前的狀態
public boolean onTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            if (firstVisibleItem == 0) {
                isRemark = true;
                startY = (int) ev.getY();
            }
            break;
        case MotionEvent.ACTION_MOVE:
            onMove(ev);
            break;
        case MotionEvent.ACTION_UP:
            if(state==RELESE){
                state=REFRESH;
          iRefreshListener.onRefresh();
            }
            else if(state==PULL){
                state=NONE;
                isRemark=false;
            }
            refreshViewByState();
            break;
    }
    return super .onTouchEvent(ev);
}

//2、移動過程中的操作
private void onMove(MotionEvent ev) {
    if(!isRemark ){
        return ;
    }
    int tempY= (int ) ev.getY();
    int space=tempY-startY ;
    int topPadding=space-headViewHeight ;
    topPadding(topPadding);
    if (space>0 ){
        state =PULL ;
    }
    switch (state ){
        case NONE:
            if (space>0){
                state=PULL;
            }
            refreshViewByState();
            break;
        case PULL:
            if(space>headViewHeight+30 && scrollState== SCROLL_STATE_TOUCH_SCROLL) {
                state = RELESE;
            }
            refreshViewByState();
            break;
        case RELESE:
            if(space
//3、根據當前狀態改變界面顯示
private void refreshViewByState(){
    TextView tip= (TextView) headView .findViewById(R.id.tip);
    ImageView imageView= (ImageView) headView.findViewById(R.id.arrow);
    ProgressBar progressBar= (ProgressBar) headView.findViewById(R.id.progress);
    RotateAnimation animation1=new RotateAnimation(0,180,RotateAnimation.RELATIVE_TO_SELF, 0.5f,RotateAnimation. RELATIVE_TO_SELF, 0.5f);
    animation1.setDuration(500 );
    animation1.setFillAfter(true );
    RotateAnimation animation2=new RotateAnimation(180,0,RotateAnimation.RELATIVE_TO_SELF, 0.5f,RotateAnimation. RELATIVE_TO_SELF, 0.5f);
    animation2.setDuration(500 );
    animation2.setFillAfter(true );
    switch (state ){
        case NONE:
            topPadding(-headViewHeight);
            break;
        case PULL:
            imageView.setVisibility(VISIBLE);
            progressBar.setVisibility(GONE);
            tip.setText("下拉可以刷新");
            imageView.clearAnimation();
            imageView.setAnimation(animation2);
            break;
        case RELESE:
            imageView.setVisibility(VISIBLE);
            progressBar.setVisibility(GONE);
            tip.setText("松開可以刷新");
            imageView.clearAnimation();
            imageView.setAnimation(animation1);
            break;
        case REFRESH:
            topPadding(50 );
            imageView.setVisibility(GONE);
            imageView.clearAnimation();
            progressBar.setVisibility(VISIBLE);
            tip.setText("正在刷新");
            break;
    }
}
//4、刷新完成
//獲取完數據
public void refreshComplete(){
    state=NONE ;
    isRemark=false ;
    refreshViewByState();
    TextView time= (TextView) headView .findViewById(R.id.time);
    SimpleDateFormat format=new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
    Date date=new Date(System.currentTimeMillis());
    String t=format.format(date);
    time.setText(t);
}


第四步,加載最新數據 1、實現接口調用
public void setInterface(IRefreshListener iRefreshListener){
    this.iRefreshListener =iRefreshListener;
}

//刷新數據接口
public interface IRefreshListener{
    public void onRefresh();
}
  在 state=REFRESHs時調用這個接口中的函數
case MotionEvent.ACTION_UP:
            if(state==RELESE){
                state=REFRESH;
          iRefreshListener.onRefresh();
2、在Activity中實現IRefreshListener接口
//添加數據
private void setRefreshData(){
    for (int i = 0 ; i < 2 ; i++) {
        bean .add(0 ,new ItemBean(R.drawable.image,
                "我是新加載"+i,
                "我想請你吃飯"+i,
                "8月"+( 22-i)+ "日"));
    }
}
@Override
public void onRefresh() {
    //獲取最新數據
    setRefreshData();
    android.os.Handler handler=new android.os.Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            //通知界面刷新
            adapter.notifyDataSetChanged();
            //通知ListView刷新完畢
            mListView.refreshComplete();
        }
    },2000);

}
此處用Handler模擬2秒刷新過程 \   \     二、ListView分頁功能   第一步:添加底部加載界面,即ListView的footer頭布局 1、創建layout布局文件footer_layout 2、創建一個自定義ListView文件,繼承ListView, 3、將布局文件加載到ListView中 4、設置footer隱藏  
    LayoutInflater inflater=LayoutInflater.from(context);
    footerView=inflater.inflate(R.layout.footer_layout,null);
    footerView.findViewById(R.id.layout).setVisibility(GONE );
    this.addFooterView(footerView );
  第二步:監聽onScrollListener,來判斷當前是否顯示在listview的最底部  
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

    this.lastVisibleItem =firstVisibleItem+visibleItemCount;
    this.totalItemCount =totalItemCount;
}

  firstVisibleItem:顯示的第一個item的排序號 visibleItemCount:顯示的數量 totalItemCount:總的數量
public void onScrollStateChanged(AbsListView view, int scrollState) {
    this.scrollState =scrollState;
    if(lastVisibleItem ==totalItemCount &&scrollState==SCROLL_STATE_IDLE){
        if (!isLoading ){
            isLoading=true;
            footerView.findViewById(R.id.layout).setVisibility( VISIBLE);
iRefreshListener.onLoad();
        }
    }
}

  第三步:加載數據 1、實現接口調用  
public void setInterface(IRefreshListener iRefreshListener){
    this.iRefreshListener =iRefreshListener;
}

//刷新數據接口
public interface IRefreshListener{
public void onLoad();
}

  2、設置headerView加載完隱藏
//加載完數據
public void loadComplete(){
    isLoading=false ;
    footerView.findViewById(R.id.layout).setVisibility(GONE);
}

  3、更新數據
private void loadData(){
    for (int i = 20 ; i < 30 ; i++) {
        bean .add(new ItemBean(R.drawable.image,
                "我是xucan"+i,
                "我想請你吃飯"+i,
                "8月"+i+ "日"));
    }
}
@Override
public void onLoad() {
    android.os.Handler handler=new android.os.Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            //加載數據
            loadData();
            //通知界面刷新
            adapter.notifyDataSetChanged();
            //通知加載完畢
            mListView.loadComplete();
        }
    },1000);
}

  三、具有彈性的ListView   我們可以通過如上方法,通過添加HeaderView來實現彈性效果,不過這裡有個簡單的方法。 ListView中有一個控制滑動到邊緣的處理方法,如下

protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent)

參數maxOverScrollY:默認值為0;只要修改這個參數,就可以實現彈性效果


 
如下:重寫這個方法,將maxOverScrollY改為你想要的值

protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX,
 int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
    return super .overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, 40, isTouchEvent);
}
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved