需求:项目中的消息列表界面要求实现类似sina微博的下拉刷新;

思路:一般的消息列表为ListView类型,将list加载到adapter中,再将adapter加载到 ListView中,从而实现消息列表的展示。而下拉刷新要求给消息列表加一个头部,其中有图片(向上/向下箭头)和提示字样(下拉刷新/松开刷新),从 而我们需要做的事情:1.需要做一个head.xm来实现头部的样式定义;2.需要自定义一个继承了ListView的MsgListView,在该类中 将head加在MsgListView对象的头部;3.将原有的消息界面布局文件中的ListView改为 cn.xd.microblogging.tools.MsgListView(包名.MsgListView);4.将原有的消息界面后台代码中创建的 ListView对象改为MsgListView对象,注意消息界面Activity要继承ListActivity,并且实现其刷新监听。

说明:实现下拉刷新很简单,仅需要4个文件:MsgRcvListActivity.java(消息列表界面的后台文件,真正的刷新动作在这里完成,下拉刷新相关code下面列出),msgrcvlistactivity.xml(消息列表界面的前台文件,下拉刷新相关code下面列出),MsgListView.java(本文件拿来主义即可不用改,下拉刷新自定义的列表类,监听并执行下拉刷新、松开刷新、正在刷新、完成刷新等状态的改变,但真正的刷新动作不在这里完成,完整code下面列出),head.xml(本文件拿来主义即可不用改,下拉刷新的样式定义文件,包括向上、向下箭头,刷新状态提示等,完整code下面列出);

效果

代码

1.MsgRcvListActivity.java :

  1. public class MsgRcvListActivity extends ListActivity {//注意:要继承ListActivity
  2. …………//变量定义,略
  3. MsgListView list;
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.msgrcvlistactivity);
  8. list=(MsgListView)findViewById(android.R.id.list);//继承ListActivity,id要写成android.R.id.list,否则报异常
  9. …………//其他代码,略
  10. //刷新监听,此处实现真正刷新
  11. list.setonRefreshListener(new OnRefreshListener() {
  12. public void onRefresh() {
  13. new AsyncTask<Void, Void, Void>() {
  14. protected Void doInBackground(Void... params) {
  15. try {
  16. Thread.sleep(1000);
  17. } catch (Exception e) {
  18. e.printStackTrace();
  19. }
  20. return null;
  21. }
  22. @Override
  23. protected void onPostExecute(Void result) {
  24. adapter.notifyDataSetChanged();
  25. new MsgLoad().execute();//刷新监听中,真正执行刷新动作
  26. list.onRefreshComplete();
  27. }
  28. }.execute(null);
  29. }
  30. });
  31. list.setItemsCanFocus(false);
  32. list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
  33. }
  34. …………//其他代码,略
  35. public class MsgLoad extends AsyncTask<Void, Void, List<MsgBean>> {
  36. …………//其他代码,略
  37. }
  38. }

2.msgrcvlistactivity.xml:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. >
  7. <LinearLayout android:orientation="vertical"
  8. android:layout_width="fill_parent"
  9. android:layout_height="fill_parent"
  10. android:background="#000000">
  11. //将ListView改为包名.自定义的列表类名,MsgListView.java代码见后,此代码不需改通用,下拉刷新相关即此处,其他无关
  12. <cn.xd.microblogging.tools.MsgListView
  13. android:id="@android:id/list"
  14. android:layout_height="wrap_content"
  15. android:layout_width="fill_parent"
  16. android:layout_weight="1.0"
  17. android:drawSelectorOnTop="false"
  18. android:scrollbars="vertical"
  19. android:fadingEdgeLength="0dip"
  20. android:divider="@drawable/line"
  21. android:dividerHeight="3.0dip"
  22. android:cacheColorHint="#00000000"
  23. android:paddingBottom="40dp"/>
  24. </LinearLayout>
  25. <LinearLayout
  26. android:id="@+id/msg_list_load"
  27. android:layout_width="fill_parent"
  28. android:layout_height="fill_parent" >
  29. <LinearLayout android:id="@android:id/empty"
  30. android:layout_width="fill_parent"
  31. android:layout_height="fill_parent" >
  32. <include
  33. android:id="@android:id/empty"
  34. layout="@layout/empty_loading"
  35. android:layout_width="fill_parent"
  36. android:layout_height="fill_parent" />
  37. </LinearLayout>
  38. </LinearLayout>
  39. </RelativeLayout>

