/** 当所有的刷新逻辑完成后,记录调用一下,否则你的ListView将一直处于正在刷新状态。 */ public void finishRefreshing() { if (log.isDebugEnabled()) { log.debug("Finishing refreshing status ..."); } preferences.edit().putLong(UPDATED_AT + mId, System.currentTimeMillis()).commit(); hideHeader(); }
/** 更新下拉头中的信息。 */ private void updateHeaderView() { if (log.isDebugEnabled()) { log.debug( "updateHeaderView, current status :" + currentStatus + ", last status :" + lastStatus); } if (lastStatus != currentStatus) { if (currentStatus == STATUS_PULL_TO_REFRESH) { description.setText(getResources().getString(R.string.pull_to_refresh)); arrow.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); rotateArrow(); } else if (currentStatus == STATUS_RELEASE_TO_REFRESH) { description.setText(getResources().getString(R.string.release_to_refresh)); arrow.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); rotateArrow(); } else if (currentStatus == STATUS_REFRESHING) { description.setText(getResources().getString(R.string.refreshing)); progressBar.setVisibility(View.VISIBLE); arrow.clearAnimation(); arrow.setVisibility(View.GONE); } refreshUpdatedAtValue(); } }
public void hideHeader() { if (log.isDebugEnabled()) { log.debug("Exitting refreshing status ..."); } // currentStatus = STATUS_REFRESH_FINISHED; // updateHeaderView(); if (this.headerLayoutParams != null) { new HideHeaderTask().execute(); } else { this.pendingTasks.add(new HideHeaderTask()); } }
protected void setOnRefreshing(boolean callListener) { if (log.isDebugEnabled()) { log.debug("Set on refreshing status ..."); } currentStatus = STATUS_REFRESHING; updateHeaderView(); if (this.headerLayoutParams != null) { new RefreshingTask(callListener).execute(); } else { this.pendingTasks.add(new RefreshingTask(callListener)); } }
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { if (log.isDebugEnabled()) { log.debug("onLayout ..."); } super.onLayout(changed, l, t, r, b); if (changed && (headerLayoutParams == null)) { hideHeaderHeight = -header.getHeight(); if (log.isDebugEnabled()) { log.debug("init Layout params, hideHeaderHeight :" + hideHeaderHeight); } headerLayoutParams = (MarginLayoutParams) header.getLayoutParams(); headerLayoutParams.topMargin = hideHeaderHeight; if (!this.pendingTasks.isEmpty()) { for (AsyncTask<Void, Integer, Integer> task : this.pendingTasks) { task.execute(); } this.pendingTasks.clear(); } } else { if (log.isDebugEnabled()) { log.debug("onLayout, hideHeaderHeight :" + headerLayoutParams.topMargin); } // header.setLayoutParams(headerLayoutParams); } }
public class ImprorDataProcessDialog extends BaseActivity { private static final Trace log = Trace.register(ImprorDataProcessDialog.class); // com.wxxr.callhelper.widget.MyProcesBar processbar; SeekBar processbar; TextView processtip; ArrayList<String> addperson; private Context mcontext; private int requestcode; private String tip; Handler hanler = new Handler() { public void handleMessage(android.os.Message msg) { if (processbar.getMax() != 0) { processtip.setText(tip + (processbar.getProgress() * 100 / processbar.getMax()) + "%"); } }; }; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.import_sysmes_processbar); requestcode = getIntent().getIntExtra(Constant.REQUEST_CODE, -1); processbar = (SeekBar) findViewById(R.id.my_progressbar1); processtip = (TextView) findViewById(R.id.my_progressbar_tip); addperson = getIntent().getStringArrayListExtra(Constant.IMPORT_OR_DEL_NUMS); mcontext = this.getBaseContext(); if (getIntent().getStringExtra(Constant.IS_IMPORT_NUMS).length() > 0) { tip = "正在导入联系人"; new ImportSysmes().execute(); } else { tip = "正在导出联系人"; findViewById(R.id.gd_iv_titlebar_icon) .setBackgroundResource(R.drawable.gd_dialog_private_contacts_icon_out); new ExportToSysmes().execute(); } } @Override public void onBackPressed() { // TODO Auto-generated method stub // super.onBackPressed(); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); } class ImportSysmes extends AsyncTask<Context, Void, Void> { @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); finish(); } @Override protected Void doInBackground(Context... params) { int size = addperson.size(); int total = 0; // 计算信息总数 for (int i = 0; i < size; i++) { total = +Tools.getSmsOfPhoneNum(mcontext, null, addperson.get(i)); } processbar.setMax(total); processbar.setProgress(1); // 开始导入,不要用列表,避免内存不足 IPrivateSMService service = getService(IPrivateSMService.class); boolean needbell = service.isRingBellWhenReceiving(); service.setRingBellWhenReceiving(false); int curvalue = 0; for (int i = 0; i < size; i++) { String phonenum = addperson.get(i); if (phonenum.length() > 10) { phonenum = phonenum.substring(phonenum.length() - 11, phonenum.length()); } Cursor c = mcontext .getApplicationContext() .getContentResolver() .query( Sms.CONTENT_URI, null, Sms.ADDRESS + " like '%" + phonenum + "%'", null, null); if (c.moveToFirst()) { if (log.isDebugEnabled()) { log.debug("find sms of ==========", phonenum); } String threadid = c.getString(c.getColumnIndex(Sms.THREAD_ID)); Cursor cursor = mcontext .getApplicationContext() .getContentResolver() .query(Sms.CONTENT_URI, null, Sms.THREAD_ID + " = " + threadid, null, null); ContentResolver contentResolver = mcontext.getApplicationContext().getContentResolver(); StringBuffer sb = new StringBuffer(); if (cursor.moveToFirst()) { if (log.isDebugEnabled()) { log.debug("ImprorDataProcessDialog cont==", cursor.getCount()); } int bodyindex = cursor.getColumnIndex(Sms.BODY); int dateindex = cursor.getColumnIndex(Sms.DATE); int typeindex = cursor.getColumnIndex(Sms.TYPE); int numindex = cursor.getColumnIndex(Sms.ADDRESS); int idindex = cursor.getColumnIndex(Sms._ID); do { TextMessageBean bean = new TextMessageBean(); String strnum = cursor.getString(numindex); String body = cursor.getString(bodyindex); // 回执和漏电短信都不用要导入 if (SMSFilter.isSmsFailHuizhi(body, strnum) || SMSFilter.isSmsOKHuizhi(body, strnum) || getService(ILouHuaHuizhiService.class).isMatch(body, strnum)) { } else { // 去除前缀,只保留后边的11位 if (strnum.endsWith(phonenum)) { strnum = phonenum; } int type = cursor.getInt(typeindex); if (type == 1) { bean.setMo(strnum); } else if (type == 2) { bean.setMt(strnum); } bean.setNumber(strnum); bean.setTimestamp(cursor.getLong(dateindex)); bean.setContent(body); service.onSMReceived(bean, false, true); sb.append(cursor.getString(idindex)).append(","); } curvalue++; processbar.setProgress(curvalue); processbar.setMax(total); hanler.sendEmptyMessage(0); if (log.isDebugEnabled()) { log.debug("ImprorDataProcessDialog text==", cursor.getString(bodyindex)); } } while (cursor.moveToNext()); cursor.close(); if (sb.toString().length() > 0) { sb.deleteCharAt(sb.length() - 1); String ids = sb.toString(); contentResolver.delete(Sms.CONTENT_URI, Sms._ID + " in (" + ids + ")", null); } } } else { if (log.isDebugEnabled()) { log.debug("not find sms of $$$$$$$$ ", phonenum); } } c.close(); service.setRingBellWhenReceiving(needbell); setResult(requestcode); } return null; } } class ExportToSysmes extends AsyncTask<Context, Void, Void> { @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); } @Override protected void onPostExecute(Void result) { showMessageBox("成功导出联系人信息"); super.onPostExecute(result); finish(); } @Override protected Void doInBackground(Context... params) { int size = addperson.size(); int total = 0; // 计算信息总数 for (int i = 0; i < size; i++) { List<TextMessageBean> list = getService(IPrivateSMService.class).getAllMessageOf(addperson.get(i)); if (list != null) { total += list.size(); list = null; } } processbar.setMax(total); processbar.setProgress(1); int curcount = 0; for (int j = 0; j < size; j++) { String num = addperson.get(j); List<TextMessageBean> list = getService(IPrivateSMService.class).getAllMessageOf(num); if (list != null) { Tools.remove_to_sysbox.put(num, ""); int leng = list.size(); for (int k = 0; k < leng; k++) { Tools.inserToSysmsgOne(list.get(k), mcontext); curcount++; hanler.sendEmptyMessage(0); processbar.setProgress(curcount); } getService(IPrivateSMService.class).deleteMessage(num, j == size - 1); } getService(IPrivateSMService.class).removePrivateNumber(num); } return null; } } }
public class SiMiSettingActivity extends BaseActivity implements OnClickListener { private static final Trace log = Trace.register(SiMiSettingActivity.class); ImageView iv_kaiguan; ImageView iv_finish; boolean lMRFlag = true; TextView tv_update; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.simiren_setting_dialog); iv_kaiguan = (ImageView) findViewById(R.id.iv_simi_kaiguan); tv_update = (TextView) findViewById(R.id.tv_update); iv_kaiguan.setOnClickListener(this); tv_update.setOnClickListener(this); try { this.lMRFlag = getService(IPrivateSMService.class).isRingBellWhenReceiving() == false; if (this.lMRFlag) { iv_kaiguan.setBackgroundResource(R.drawable.close); } else { iv_kaiguan.setBackgroundResource(R.drawable.open); } } catch (Throwable t) { } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.iv_simi_kaiguan: if (lMRFlag) { iv_kaiguan.setBackgroundResource(R.drawable.open); lMRFlag = false; doUpdate(true); } else { iv_kaiguan.setBackgroundResource(R.drawable.close); lMRFlag = true; doUpdate(false); } break; case R.id.iv_finish: finish(); break; case R.id.tv_update: Intent intent = new Intent(); // intent.putExtra("from_simi", "update_password"); intent.setClass(SiMiSettingActivity.this, SiMiSuoHomePasswordActivity.class); intent.putExtra("resetpass", "yes"); startActivity(intent); // finish(); break; } } private void doUpdate(final boolean bool) { new CMProgressMonitor(this) { @Override protected void handleFailed(Throwable cause) { log.error("Caught exception when sending SM message", cause); showMessageBox("提醒设置失败,原因:[" + cause.getLocalizedMessage() + "]"); } @Override protected void handleDone(Object returnVal) { showMessageBox("提醒设置成功"); } /* * (non-Javadoc) * * @see com.wxxr.callhelper.CMProgressMonitor#getDialogParams() */ @Override protected Map<String, Object> getDialogParams() { Map<String, Object> map = new HashMap<String, Object>(); map.put(DIALOG_PARAM_KEY_TITLE, "系统提示:"); map.put(DIALOG_PARAM_KEY_MESSAGE, "正在更新提醒设置,请稍侯..."); return map; } }.executeOnMonitor( new Callable<Object>() { @Override public Object call() throws Exception { getService(IPrivateSMService.class).setRingBellWhenReceiving(bool); return null; } }); } }
public void hideHeaderDirect() { if (log.isDebugEnabled()) { log.debug("Exitting refreshing status ..."); } header.setVisibility(View.GONE); }
public class RefreshableView extends LinearLayout implements OnTouchListener { private static final Trace log = Trace.register(RefreshableView.class); /** 下拉状态 */ public static final int STATUS_PULL_TO_REFRESH = 0; /** 释放立即刷新状态 */ public static final int STATUS_RELEASE_TO_REFRESH = 1; /** 正在刷新状态 */ public static final int STATUS_REFRESHING = 2; /** 刷新完成或未刷新状态 */ public static final int STATUS_REFRESH_FINISHED = 3; /** 下拉头部回滚的速度 */ public static final int SCROLL_SPEED = -20; /** 一分钟的毫秒值,用于判断上次的更新时间 */ public static final long ONE_MINUTE = 60 * 1000; /** 一小时的毫秒值,用于判断上次的更新时间 */ public static final long ONE_HOUR = 60 * ONE_MINUTE; /** 一天的毫秒值,用于判断上次的更新时间 */ public static final long ONE_DAY = 24 * ONE_HOUR; /** 一月的毫秒值,用于判断上次的更新时间 */ public static final long ONE_MONTH = 30 * ONE_DAY; /** 一年的毫秒值,用于判断上次的更新时间 */ public static final long ONE_YEAR = 12 * ONE_MONTH; /** 上次更新时间的字符串常量,用于作为SharedPreferences的键值 */ private static final String UPDATED_AT = "updated_at"; /** 下拉刷新的回调接口 */ private PullToRefreshListener mListener; /** 用于存储上次更新时间 */ private SharedPreferences preferences; /** 下拉头的View */ private View header; /** 需要去下拉刷新的ListView */ private IPullableView pullableView; /** 刷新时显示的进度条 */ private ProgressBar progressBar; /** 指示下拉和释放的箭头 */ private ImageView arrow; /** 指示下拉和释放的文字描述 */ private TextView description; /** 上次更新时间的文字描述 */ private TextView updateAt; /** 下拉头的布局参数 */ private MarginLayoutParams headerLayoutParams; /** 上次更新时间的毫秒值 */ private long lastUpdateTime; /** 为了防止不同界面的下拉刷新在上次更新时间上互相有冲突,使用id来做区分 */ private int mId = -1; /** 下拉头的高度 */ private int hideHeaderHeight; /** * 当前处理什么状态,可选值有STATUS_PULL_TO_REFRESH, STATUS_RELEASE_TO_REFRESH, STATUS_REFRESHING 和 * STATUS_REFRESH_FINISHED */ private int currentStatus = STATUS_REFRESH_FINISHED;; /** 记录上一次的状态是什么,避免进行重复操作 */ private int lastStatus = currentStatus; /** 手指按下时的屏幕纵坐标 */ private float yDown; /** 在被判定为滚动之前用户手指可以移动的最大值。 */ private int touchSlop; // /** // * 是否已加载过一次layout,这里onLayout中的初始化只需加载一次 // */ // private boolean loadOnce; /** 当前是否可以下拉,只有ListView滚动到头的时候才允许下拉 */ private boolean ableToPull; private Handler handler; private boolean pullStarted = false; private ArrayList<AsyncTask<Void, Integer, Integer>> pendingTasks = new ArrayList<AsyncTask<Void, Integer, Integer>>(); /** * 下拉刷新控件的构造函数,会在运行时动态添加一个下拉头的布局。 * * @param context * @param attrs */ public RefreshableView(Context context, AttributeSet attrs) { super(context, attrs); preferences = PreferenceManager.getDefaultSharedPreferences(context); header = LayoutInflater.from(context).inflate(R.layout.pull_to_refresh, null, true); progressBar = (ProgressBar) header.findViewById(R.id.progress_bar); arrow = (ImageView) header.findViewById(R.id.arrow_up); description = (TextView) header.findViewById(R.id.description); updateAt = (TextView) header.findViewById(R.id.updated_at); touchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); refreshUpdatedAtValue(); setOrientation(VERTICAL); addView(header, 0); } public void setHandler(Handler handler) { this.handler = handler; } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { if (log.isDebugEnabled()) { log.debug("onLayout ..."); } super.onLayout(changed, l, t, r, b); if (changed && (headerLayoutParams == null)) { hideHeaderHeight = -header.getHeight(); if (log.isDebugEnabled()) { log.debug("init Layout params, hideHeaderHeight :" + hideHeaderHeight); } headerLayoutParams = (MarginLayoutParams) header.getLayoutParams(); headerLayoutParams.topMargin = hideHeaderHeight; if (!this.pendingTasks.isEmpty()) { for (AsyncTask<Void, Integer, Integer> task : this.pendingTasks) { task.execute(); } this.pendingTasks.clear(); } } else { if (log.isDebugEnabled()) { log.debug("onLayout, hideHeaderHeight :" + headerLayoutParams.topMargin); } // header.setLayoutParams(headerLayoutParams); } } public boolean isInRefreshing() { return currentStatus == STATUS_REFRESHING; } /** 当ListView被触摸时调用,其中处理了各种下拉刷新的具体逻辑。 */ @Override public boolean onTouch(View v, MotionEvent event) { setIsAbleToPull(v, event); boolean retVal = false; if (ableToPull) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: yDown = event.getRawY(); // if(log.isDebugEnabled()){ // log.debug("Touch down, y position :"+yDown); // } break; case MotionEvent.ACTION_MOVE: float yMove = event.getRawY(); int distance = (int) (yMove - yDown); // if(log.isDebugEnabled()){ // log.debug("Touch down and move, y position :"+yMove+", move distance :"+distance); // } // 如果手指是下滑状态,并且下拉头是完全隐藏的,就屏蔽下拉事件 if (distance <= 0 && headerLayoutParams.topMargin <= hideHeaderHeight) { return false; } if (distance < touchSlop) { return false; } if (!pullStarted) { // if(log.isDebugEnabled()){ // log.debug("Pull started, touchSlop = "+touchSlop); // } pullableView.pullStarted(v); pullStarted = true; } retVal = true; if (currentStatus != STATUS_REFRESHING) { if (headerLayoutParams.topMargin > 0) { currentStatus = STATUS_RELEASE_TO_REFRESH; } else { currentStatus = STATUS_PULL_TO_REFRESH; } // 通过偏移下拉头的topMargin值,来实现下拉效果 headerLayoutParams.topMargin = (distance / 2) + hideHeaderHeight; header.setLayoutParams(headerLayoutParams); } break; case MotionEvent.ACTION_UP: default: if (pullStarted) { pullableView.pullEnded(v); pullStarted = false; retVal = true; } if (currentStatus == STATUS_RELEASE_TO_REFRESH) { // 松手时如果是释放立即刷新状态,就去调用正在刷新的任务 setOnRefreshing(true); } else if (currentStatus == STATUS_PULL_TO_REFRESH) { // 松手时如果是下拉状态,就去调用隐藏下拉头的任务 hideHeader(); } break; } // 时刻记得更新下拉头中的信息 if (currentStatus == STATUS_PULL_TO_REFRESH || currentStatus == STATUS_RELEASE_TO_REFRESH) { updateHeaderView(); // 当前正处于下拉或释放状态,要让ListView失去焦点,否则被点击的那一项会一直处于选中状态 pullableView.getView().setPressed(false); pullableView.getView().setFocusable(false); pullableView.getView().setFocusableInTouchMode(false); lastStatus = currentStatus; // 当前正处于下拉或释放状态,通过返回true屏蔽掉ListView的滚动事件 } } return retVal; } public void setOnRefreshing() { setOnRefreshing(false); } protected void setOnRefreshing(boolean callListener) { if (log.isDebugEnabled()) { log.debug("Set on refreshing status ..."); } currentStatus = STATUS_REFRESHING; updateHeaderView(); if (this.headerLayoutParams != null) { new RefreshingTask(callListener).execute(); } else { this.pendingTasks.add(new RefreshingTask(callListener)); } } /** * 给下拉刷新控件注册一个监听器。 * * @param listener 监听器的实现。 * @param id 为了防止不同界面的下拉刷新在上次更新时间上互相有冲突, 请不同界面在注册下拉刷新监听器时一定要传入不同的id。 */ public void setOnRefreshListener(PullToRefreshListener listener, int id) { mListener = listener; mId = id; } /** 当所有的刷新逻辑完成后,记录调用一下,否则你的ListView将一直处于正在刷新状态。 */ public void finishRefreshing() { if (log.isDebugEnabled()) { log.debug("Finishing refreshing status ..."); } preferences.edit().putLong(UPDATED_AT + mId, System.currentTimeMillis()).commit(); hideHeader(); } public void hideHeader() { if (log.isDebugEnabled()) { log.debug("Exitting refreshing status ..."); } // currentStatus = STATUS_REFRESH_FINISHED; // updateHeaderView(); if (this.headerLayoutParams != null) { new HideHeaderTask().execute(); } else { this.pendingTasks.add(new HideHeaderTask()); } } public void hideHeaderDirect() { if (log.isDebugEnabled()) { log.debug("Exitting refreshing status ..."); } header.setVisibility(View.GONE); } /** * 根据当前ListView的滚动状态来设定 {@link #ableToPull} * 的值,每次都需要在onTouch中第一个执行,这样可以判断出当前应该是滚动ListView,还是应该进行下拉。 * * @param event */ private void setIsAbleToPull(View view, MotionEvent event) { boolean oldVal = this.ableToPull; this.ableToPull = this.pullableView.isPullable(view, event); if (this.ableToPull) { if (oldVal == false) { yDown = event.getRawY(); } } else if (headerLayoutParams.topMargin != hideHeaderHeight) { headerLayoutParams.topMargin = hideHeaderHeight; header.setLayoutParams(headerLayoutParams); } if (pullableView.getView() instanceof ListView) { View firstChild = ((ListView) pullableView.getView()).getChildAt(0); if (firstChild != null) { int firstVisiblePos = ((ListView) pullableView.getView()).getFirstVisiblePosition(); if (firstVisiblePos == 0 && firstChild.getTop() == 0) { if (!ableToPull) { yDown = event.getRawY(); } // 如果首个元素的上边缘,距离父布局值为0,就说明ListView滚动到了最顶部,此时应该允许下拉刷新 ableToPull = true; } else { if (headerLayoutParams.topMargin != hideHeaderHeight) { headerLayoutParams.topMargin = hideHeaderHeight; header.setLayoutParams(headerLayoutParams); } ableToPull = false; } } else { // 如果ListView中没有元素,也应该允许下拉刷新 ableToPull = true; } } } /** 更新下拉头中的信息。 */ private void updateHeaderView() { if (log.isDebugEnabled()) { log.debug( "updateHeaderView, current status :" + currentStatus + ", last status :" + lastStatus); } if (lastStatus != currentStatus) { if (currentStatus == STATUS_PULL_TO_REFRESH) { description.setText(getResources().getString(R.string.pull_to_refresh)); arrow.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); rotateArrow(); } else if (currentStatus == STATUS_RELEASE_TO_REFRESH) { description.setText(getResources().getString(R.string.release_to_refresh)); arrow.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); rotateArrow(); } else if (currentStatus == STATUS_REFRESHING) { description.setText(getResources().getString(R.string.refreshing)); progressBar.setVisibility(View.VISIBLE); arrow.clearAnimation(); arrow.setVisibility(View.GONE); } refreshUpdatedAtValue(); } } /** 根据当前的状态来旋转箭头。 */ private void rotateArrow() { float pivotX = arrow.getWidth() / 2f; float pivotY = arrow.getHeight() / 2f; float fromDegrees = 0f; float toDegrees = 0f; if (currentStatus == STATUS_PULL_TO_REFRESH) { fromDegrees = 180f; toDegrees = 360f; } else if (currentStatus == STATUS_RELEASE_TO_REFRESH) { fromDegrees = 0f; toDegrees = 180f; } RotateAnimation animation = new RotateAnimation(fromDegrees, toDegrees, pivotX, pivotY); animation.setDuration(100); animation.setFillAfter(true); arrow.startAnimation(animation); } public long getLastUpdateTime() { return preferences.getLong(UPDATED_AT + mId, -1); } /** 刷新下拉头中上次更新时间的文字描述。 */ private void refreshUpdatedAtValue() { lastUpdateTime = getLastUpdateTime(); long currentTime = System.currentTimeMillis(); long timePassed = currentTime - lastUpdateTime; long timeIntoFormat; String updateAtValue; if (lastUpdateTime == -1) { updateAtValue = getResources().getString(R.string.not_updated_yet); } else if (timePassed < 0) { updateAtValue = getResources().getString(R.string.time_error); } else if (timePassed < ONE_MINUTE) { updateAtValue = getResources().getString(R.string.updated_just_now); } else if (timePassed < ONE_HOUR) { timeIntoFormat = timePassed / ONE_MINUTE; String value = timeIntoFormat + "分钟"; updateAtValue = String.format(getResources().getString(R.string.updated_at), value); } else if (timePassed < ONE_DAY) { timeIntoFormat = timePassed / ONE_HOUR; String value = timeIntoFormat + "小时"; updateAtValue = String.format(getResources().getString(R.string.updated_at), value); } else if (timePassed < ONE_MONTH) { timeIntoFormat = timePassed / ONE_DAY; String value = timeIntoFormat + "天"; updateAtValue = String.format(getResources().getString(R.string.updated_at), value); } else if (timePassed < ONE_YEAR) { timeIntoFormat = timePassed / ONE_MONTH; String value = timeIntoFormat + "个月"; updateAtValue = String.format(getResources().getString(R.string.updated_at), value); } else { timeIntoFormat = timePassed / ONE_YEAR; String value = timeIntoFormat + "年"; updateAtValue = String.format(getResources().getString(R.string.updated_at), value); } updateAt.setText(updateAtValue); } /** * 正在刷新的任务,在此任务中会去回调注册进来的下拉刷新监听器。 * * @author guolin */ class RefreshingTask extends AsyncTask<Void, Integer, Integer> { private final boolean callListener; RefreshingTask(boolean bool) { this.callListener = bool; } @Override protected Integer doInBackground(Void... params) { if (log.isDebugEnabled()) { log.debug("Execute RefreshingTask ..."); } int topMargin = headerLayoutParams.topMargin; while (true) { topMargin = topMargin + SCROLL_SPEED; if (topMargin <= 0) { topMargin = 0; break; } publishProgress(topMargin); sleep(10); } currentStatus = STATUS_REFRESHING; publishProgress(0); if (this.callListener && (mListener != null)) { mListener.onRefresh(); } return topMargin; } @Override protected void onProgressUpdate(Integer... topMargin) { if (handler != null) { handler.handle(); } updateHeaderView(); headerLayoutParams.topMargin = topMargin[0]; header.setLayoutParams(headerLayoutParams); } } interface Handler { void handle(); } /** * 隐藏下拉头的任务,当未进行下拉刷新或下拉刷新完成后,此任务将会使下拉头重新隐藏。 * * @author guolin */ class HideHeaderTask extends AsyncTask<Void, Integer, Integer> { @Override protected Integer doInBackground(Void... params) { int topMargin = headerLayoutParams.topMargin; while (true) { topMargin = topMargin + SCROLL_SPEED; if (topMargin <= hideHeaderHeight) { topMargin = hideHeaderHeight; break; } publishProgress(topMargin); sleep(10); } return topMargin; } @Override protected void onProgressUpdate(Integer... topMargin) { headerLayoutParams.topMargin = topMargin[0]; header.setLayoutParams(headerLayoutParams); } @Override protected void onPostExecute(Integer topMargin) { headerLayoutParams.topMargin = topMargin; header.setLayoutParams(headerLayoutParams); currentStatus = STATUS_REFRESH_FINISHED; } } /** * 使当前线程睡眠指定的毫秒数。 * * @param time 指定当前线程睡眠多久,以毫秒为单位 */ private void sleep(int time) { try { Thread.sleep(time); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 下拉刷新的监听器,使用下拉刷新的地方应该注册此监听器来获取刷新回调。 * * @author guolin */ public interface PullToRefreshListener { /** 刷新时会去回调此方法,在方法内编写具体的刷新逻辑。注意此方法是在子线程中调用的, 你可以不必另开线程来进行耗时操作。 */ void onRefresh(); } /** @return the pullableView */ public IPullableView getPullableView() { return pullableView; } /** @param pullableView the pullableView to set */ public void setPullableView(IPullableView pullableView) { if (pullableView == null) { throw new IllegalArgumentException("Invalid pass in view : NULL"); } this.pullableView = pullableView; addView(this.pullableView.getView()); this.pullableView.setOnTouchListener(this); } // public void setIsAbleToPull(boolean isAbleToPull) { // this.ableToPull = isAbleToPull; // } }