xListView

来源:互联网 发布:mac如何卸载flash插件 编辑:程序博客网 时间:2024/03/29 23:42

1.MainActivity

package com.example.pulldemo;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import java.util.ArrayList;import me.maxwin.view.XListView;import me.maxwin.view.XListView.IXListViewListener;import android.app.Activity;import android.os.AsyncTask;import android.os.Bundle;import com.example.pulldemo.bean.GsonBean;import com.google.gson.Gson;public class MainActivity extends Activity implements IXListViewListener {private XListView mListView;private ArrayList<GsonBean.MyList> dataList = new ArrayList<GsonBean.MyList>();private int index = 1;String path = "http://v.juhe.cn/weixin/query?key=518bccce2abaeb7f08101e47ed5f5891&pno="+ index;private int currentState;private int STATE_REFRESH = 1;private int STATE_LOAD = 2;private MyAdapter myAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mListView = (XListView) findViewById(R.id.xListView);mListView.setPullLoadEnable(true);mListView.setXListViewListener(this);// 0917c812f187b92e025c9b7c2d4e59b5getInfo(path);}private void getInfo(String path) {AsyncTask<String, Void, String> asyncTask = new AsyncTask<String, Void, String>() {@Overrideprotected String doInBackground(String... params) {try {URL url = new URL(params[0]);HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();int responseCode = httpURLConnection.getResponseCode();if (responseCode == 200) {InputStream inputStream = httpURLConnection.getInputStream();String steamUtils = SteamUtils.steamUtils(inputStream);return steamUtils;}} catch (Exception e) {e.printStackTrace();}return null;}@Overrideprotected void onPostExecute(String result) {super.onPostExecute(result);Gson gson = new Gson();GsonBean fromJson = gson.fromJson(result, GsonBean.class);if(currentState==STATE_REFRESH){dataList.clear();}dataList.addAll(fromJson.result.list);if (myAdapter == null) {myAdapter = new MyAdapter(MainActivity.this, dataList);mListView.setAdapter(myAdapter);} else {myAdapter.notifyDataSetChanged();}onLoad();}};asyncTask.execute(path);}private void onLoad() {mListView.stopRefresh();mListView.stopLoadMore();mListView.setRefreshTime("刚刚");}@Overridepublic void onRefresh() {currentState=STATE_REFRESH;getInfo(path);}@Overridepublic void onLoadMore() {currentState=STATE_LOAD;index++;getInfo(path);}}

2.xListView
/** * @file XListView.java * @package me.maxwin.view * @create Mar 18, 2012 6:28:41 PM * @author Maxwin * @description An ListView support (a) Pull down to refresh, (b) Pull up to load more. * Implement IXListViewListener, and see stopRefresh() / stopLoadMore(). */package me.maxwin.view;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.ViewTreeObserver.OnGlobalLayoutListener;import android.view.animation.DecelerateInterpolator;import android.widget.AbsListView;import android.widget.AbsListView.OnScrollListener;import android.widget.ListAdapter;import android.widget.ListView;import android.widget.RelativeLayout;import android.widget.Scroller;import android.widget.TextView;import com.example.pulldemo.R;public class XListView extends ListView implements OnScrollListener {private float mLastY = -1; // save event yprivate Scroller mScroller; // used for scroll backprivate OnScrollListener mScrollListener; // user's scroll listener// the interface to trigger refresh and load more.private IXListViewListener mListViewListener;// -- header viewprivate XListViewHeader mHeaderView;// header view content, use it to calculate the Header's height. And hide it// when disable pull refresh.private RelativeLayout mHeaderViewContent;private TextView mHeaderTimeView;private int mHeaderViewHeight; // header view's heightprivate boolean mEnablePullRefresh = true;private boolean mPullRefreshing = false; // is refreashing.// -- footer viewprivate XListViewFooter mFooterView;private boolean mEnablePullLoad;private boolean mPullLoading;private boolean mIsFooterReady = false;// total list items, used to detect is at the bottom of listview.private int mTotalItemCount;// for mScroller, scroll back from header or footer.private int mScrollBack;private final static int SCROLLBACK_HEADER = 0;private final static int SCROLLBACK_FOOTER = 1;private final static int SCROLL_DURATION = 400; // scroll back durationprivate final static int PULL_LOAD_MORE_DELTA = 50; // when pull up >= 50px// at bottom, trigger// load more.private final static float OFFSET_RADIO = 1.8f; // support iOS like pull// feature./** * @param context */public XListView(Context context) {super(context);initWithContext(context);}public XListView(Context context, AttributeSet attrs) {super(context, attrs);initWithContext(context);}public XListView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);initWithContext(context);}private void initWithContext(Context context) {mScroller = new Scroller(context, new DecelerateInterpolator());// XListView need the scroll event, and it will dispatch the event to// user's listener (as a proxy).super.setOnScrollListener(this);// init header viewmHeaderView = new XListViewHeader(context);mHeaderViewContent = (RelativeLayout) mHeaderView.findViewById(R.id.xlistview_header_content);mHeaderTimeView = (TextView) mHeaderView.findViewById(R.id.xlistview_header_time);addHeaderView(mHeaderView);// init footer viewmFooterView = new XListViewFooter(context);// init header heightmHeaderView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {@Overridepublic void onGlobalLayout() {mHeaderViewHeight = mHeaderViewContent.getHeight();getViewTreeObserver().removeGlobalOnLayoutListener(this);}});}@Overridepublic void setAdapter(ListAdapter adapter) {// make sure XListViewFooter is the last footer view, and only add once.if (mIsFooterReady == false) {mIsFooterReady = true;addFooterView(mFooterView);}super.setAdapter(adapter);}/** * enable or disable pull down refresh feature. *  * @param enable */public void setPullRefreshEnable(boolean enable) {mEnablePullRefresh = enable;if (!mEnablePullRefresh) { // disable, hide the contentmHeaderViewContent.setVisibility(View.INVISIBLE);} else {mHeaderViewContent.setVisibility(View.VISIBLE);}}/** * enable or disable pull up load more feature. *  * @param enable */public void setPullLoadEnable(boolean enable) {mEnablePullLoad = enable;if (!mEnablePullLoad) {mFooterView.hide();mFooterView.setOnClickListener(null);//make sure "pull up" don't show a line in bottom when listview with one page setFooterDividersEnabled(false);} else {mPullLoading = false;mFooterView.show();mFooterView.setState(XListViewFooter.STATE_NORMAL);//make sure "pull up" don't show a line in bottom when listview with one page  setFooterDividersEnabled(true);// both "pull up" and "click" will invoke load more.mFooterView.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {startLoadMore();}});}}/** * stop refresh, reset header view. */public void stopRefresh() {if (mPullRefreshing == true) {mPullRefreshing = false;resetHeaderHeight();}}/** * stop load more, reset footer view. */public void stopLoadMore() {if (mPullLoading == true) {mPullLoading = false;mFooterView.setState(XListViewFooter.STATE_NORMAL);}}/** * set last refresh time *  * @param time */public void setRefreshTime(String time) {mHeaderTimeView.setText(time);}private void invokeOnScrolling() {if (mScrollListener instanceof OnXScrollListener) {OnXScrollListener l = (OnXScrollListener) mScrollListener;l.onXScrolling(this);}}private void updateHeaderHeight(float delta) {mHeaderView.setVisiableHeight((int) delta+ mHeaderView.getVisiableHeight());if (mEnablePullRefresh && !mPullRefreshing) { // 未处于刷新状态,更新箭头if (mHeaderView.getVisiableHeight() > mHeaderViewHeight) {mHeaderView.setState(XListViewHeader.STATE_READY);} else {mHeaderView.setState(XListViewHeader.STATE_NORMAL);}}setSelection(0); // scroll to top each time}/** * reset header view's height. */private void resetHeaderHeight() {int height = mHeaderView.getVisiableHeight();if (height == 0) // not visible.return;// refreshing and header isn't shown fully. do nothing.if (mPullRefreshing && height <= mHeaderViewHeight) {return;}int finalHeight = 0; // default: scroll back to dismiss header.// is refreshing, just scroll back to show all the header.if (mPullRefreshing && height > mHeaderViewHeight) {finalHeight = mHeaderViewHeight;}mScrollBack = SCROLLBACK_HEADER;mScroller.startScroll(0, height, 0, finalHeight - height,SCROLL_DURATION);// trigger computeScrollinvalidate();}private void updateFooterHeight(float delta) {int height = mFooterView.getBottomMargin() + (int) delta;if (mEnablePullLoad && !mPullLoading) {if (height > PULL_LOAD_MORE_DELTA) { // height enough to invoke load// more.mFooterView.setState(XListViewFooter.STATE_READY);} else {mFooterView.setState(XListViewFooter.STATE_NORMAL);}}mFooterView.setBottomMargin(height);//setSelection(mTotalItemCount - 1); // scroll to bottom}private void resetFooterHeight() {int bottomMargin = mFooterView.getBottomMargin();if (bottomMargin > 0) {mScrollBack = SCROLLBACK_FOOTER;mScroller.startScroll(0, bottomMargin, 0, -bottomMargin,SCROLL_DURATION);invalidate();}}private void startLoadMore() {mPullLoading = true;mFooterView.setState(XListViewFooter.STATE_LOADING);if (mListViewListener != null) {mListViewListener.onLoadMore();}}@Overridepublic 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 (getFirstVisiblePosition() == 0&& (mHeaderView.getVisiableHeight() > 0 || deltaY > 0)) {// the first item is showing, header has shown or pull down.updateHeaderHeight(deltaY / OFFSET_RADIO);invokeOnScrolling();} else if (getLastVisiblePosition() == mTotalItemCount - 1&& (mFooterView.getBottomMargin() > 0 || deltaY < 0)) {// last item, already pulled up or want to pull up.updateFooterHeight(-deltaY / OFFSET_RADIO);}break;default:mLastY = -1; // resetif (getFirstVisiblePosition() == 0) {// invoke refreshif (mEnablePullRefresh&& mHeaderView.getVisiableHeight() > mHeaderViewHeight) {mPullRefreshing = true;mHeaderView.setState(XListViewHeader.STATE_REFRESHING);if (mListViewListener != null) {mListViewListener.onRefresh();}}resetHeaderHeight();} else if (getLastVisiblePosition() == mTotalItemCount - 1) {// invoke load more.if (mEnablePullLoad    && mFooterView.getBottomMargin() > PULL_LOAD_MORE_DELTA    && !mPullLoading) {startLoadMore();}resetFooterHeight();}break;}return super.onTouchEvent(ev);}@Overridepublic void computeScroll() {if (mScroller.computeScrollOffset()) {if (mScrollBack == SCROLLBACK_HEADER) {mHeaderView.setVisiableHeight(mScroller.getCurrY());} else {mFooterView.setBottomMargin(mScroller.getCurrY());}postInvalidate();invokeOnScrolling();}super.computeScroll();}@Overridepublic void setOnScrollListener(OnScrollListener l) {mScrollListener = l;}@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {if (mScrollListener != null) {mScrollListener.onScrollStateChanged(view, scrollState);}}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {// send to user's listenermTotalItemCount = totalItemCount;if (mScrollListener != null) {mScrollListener.onScroll(view, firstVisibleItem, visibleItemCount,totalItemCount);}}public void setXListViewListener(IXListViewListener l) {mListViewListener = l;}/** * you can listen ListView.OnScrollListener or this one. it will invoke * onXScrolling when header/footer scroll back. */public interface OnXScrollListener extends OnScrollListener {public void onXScrolling(View view);}/** * implements this interface to get refresh/load more event. */public interface IXListViewListener {public void onRefresh();public void onLoadMore();}}

3.xlistViewFooter
/** * @file XFooterView.java * @create Mar 31, 2012 9:33:43 PM * @author Maxwin * @description XListView's footer */package me.maxwin.view;import android.content.Context;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;import com.example.pulldemo.R;public 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(R.string.xlistview_footer_hint_ready);} else if (state == STATE_LOADING) {mProgressBar.setVisibility(View.VISIBLE);} else {mHintView.setVisibility(View.VISIBLE);mHintView.setText(R.string.xlistview_footer_hint_normal);}}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);}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);}}