3.MsgListView.java,拷进项目基本不需改:

  1. package cn.xd.microblogging.tools;
  2. import java.util.Date;
  3. import cn.xd.microblogging.R;
  4. import android.content.Context;
  5. import android.util.AttributeSet;
  6. import android.util.Log;
  7. import android.view.LayoutInflater;
  8. import android.view.MotionEvent;
  9. import android.view.View;
  10. import android.view.ViewGroup;
  11. import android.view.animation.LinearInterpolator;
  12. import android.view.animation.RotateAnimation;
  13. import android.widget.AbsListView;
  14. import android.widget.BaseAdapter;
  15. import android.widget.ImageView;
  16. import android.widget.LinearLayout;
  17. import android.widget.ListView;
  18. import android.widget.AbsListView.OnScrollListener;
  19. import android.widget.ProgressBar;
  20. import android.widget.TextView;
  21. /**
  22. *
  23. * 自定义MsgListView,继承了ListView,
  24. * 但填充了listview的头部,即下拉刷新样式,并实现其功能
  25. * @author yanbo
  26. *
  27. */
  28. public class MsgListView extends ListView implements OnScrollListener {
  29. private final static int RELEASE_To_REFRESH = 0;
  30. private final static int PULL_To_REFRESH = 1;
  31. private final static int REFRESHING = 2;
  32. private final static int DONE = 3;
  33. private LayoutInflater inflater;
  34. private LinearLayout headView; // 头部
  35. private TextView tipsTextview;//下拉刷新
  36. private TextView lastUpdatedTextView;//最新更新
  37. private ImageView arrowImageView;//箭头
  38. private ProgressBar progressBar;//刷新进度条
  39. private RotateAnimation animation;//旋转特效 刷新中箭头翻转 向下变向上
  40. private RotateAnimation reverseAnimation;
  41. // 用于保证startY的值在一个完整的touch事件中只被记录一次
  42. private boolean isRecored;
  43. private int headContentWidth;//头部宽度
  44. private int headContentHeight;//头部高度
  45. private int startY;//高度起始位置,用来记录与头部距离
  46. private int firstItemIndex;//列表中首行索引,用来记录其与头部距离
  47. private int state;//下拉刷新中、松开刷新中、正在刷新中、完成刷新
  48. private boolean isBack;
  49. public OnRefreshListener refreshListener;//刷新监听
  50. private final static String TAG = "abc";
  51. public MsgListView(Context context, AttributeSet attrs) {
  52. super(context, attrs);
  53. init(context);
  54. }
  55. private void init(Context context) {
  56. inflater = LayoutInflater.from(context);
  57. headView = (LinearLayout) inflater.inflate(R.layout.head, null);//listview拼接headview
  58. arrowImageView = (ImageView) headView
  59. .findViewById(R.id.head_arrowImageView);//headview中各view
  60. arrowImageView.setMinimumWidth(50);
  61. arrowImageView.setMinimumHeight(50);
  62. progressBar = (ProgressBar) headView
  63. .findViewById(R.id.head_progressBar);//headview中各view
  64. tipsTextview = (TextView) headView.findViewById(R.id.head_tipsTextView);//headview中各view
  65. lastUpdatedTextView = (TextView) headView
  66. .findViewById(R.id.head_lastUpdatedTextView);//headview中各view
  67. measureView(headView);
  68. headContentHeight = headView.getMeasuredHeight();//头部高度
  69. headContentWidth = headView.getMeasuredWidth();//头部宽度
  70. headView.setPadding(0, -1 * headContentHeight, 0, 0);//setPadding(int left, int top, int right, int bottom)
  71. headView.invalidate();//Invalidate the whole view
  72. Log.v("size", "width:" + headContentWidth + " height:"
  73. + headContentHeight);
  74. addHeaderView(headView);//添加进headview
  75. setOnScrollListener(this);//滚动监听
  76. animation = new RotateAnimation(0, -180,
  77. RotateAnimation.RELATIVE_TO_SELF, 0.5f,
  78. RotateAnimation.RELATIVE_TO_SELF, 0.5f);
  79. animation.setInterpolator(new LinearInterpolator());
  80. animation.setDuration(250);
  81. animation.setFillAfter(true);//特效animation设置
  82. reverseAnimation = new RotateAnimation(-180, 0,
  83. RotateAnimation.RELATIVE_TO_SELF, 0.5f,
  84. RotateAnimation.RELATIVE_TO_SELF, 0.5f);
  85. reverseAnimation.setInterpolator(new LinearInterpolator());
  86. reverseAnimation.setDuration(250);
  87. reverseAnimation.setFillAfter(true);//特效reverseAnimation设置
  88. }
  89. public void onScroll(AbsListView arg0, int firstVisiableItem, int arg2,//滚动事件
  90. int arg3) {
  91. firstItemIndex = firstVisiableItem;//得到首item索引
  92. }
  93. public void onScrollStateChanged(AbsListView arg0, int arg1) {
  94. }
  95. public boolean onTouchEvent(MotionEvent event) {//触摸事件
  96. switch (event.getAction()) {
  97. case MotionEvent.ACTION_DOWN://手按下  对应下拉刷新状态
  98. if (firstItemIndex == 0 && !isRecored) {//如果首item索引为0,且尚未记录startY,则在下拉时记录之,并执行isRecored = true;
  99. startY = (int) event.getY();
  100. isRecored = true;
  101. Log.v(TAG, "在down时候记录当前位置‘");
  102. }
  103. break;
  104. case MotionEvent.ACTION_UP://手松开  对应松开刷新状态
  105. if (state != REFRESHING) {//手松开有4个状态:下拉刷新、松开刷新、正在刷新、完成刷新。如果当前不是正在刷新
  106. if (state == DONE) {//如果当前是完成刷新,什么都不做
  107. }
  108. if (state == PULL_To_REFRESH) {//如果当前是下拉刷新,状态设为完成刷新(意即下拉刷新中就松开了,实际未完成刷新),执行changeHeaderViewByState()
  109. state = DONE;
  110. changeHeaderViewByState();
  111. Log.v(TAG, "由下拉刷新状态,到done状态");
  112. }
  113. if (state == RELEASE_To_REFRESH) {//如果当前是松开刷新,状态设为正在刷新(意即松开刷新中松开手,才是真正地刷新),执行changeHeaderViewByState()
  114. state = REFRESHING;
  115. changeHeaderViewByState();
  116. onRefresh();//真正刷新,所以执行onrefresh,执行后状态设为完成刷新
  117. Log.v(TAG, "由松开刷新状态,到done状态");
  118. }
  119. }
  120. isRecored = false;//手松开,则无论怎样,可以重新记录startY,因为只要手松开就认为一次刷新已完成
  121. isBack = false;
  122. break;
  123. case MotionEvent.ACTION_MOVE://手拖动,拖动过程中不断地实时记录当前位置
  124. int tempY = (int) event.getY();
  125. if (!isRecored && firstItemIndex == 0) {//如果首item索引为0,且尚未记录startY,则在拖动时记录之,并执行isRecored = true;
  126. Log.v(TAG, "在move时候记录下位置");
  127. isRecored = true;
  128. startY = tempY;
  129. }
  130. if (state != REFRESHING && isRecored) {//如果状态不是正在刷新,且已记录startY:tempY为拖动过程中一直在变的高度,startY为拖动起始高度
  131. // 可以松手去刷新了
  132. if (state == RELEASE_To_REFRESH) {//如果状态是松开刷新
  133. // 往上推了,推到了屏幕足够掩盖head的程度,但是还没有推到全部掩盖的地步
  134. if ((tempY - startY < headContentHeight)//如果实时高度大于起始高度,且两者之差小于头部高度,则状态设为下拉刷新
  135. && (tempY - startY) > 0) {
  136. state = PULL_To_REFRESH;
  137. changeHeaderViewByState();
  138. Log.v(TAG, "由松开刷新状态转变到下拉刷新状态");
  139. }
  140. // 一下子推到顶了
  141. else if (tempY - startY <= 0) {//如果实时高度小于等于起始高度了,则说明到顶了,状态设为完成刷新
  142. state = DONE;
  143. changeHeaderViewByState();
  144. Log.v(TAG, "由松开刷新状态转变到done状态");
  145. }
  146. // 往下拉了,或者还没有上推到屏幕顶部掩盖head的地步
  147. else {//如果当前拖动过程中既没有到下拉刷新的地步,也没有到完成刷新(到顶)的地步,则保持松开刷新状态
  148. // 不用进行特别的操作,只用更新paddingTop的值就行了
  149. }
  150. }
  151. // 还没有到达显示松开刷新的时候,DONE或者是PULL_To_REFRESH状态
  152. if (state == PULL_To_REFRESH) {//如果状态是下拉刷新
  153. // 下拉到可以进入RELEASE_TO_REFRESH的状态
  154. if (tempY - startY >= headContentHeight) {//如果实时高度与起始高度之差大于等于头部高度,则状态设为松开刷新
  155. state = RELEASE_To_REFRESH;
  156. isBack = true;
  157. changeHeaderViewByState();
  158. Log.v(TAG, "由done或者下拉刷新状态转变到松开刷新");
  159. }
  160. // 上推到顶了
  161. else if (tempY - startY <= 0) {//如果实时高度小于等于起始高度了,则说明到顶了,状态设为完成刷新
  162. state = DONE;
  163. changeHeaderViewByState();
  164. Log.v(TAG, "由DOne或者下拉刷新状态转变到done状态");
  165. }
  166. }
  167. // done状态下
  168. if (state == DONE) {//如果状态是完成刷新
  169. if (tempY - startY > 0) {//如果实时高度大于起始高度了,则状态设为下拉刷新
  170. state = PULL_To_REFRESH;
  171. changeHeaderViewByState();
  172. }
  173. }
  174. // 更新headView的size
  175. if (state == PULL_To_REFRESH) {//如果状态是下拉刷新,更新headview的size           ?
  176. headView.setPadding(0, -1 * headContentHeight
  177. + (tempY - startY), 0, 0);
  178. headView.invalidate();
  179. }
  180. // 更新headView的paddingTop
  181. if (state == RELEASE_To_REFRESH) {//如果状态是松开刷新,更新 headview的paddingtop      ?
  182. headView.setPadding(0, tempY - startY - headContentHeight,
  183. 0, 0);
  184. headView.invalidate();
  185. }
  186. }
  187. break;
  188. }
  189. return super.onTouchEvent(event);
  190. }
  191. // 当状态改变时候,调用该方法,以更新界面
  192. private void changeHeaderViewByState() {
  193. switch (state) {
  194. case RELEASE_To_REFRESH:
  195. arrowImageView.setVisibility(View.VISIBLE);
  196. progressBar.setVisibility(View.GONE);
  197. tipsTextview.setVisibility(View.VISIBLE);
  198. lastUpdatedTextView.setVisibility(View.VISIBLE);
  199. arrowImageView.clearAnimation();
  200. arrowImageView.startAnimation(animation);
  201. tipsTextview.setText("松开刷新");
  202. Log.v(TAG, "当前状态,松开刷新");
  203. break;
  204. case PULL_To_REFRESH:
  205. progressBar.setVisibility(View.GONE);
  206. tipsTextview.setVisibility(View.VISIBLE);
  207. lastUpdatedTextView.setVisibility(View.VISIBLE);
  208. arrowImageView.clearAnimation();
  209. arrowImageView.setVisibility(View.VISIBLE);
  210. // 是由RELEASE_To_REFRESH状态转变来的
  211. if (isBack) {
  212. isBack = false;
  213. arrowImageView.clearAnimation();
  214. arrowImageView.startAnimation(reverseAnimation);
  215. tipsTextview.setText("下拉刷新");
  216. } else {
  217. tipsTextview.setText("下拉刷新");
  218. }
  219. Log.v(TAG, "当前状态,下拉刷新");
  220. break;
  221. case REFRESHING:
  222. headView.setPadding(0, 0, 0, 0);
  223. headView.invalidate();
  224. progressBar.setVisibility(View.VISIBLE);
  225. arrowImageView.clearAnimation();
  226. arrowImageView.setVisibility(View.GONE);
  227. tipsTextview.setText("正在刷新...");
  228. lastUpdatedTextView.setVisibility(View.VISIBLE);
  229. Log.v(TAG, "当前状态,正在刷新...");
  230. break;
  231. case DONE:
  232. headView.setPadding(0, -1 * headContentHeight, 0, 0);
  233. headView.invalidate();
  234. progressBar.setVisibility(View.GONE);
  235. arrowImageView.clearAnimation();
  236. arrowImageView
  237. .setImageResource(R.drawable.ic_pulltorefresh_arrow);
  238. tipsTextview.setText("下拉刷新");
  239. lastUpdatedTextView.setVisibility(View.VISIBLE);
  240. Log.v(TAG, "当前状态,done");
  241. break;
  242. }
  243. }
  244. public void setonRefreshListener(OnRefreshListener refreshListener) {
  245. this.refreshListener = refreshListener;
  246. }
  247. public interface OnRefreshListener {
  248. public void onRefresh();
  249. }
  250. public void onRefreshComplete() {
  251. state = DONE;
  252. lastUpdatedTextView.setText("最近更新:" + new Date().toLocaleString());//刷新完成时,头部提醒的刷新日期
  253. changeHeaderViewByState();
  254. }
  255. private void onRefresh() {
  256. if (refreshListener != null) {
  257. refreshListener.onRefresh();
  258. }
  259. }
  260. //此方法直接照搬自网络上的一个下拉刷新的demo,此处是“估计”headView的width以及height
  261. private void measureView(View child) {
  262. ViewGroup.LayoutParams p = child.getLayoutParams();
  263. if (p == null) {
  264. p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
  265. ViewGroup.LayoutParams.WRAP_CONTENT);
  266. }
  267. int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
  268. int lpHeight = p.height;
  269. int childHeightSpec;
  270. if (lpHeight > 0) {
  271. childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
  272. MeasureSpec.EXACTLY);
  273. } else {
  274. childHeightSpec = MeasureSpec.makeMeasureSpec(0,
  275. MeasureSpec.UNSPECIFIED);
  276. }
  277. child.measure(childWidthSpec, childHeightSpec);
  278. }
  279. }

