• 自定义控件之上拉刷新


    自定义控件所需要的布局文件:xlistview_footer.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
    
        <RelativeLayout
            android:id="@+id/xlistview_footer_content"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="5dp" >
    
            <ProgressBar
                android:id="@+id/xlistview_footer_progressbar"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"    
                android:visibility="invisible" />
    
            <TextView
                android:id="@+id/xlistview_footer_hint_textview"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:text="查看更多" />
        </RelativeLayout>
    
    </LinearLayout>

    自定义控件:XListView.java

    /* 
     * @(#)XListView.java
     *
     * Copyright 2015, .....
     */
    package com.example.test_my_x_list_view.widget;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.animation.DecelerateInterpolator;
    import android.widget.AbsListView;
    import android.widget.AbsListView.OnScrollListener;
    import android.widget.LinearLayout;
    import android.widget.ListAdapter;
    import android.widget.ListView;
    import android.widget.Scroller;
    import android.widget.TextView;
    
    import com.example.test_my_x_list_view.R;
    
    /**
     * XListView:上拉刷新
     * 
     * <p>
     * <b>History:</b>
     * <table border="1">
     * <tr>
     * <th>Date</th>
     * <th>Operator</th>
     * <th>Memo</th>
     * </tr>
     * <tr>
     * <td>2015-5-13</td>
     * <td>Zjc</td>
     * <td>Create</td>
     * </tr>
     * </table>
     * 
     * @author Zjc
     * 
     * @version 1.0.0
     * @since 1.0.0
     */
    public class XListView extends ListView implements OnScrollListener {
    
        private float mLastY = -1;
        private Scroller mScroller;
        private OnScrollListener mScrollListener;
        private IXListViewListener mListViewListener;
        public XListViewFooter mFooterView;
        private boolean mEnablePullLoad;
        private boolean mPullLoading;
        private boolean mIsFooterReady = false;
        private int mTotalItemCount;
        private int mScrollBack;
        private final static int SCROLLBACK_HEADER = 0;
        private final static int SCROLLBACK_FOOTER = 1;
        private final static int SCROLL_DURATION = 400;
        private final static int PULL_LOAD_MORE_DELTA = 50;
        private final static float OFFSET_RADIO = 1.8f;
    
        /**
         * 默认构造方法
         * 
         * @param context
         * @param attrs
         */
        public XListView(Context context, AttributeSet attrs) {
            super(context, attrs);
            initWithContext(context);
        }
    
        /**
         * 默认构造方法
         * 
         * @param context
         * @param attrs
         * @param defStyle
         */
        public XListView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            initWithContext(context);
        }
    
        /**
         * 默认构造方法
         * 
         * @param context
         */
        public XListView(Context context) {
            super(context);
            initWithContext(context);
        }
    
        /**
         * 根据上下文进行初始化
         * 
         * @param context
         */
        private void initWithContext(Context context) {
            mScroller = new Scroller(context, new DecelerateInterpolator());
            super.setOnScrollListener(this);
            mFooterView = new XListViewFooter(context);
        }
    
        @Override
        public void setAdapter(ListAdapter adapter) {
            if (mIsFooterReady == false) {
                mIsFooterReady = true;
                addFooterView(mFooterView);
                // addHeaderView(mFooterView);
            }
            super.setAdapter(adapter);
        }
    
        /**
         * enable or disable pull up load more feature.
         * 
         * @param enable
         */
        public void setPullLoadEnable(boolean enable) {
            mEnablePullLoad = enable;
            if (!mEnablePullLoad) {
                mFooterView.hide();
                mFooterView.setOnClickListener(null);
            } else {
                mPullLoading = false;
                mFooterView.show();
                mFooterView.setState(XListViewFooter.STATE_NORMAL);
                // both "pull up" and "click" will invoke load more.
                mFooterView.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        startLoadMore();
                    }
                });
            }
        }
    
        private void startLoadMore() {
            mPullLoading = true;
            // 设置底部状态
            mFooterView.setState(XListViewFooter.STATE_LOADING);
            if (mListViewListener != null) {
                mListViewListener.onLoadMore();
            }
        }
    
        /**
         * stop load more, reset footer view.
         */
        public void stopLoadMore() {
            if (mPullLoading == true) {
                mPullLoading = false;
                mFooterView.setState(XListViewFooter.STATE_NORMAL);
            }
        }
    
        private void updateFooterHeight(float delta) {
            int height = mFooterView.getBottomMargin() + (int) delta;
            if (mEnablePullLoad && !mPullLoading) {
                if (height > PULL_LOAD_MORE_DELTA) {
                    mFooterView.setState(XListViewFooter.STATE_READY);
                } else {
                    mFooterView.setState(XListViewFooter.STATE_NORMAL);
                }
            }
            mFooterView.setBottomMargin(height);
    
        }
    
        private void invokeOnScrolling() {
            if (mScrollListener instanceof OnXScrollListener) {
                OnXScrollListener l = (OnXScrollListener) mScrollListener;
                l.onXScrolling(this);
            }
        }
    
        private void resetFooterHeight() {
            int bottomMargin = mFooterView.getBottomMargin();
            if (bottomMargin > 0) {
                mScrollBack = SCROLLBACK_FOOTER;
                mScroller.startScroll(0, bottomMargin, 0, -bottomMargin,
                        SCROLL_DURATION);
                invalidate();
            }
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent ev) {
            if (mLastY == -1) {
                mLastY = ev.getRawY();
            }
            switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mLastY = ev.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                final float deltaY = ev.getRawY() - mLastY;
                mLastY = ev.getRawY();
                if (getLastVisiblePosition() == mTotalItemCount - 1
                        && (mFooterView.getBottomMargin() > 0 || deltaY < 0)) {
                    updateFooterHeight(-deltaY / OFFSET_RADIO);
                }
                break;
            default:
                mLastY = -1; // reset
                if (getLastVisiblePosition() == mTotalItemCount - 1) {
                    // invoke load more.
                    if (mEnablePullLoad
                            && mFooterView.getBottomMargin() > PULL_LOAD_MORE_DELTA) {
                        startLoadMore();
                    }
                    resetFooterHeight();
                }
                break;
            }
            return super.onTouchEvent(ev);
        }
    
        @Override
        public void computeScroll() {
            if (mScroller.computeScrollOffset()) {
                if (mScrollBack != SCROLLBACK_HEADER) {
                    mFooterView.setBottomMargin(mScroller.getCurrY());
                }
                postInvalidate();
                invokeOnScrolling();
            }
            super.computeScroll();
        }
    
        @Override
        public void setOnScrollListener(OnScrollListener l) {
            mScrollListener = l;
        }
    
        public interface OnXScrollListener extends OnScrollListener {
            public void onXScrolling(View view);
        }
    
        public interface IXListViewListener {
            public void onLoadMore();
        }
    
        public void setXListViewListener(IXListViewListener l) {
            mListViewListener = l;
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see
         * android.widget.AbsListView.OnScrollListener#onScrollStateChanged(android
         * .widget.AbsListView, int)
         */
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            if (mScrollListener != null) {
                mScrollListener.onScrollStateChanged(view, scrollState);
            }
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see android.widget.AbsListView.OnScrollListener#onScroll(android.widget.
         * AbsListView, int, int, int)
         */
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {
            mTotalItemCount = totalItemCount;
            if (mScrollListener != null) {
                mScrollListener.onScroll(view, firstVisibleItem, visibleItemCount,
                        totalItemCount);
            }
        }
    
        protected class XListViewFooter extends LinearLayout {
            public final static int STATE_NORMAL = 0;
            public final static int STATE_READY = 1;
            public final static int STATE_LOADING = 2;
            private Context mContext;
            private View mContentView;
            private View mProgressBar;
            private TextView mHintView;
    
            public XListViewFooter(Context context) {
                super(context);
                initView(context);
            }
    
            public XListViewFooter(Context context, AttributeSet attrs) {
                super(context, attrs);
                initView(context);
            }
    
            public void setState(int state) {
                mHintView.setVisibility(View.INVISIBLE);
                mProgressBar.setVisibility(View.INVISIBLE);
                mHintView.setVisibility(View.INVISIBLE);
                if (state == STATE_READY) {
                    mHintView.setVisibility(View.VISIBLE);
                    mHintView.setText("松开载入更多");
                } else if (state == STATE_LOADING) {
                    mProgressBar.setVisibility(View.VISIBLE);
                } else {
                    mHintView.setVisibility(View.VISIBLE);
                    mHintView.setText("查看更多");
                }
            }
    
            public void setBottomMargin(int height) {
                if (height < 0)
                    return;
                LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContentView
                        .getLayoutParams();
                lp.bottomMargin = height;
                mContentView.setLayoutParams(lp);
            }
    
            public int getBottomMargin() {
                LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContentView
                        .getLayoutParams();
                return lp.bottomMargin;
            }
    
            /**
             * normal status
             */
            public void normal() {
                mHintView.setVisibility(View.VISIBLE);
                mProgressBar.setVisibility(View.GONE);
            }
    
            /**
             * loading status
             */
            public void loading() {
                mHintView.setVisibility(View.GONE);
                mProgressBar.setVisibility(View.VISIBLE);
            }
    
            /**
             * hide footer when disable pull load more
             */
            public void hide() {
                LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContentView
                        .getLayoutParams();
                lp.height = 0;
                mContentView.setLayoutParams(lp);
            }
    
            /**
             * show footer
             */
            public void show() {
                LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContentView
                        .getLayoutParams();
                lp.height = LayoutParams.WRAP_CONTENT;
                mContentView.setLayoutParams(lp);
            }
    
            @SuppressWarnings("deprecation")
            private void initView(Context context) {
                mContext = context;
                LinearLayout moreView = (LinearLayout) LayoutInflater
                        .from(mContext).inflate(R.layout.xlistview_footer, null);
                addView(moreView);
                moreView.setLayoutParams(new LinearLayout.LayoutParams(
                        LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
                mContentView = moreView.findViewById(R.id.xlistview_footer_content);
                mProgressBar = moreView
                        .findViewById(R.id.xlistview_footer_progressbar);
                mHintView = (TextView) moreView
                        .findViewById(R.id.xlistview_footer_hint_textview);
            }
    
        }
    
    }

    MainActivity.java对控件的使用

    package com.example.test_my_x_list_view;
    
    import android.app.Activity;
    import android.os.Bundle;
    
    import com.example.test_my_x_list_view.widget.XListView;
    import com.example.test_my_x_list_view.widget.XListView.IXListViewListener;
    import com.example.test_my_x_list_view.widget.adapter.MyAdapter;
    
    public class MainActivity extends Activity {
    
        /** 页面控件 */
        private XListView x_list_view;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            x_list_view = (XListView) findViewById(R.id.x_list_view);
            // 设置可加载更多
            x_list_view.setPullLoadEnable(true);
            // 设置上拉刷新监听
            x_list_view.setXListViewListener(new IXListViewListener() {
    
                @Override
                public void onLoadMore() {
                    // onLoaded();
                }
            });
            // 映射值
            x_list_view.setAdapter(new MyAdapter(getApplicationContext()));
        }
    }

    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" >
    
        <com.example.test_my_x_list_view.widget.XListView
            android:id="@+id/x_list_view"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />
    
    </RelativeLayout>

    适配器MyAdapter.java

    /* 
     * @(#)MyAdapter.java
     *
     * Copyright 2015, .....
     */
    package com.example.test_my_x_list_view.widget.adapter;
    
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    
    import com.example.test_my_x_list_view.R;
    
    /**
     * ListView适配器
     * 
     * <p>
     * <b>History:</b>
     * <table border="1">
     * <tr>
     * <th>Date</th>
     * <th>Operator</th>
     * <th>Memo</th>
     * </tr>
     * <tr>
     * <td>2015-5-6</td>
     * <td>Zjc</td>
     * <td>Create</td>
     * </tr>
     * </table>
     * 
     * @author Zjc
     * 
     * @version 1.0.0
     * @since 1.0.0
     */
    public class MyAdapter extends BaseAdapter {
    
        private LayoutInflater inflater;
    
        /**
         * 默认构造方法
         */
        public MyAdapter(Context context) {
            this.inflater = LayoutInflater.from(context);
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see android.widget.Adapter#getCount()
         */
        @Override
        public int getCount() {
            return 28;
            // TODO 完成Adapter.getCount方法的构建或覆盖
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see android.widget.Adapter#getItem(int)
         */
        @Override
        public Object getItem(int position) {
            return null;
            // TODO 完成Adapter.getItem方法的构建或覆盖
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see android.widget.Adapter#getItemId(int)
         */
        @Override
        public long getItemId(int position) {
            return position;
            // TODO 完成Adapter.getItemId方法的构建或覆盖
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see android.widget.Adapter#getView(int, android.view.View,
         * android.view.ViewGroup)
         */
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            convertView = inflater.inflate(R.layout.item, parent, false);
            return convertView;
        }
    }

    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"
        android:background="#607D8B" >
    
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="60dp"
            android:gravity="center_vertical" >
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="列表数据"
                android:textColor="#ffffff"
                android:textSize="14sp" />
        </LinearLayout>
    
    </LinearLayout>
  • 相关阅读:
    [转]SQL Server 索引结构及其使用一
    平台无关的RICHTEXT实现
    谈谈时间管理陶哲轩
    BigNumCalculator
    关于构造和析构的几点拟人化思考
    ScaleForm十六戒言
    VAX对多种格式增加支持
    关于知识,经验,能力
    AutoTidyMyFiles
    王石语摘
  • 原文地址:https://www.cnblogs.com/zjc0514/p/4501075.html
Copyright © 2020-2023  润新知