4.xListViewHeader

/** * @file XListViewHeader.java * @create Apr 18, 2012 5:22:27 PM * @author Maxwin * @description XListView's header */package me.maxwin.view;import android.content.Context;import android.util.AttributeSet;import android.view.Gravity;import android.view.LayoutInflater;import android.view.View;import android.view.animation.Animation;import android.view.animation.RotateAnimation;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.ProgressBar;import android.widget.TextView;import com.example.pulldemo.R;public class XListViewHeader extends LinearLayout {private LinearLayout mContainer;private ImageView mArrowImageView;private ProgressBar mProgressBar;private TextView mHintTextView;private int mState = STATE_NORMAL;private Animation mRotateUpAnim;private Animation mRotateDownAnim;private final int ROTATE_ANIM_DURATION = 180;public final static int STATE_NORMAL = 0;public final static int STATE_READY = 1;public final static int STATE_REFRESHING = 2;public XListViewHeader(Context context) {super(context);initView(context);}/** * @param context * @param attrs */public XListViewHeader(Context context, AttributeSet attrs) {super(context, attrs);initView(context);}private void initView(Context context) {// 初始情况,设置下拉刷新view高度为0LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 0);// 将下拉刷新的view添加进来mContainer = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.xlistview_header, null);addView(mContainer, lp);setGravity(Gravity.BOTTOM);mArrowImageView = (ImageView) findViewById(R.id.xlistview_header_arrow);mHintTextView = (TextView) findViewById(R.id.xlistview_header_hint_textview);mProgressBar = (ProgressBar) findViewById(R.id.xlistview_header_progressbar);// 准备向上和向下的动画mRotateUpAnim = new RotateAnimation(0.0f, -180.0f,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);// 设置旋转时间间隔mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION);mRotateUpAnim.setFillAfter(true);mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION);mRotateDownAnim.setFillAfter(true);}public void setState(int state) {if (state == mState)return;// 如果当前状态是正在刷新if (state == STATE_REFRESHING) { // 显示进度// 移除动画mArrowImageView.clearAnimation();// 设置imageView不可见mArrowImageView.setVisibility(View.INVISIBLE);// 设置progressBar可见mProgressBar.setVisibility(View.VISIBLE);} else { // 显示箭头图片// 只要不是正在刷新,进度条可见,imageView不可见mArrowImageView.setVisibility(View.VISIBLE);mProgressBar.setVisibility(View.INVISIBLE);}switch (state) {case STATE_NORMAL:if (mState == STATE_READY) {mArrowImageView.startAnimation(mRotateDownAnim);}if (mState == STATE_REFRESHING) {mArrowImageView.clearAnimation();}mHintTextView.setText(R.string.xlistview_header_hint_normal);break;case STATE_READY:if (mState != STATE_READY) {mArrowImageView.clearAnimation();mArrowImageView.startAnimation(mRotateUpAnim);mHintTextView.setText(R.string.xlistview_header_hint_ready);}break;case STATE_REFRESHING:mHintTextView.setText(R.string.xlistview_header_hint_loading);break;default:}mState = state;}public void setVisiableHeight(int height) {if (height < 0)height = 0;LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContainer.getLayoutParams();lp.height = height;mContainer.setLayoutParams(lp);}public int getVisiableHeight() {return mContainer.getLayoutParams().height;}}

5.Main布局文件
<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" >    <me.maxwin.view.XListView        android:id="@+id/xListView"        android:layout_width="wrap_content"        android:layout_height="wrap_content" /></RelativeLayout>

6.lv_item
<?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" />    <TextView        android:id="@+id/textView"        android:layout_width="wrap_content"        android:layout_height="wrap_content" /></LinearLayout>

7.xListview_footer
<?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="10dp" >        <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="@string/xlistview_footer_hint_normal" />    </RelativeLayout></LinearLayout>

8.xListview_header

<?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"    android:gravity="bottom" >    <RelativeLayout        android:id="@+id/xlistview_header_content"        android:layout_width="fill_parent"        android:layout_height="60dp" >        <LinearLayout            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerInParent="true"            android:gravity="center"            android:orientation="vertical" android:id="@+id/xlistview_header_text">            <TextView                android:id="@+id/xlistview_header_hint_textview"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="@string/xlistview_header_hint_normal" />            <LinearLayout                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_marginTop="3dp" >                <TextView                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:text="@string/xlistview_header_last_time"                    android:textSize="12sp" />                <TextView                    android:id="@+id/xlistview_header_time"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:textSize="12sp" />            </LinearLayout>        </LinearLayout>        <ImageView            android:id="@+id/xlistview_header_arrow"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignLeft="@id/xlistview_header_text"            android:layout_centerVertical="true"            android:layout_marginLeft="-35dp"            android:src="@drawable/xlistview_arrow" />        <ProgressBar            android:id="@+id/xlistview_header_progressbar"            android:layout_width="30dp"            android:layout_height="30dp"            android:layout_alignLeft="@id/xlistview_header_text"            android:layout_centerVertical="true"            android:layout_marginLeft="-40dp"            android:visibility="invisible" />    </RelativeLayout></LinearLayout>

9.strings

<?xml version="1.0" encoding="utf-8"?><resources>    <string name="app_name">我的上拉加载下拉刷新Demo</string>    <string name="action_settings">Settings</string>    <string name="hello_world">Hello world!</string>    <string name="xlistview_header_hint_normal">下拉刷新</string>    <string name="xlistview_header_hint_ready">松开刷新数据</string>    <string name="xlistview_header_hint_loading">正在加载...</string>    <string name="xlistview_header_last_time">上次更新时间:</string>    <string name="xlistview_footer_hint_normal">查看更多</string>    <string name="xlistview_footer_hint_ready">松开载入更多</string></resources>


0 0
原创粉丝点击