4.head.xml,拷进项目基本不需改:

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <!-- ListView的头部 -->
    3. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    4. android:id="@+id/head_rootLayout"
    5. android:layout_width="fill_parent"
    6. android:layout_height="wrap_content" >
    7. <!-- 内容 -->
    8. <RelativeLayout
    9. xmlns:android="http://schemas.android.com/apk/res/android"
    10. android:id="@+id/head_contentLayout"
    11. android:layout_width="fill_parent"
    12. android:layout_height="wrap_content"
    13. android:paddingLeft="30dp" >
    14. <!-- 箭头图像、进度条 -->
    15. <FrameLayout
    16. android:layout_width="wrap_content"
    17. android:layout_height="wrap_content"
    18. android:layout_alignParentLeft="true"
    19. android:layout_centerVertical="true" >
    20. <!-- 箭头 -->
    21. <ImageView
    22. android:id="@+id/head_arrowImageView"
    23. android:layout_width="wrap_content"
    24. android:layout_height="wrap_content"
    25. android:layout_gravity="center"
    26. android:src="@drawable/ic_pulltorefresh_arrow"
    27. android:contentDescription="@string/app_name"/>
    28. <!-- 进度条 -->
    29. <ProgressBar
    30. android:id="@+id/head_progressBar"
    31. style="?android:attr/progressBarStyleSmall"
    32. android:layout_width="wrap_content"
    33. android:layout_height="wrap_content"
    34. android:layout_gravity="center"
    35. android:visibility="gone" />
    36. </FrameLayout>
    37. <!-- 提示、最近更新 -->
    38. <LinearLayout
    39. android:layout_width="wrap_content"
    40. android:layout_height="wrap_content"
    41. android:layout_centerHorizontal="true"
    42. android:gravity="center_horizontal"
    43. android:orientation="vertical" >
    44. <!-- 提示 -->
    45. <TextView
    46. android:id="@+id/head_tipsTextView"
    47. android:layout_width="wrap_content"
    48. android:layout_height="wrap_content"
    49. android:text="@string/pulltorefresh"
    50. android:textColor="#ffffff"
    51. android:textSize="20sp" />
    52. <!-- 最近更新 -->
    53. <TextView
    54. android:id="@+id/head_lastUpdatedTextView"
    55. android:layout_width="wrap_content"
    56. android:layout_height="wrap_content"
    57. android:text="@string/lastupdate"
    58. android:textColor="#cc6600"
    59. android:textSize="10sp" />
    60. </LinearLayout>
    61. </RelativeLayout>
    62. </LinearLayout>

Android中实现下拉刷新的更多相关文章

  1. 【转载】Android中ListView下拉刷新的实现

    在网上看到一个下拉刷新的例子,很的很棒,转载和更多的人分享学习 原文:http://blog.csdn.net/loongggdroid/article/details/9385535 ListVie ...

  2. Android中ListView下拉刷新的实现

    ListView中的下拉刷新是非常常见的,也是经常使用的,看到有很多同学想要,那我就整理一下,供大家参考.那我就不解释,直接上代码了. 这里需要自己重写一下ListView,重写代码如下: packa ...

  3. android中listView下拉刷新

    Android的ListView是应用最广的一个组件,功能强大,扩展性灵活(不局限于ListView本身一个类),前面的文章有介绍分组,拖拽,3D立体,游标,圆角,而今天我们要介绍的是另外一个扩展Li ...

  4. Android之自定义控件-下拉刷新

    实现效果: 图片素材:         --> 首先, 写先下拉刷新时的刷新布局 pull_to_refresh.xml: <resources> <string name=& ...

  5. Android之XListView下拉刷新,更新网络美女图

    一.简介:   下拉刷新是一种特定的手动刷新交互,和其他的同类操作不同的地方在于它采用了更加直觉的下拉操作,所以它的交互足够清晰明显. 下拉刷新主要用在类似ListView这样的控件,设计下拉刷新有三 ...

  6. Android 使用官方下拉刷新

    网上关于下拉刷新的文章也不少,不过都太长了,看得挺难受的.恰好发现了官方的下拉刷新库,而且效果还是不错的,简洁美观,用得也挺方便. 下面是效果图: 我的好友原来是空的,刷新后多了两个. 使用还是挺方便 ...

  7. Android PullToRrefresh 自定义下拉刷新动画 (listview、scrollview等)

    PullToRefreshScrollView 自定义下拉刷新动画,只需改一处. 以下部分转载自http://blog.csdn.net/superjunjin/article/details/450 ...

  8. Android——谷歌官方下拉刷新控件SwipeRefreshLayout(转)

    转自:http://blog.csdn.net/zouzhigang96/article/details/50476402 版权声明:本文为博主原创文章,未经博主允许不得转载. 前言: 如今谷歌推出了 ...

  9. Android SwipeRefreshLayout 官方下拉刷新控件介绍

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24521483 下面App基本都有下拉刷新的功能,以前基本都使用XListView ...

随机推荐

  1. SQL查询今天、昨天、7天内、30天【转】

    SQL查询今天.昨天.7天内.30天 今天的所有数据:select * from 表名 where DateDiff(dd,datetime类型字段,getdate())=0 昨天的所有数据:sele ...

  2. Memento 备忘录 快照模式 MD

    备忘录模式 简介 在不破坏封装的前提下,捕获一个对象的[内部状态],并在该对象之外保存这个状态,这样以后就可以将该对象恢复到原先保存的状态. 角色: 发起人Originator:要被备份的成员,它提供 ...

  3. Ngxtop-Nginx日志实时分析利器

    ngxtop实时解析nginx访问日志,并且将处理结果输出到终端,功能类似于系统命令top,所以这个软件起名ngxtop.有了ngxtop,你可以实时了解到当前nginx的访问状况,再也不需要tail ...

  4. 【Nodejs】理想论坛帖子爬虫1.01

    用Nodejs把Python实现过的理想论坛爬虫又实现了一遍,但是怎么判断所有回调函数都结束没有好办法,目前的spiderCount==spiderFinished判断法在多页情况下还是会提前中止. ...

  5. uploadify的java应用

    API:http://www.uploadify.com/documentation/ 下载地址:http://www.uploadify.com/ 这几天查看插件,发现uploadify插件做不错, ...

  6. maven command to create your application

    How do I make my first Maven project? We are going to jump headlong into creating your first Maven p ...

  7. Oracle综合数据库管理命令集

    sqlplus SANKYU/SANKYU@ORADB_192.168.25.235 cmd: exp .......(最后不要加;号)--sankyuexp SANKYU/SANKYU@SUNNY ...

  8. AngularJS是什么?

    AngularJS扩展了HTML? 看了几天AngularJS的各种中文教程,一直没有理解AngularJS是做什么的. 直到今天了英文文档,才有了初步了解. HTML是静态语言. JavaScrip ...

  9. 嵌入式web服务器-thttpd

    交叉编译thttpd http://lakie.blog.163.com/blog/static/45185220201162910432330/ thttpd安装与调试 http://blog.cs ...

  10. iOS禁用系统休眠

    [UIApplicationsharedApplication].idleTimeDisabled= YES