<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                **(一):寫在前面的話** 接著上一篇繼續更新,上一篇文章已經把FastDev4Android項目新增圖片自動無限輪播,包括項目結構已經需要進行完善的功能,那么今天我們繼續完善這個項目;今天我們會再項目添加下拉刷新組件以及組件實現講解和使用基本方法;? **(二):基本實現** 這邊我們采用繼承Listview控件來擴展下拉刷新的功能,主要在listview的頭部添加一個下拉刷新的view,然后監聽OnScrollListener滾動接口和實現onTouchEvent方法來處理。進行下拉listview滑動到指定的高度,然后接口回調加載刷新方法即可。? ![](https://box.kancloud.cn/2016-01-18_569c8eb01d528.jpg)? 效果如下:? ![](https://box.kancloud.cn/2016-01-18_569c8eb031690.jpg)? **(三):詳細實現:** 這邊主要看幾個重點地方,詳細的代碼到項目中查看即可? onTouchEvent處理方法 ~~~ /** * touch事件處理 * @param event * @return */ @Override public boolean onTouchEvent(MotionEvent event) { final int y = (int) event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mLastMotionY = y; break; case MotionEvent.ACTION_MOVE: int offsetY = (int) event.getY(); int deltY = Math.round(offsetY - mLastMotionY); mLastMotionY = offsetY; if (getFirstVisiblePosition() == 0 && mRefreshState != REFRESHING) { deltY = deltY / 2; mRefreshOriginalTopPadding += deltY; if (mRefreshOriginalTopPadding < -mRefreshViewHeight) { mRefreshOriginalTopPadding = -mRefreshViewHeight; } resetHeaderPadding(); } break; case MotionEvent.ACTION_UP: //當手指抬開得時候 進行判斷下拉的距離 ,如果>=臨界值,那么進行刷洗,否則回歸原位 if (!isVerticalScrollBarEnabled()) { setVerticalScrollBarEnabled(true); } if (getFirstVisiblePosition() == 0 && mRefreshState != REFRESHING) { if (mRefreshView.getBottom() >= mRefreshViewHeight && mRefreshState == RELEASE_TO_REFRESH) { //準備開始刷新 prepareForRefresh(); } else { // Abort refresh resetHeader(); } } break; } return super.onTouchEvent(event); } ~~~ onScrooll和onScrollStateChanged處理listview滑動過程中,實時改變頭部view(pull view)上面的數據效果顯示 ~~~ @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (mCurrentScrollState == SCROLL_STATE_TOUCH_SCROLL && mRefreshState != REFRESHING) { if (firstVisibleItem == 0) { if ((mRefreshView.getBottom() >= mRefreshViewHeight) && mRefreshState != RELEASE_TO_REFRESH) { mRefreshViewText.setText(R.string.pull_to_refresh_release_label_it); mRefreshViewImage.clearAnimation(); mRefreshViewImage.startAnimation(mFlipAnimation); mRefreshState = RELEASE_TO_REFRESH; } else if (mRefreshView.getBottom() < mRefreshViewHeight && mRefreshState != PULL_TO_REFRESH) { mRefreshViewText.setText(R.string.pull_to_refresh_pull_label_it); mRefreshViewImage.clearAnimation(); mRefreshViewImage.startAnimation(mReverseFlipAnimation); mRefreshState = PULL_TO_REFRESH; } } } if (mOnScrollListener != null) { mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); } } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { mCurrentScrollState = scrollState; if (mOnScrollListener != null) { mOnScrollListener.onScrollStateChanged(view, scrollState); } } ~~~ 使用方法如下: ~~~ package com.chinaztt.fda.test; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.Layout; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; import com.chinaztt.fda.ui.R; import com.chinaztt.fda.ui.base.BaseActivity; import com.chinaztt.fda.utils.UIUtils; import com.chinaztt.fda.widget.PullToRefreshListView; import java.util.ArrayList; import java.util.List; /** * 當前類注釋:下拉刷新,上拉加載更多組件實例 * 項目名:FastDev4Android * 包名:com.chinaztt.fda.test * 作者:江清清 on 15/10/23 11:25 * 郵箱:jiangqqlmj@163.com * QQ: 781931404 * 公司:江蘇中天科技軟件技術有限公司 */ public class PullListviewActivity extends BaseActivity{ private PullToRefreshListView lv_pull_item; private PullAdapter mPullAdapter; private LayoutInflater mInflater; private List<String> mTitles; private View load_more; private TextView load_more_tv; // listview底部加載view 顯示數據 private ProgressBar load_more_progress; // listview底部加載view 顯示進度 private LinearLayout load_next_page_layout; private Handler newHandler=new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if(msg.what==1){ refreshTitles(); UIUtils.savePullToRefreshLastUpdateAt(lv_pull_item,UIUtils.DEMO_PULL_TIME_KEY); //刷新view mPullAdapter.notifyDataSetChanged(); }else if(msg.what==2){ moreTitles(); //刷新view mPullAdapter.notifyDataSetChanged(); showToastMsgShort("加載更多數據成功..."); load_more_tv.setText("數據加載完成"); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.pull_listview_layout); lv_pull_item=(PullToRefreshListView)this.findViewById(R.id.lv_pull_item); mInflater=getLayouInflater(); //特別注意 里邊的view的控件可以根據當前的狀態 修改字符串信息 load_more = mInflater.inflate(R.layout.load_more_footview_layout, null); load_more_tv = (TextView) load_more .findViewById(R.id.load_next_page_text); load_more_progress = (ProgressBar) load_more .findViewById(R.id.load_next_page_progress); load_next_page_layout = (LinearLayout) load_more .findViewById(R.id.load_next_page_layout); //listview添加尾部 上拉加載更多view lv_pull_item.addFooterView(load_more, null, false); load_more_tv.setText("上拉加載更多數據..."); initTitles(); //初始化 上次下拉刷新的時間 UIUtils.setPullToRefreshLastUpdated(lv_pull_item,UIUtils.DEMO_PULL_TIME_KEY); mPullAdapter=new PullAdapter(); lv_pull_item.setAdapter(mPullAdapter); //listview item點擊事件處理 lv_pull_item.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { int index = position++; showToastMsgShort("點擊了第:" + index + "個item"); } }); //listview 開始下拉刷新回調函數 lv_pull_item.setOnRefreshListener(new PullToRefreshListView.OnRefreshListener() { @Override public void onRefresh() { //進行加載數據 new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(5000); newHandler.sendEmptyMessage(1); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } }); //listview 滑動 進行上拉加載更多 lv_pull_item.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) { if (lv_pull_item.getLastVisiblePosition() == (lv_pull_item .getCount() - 1)) { load_more_tv.setText("正在加載最新數據...."); //進行獲取最新數據 new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(5000); newHandler.sendEmptyMessage(2); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } } if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) { //正在滑動中,當前listview正在滑動 可以暫停圖片加載器或者其他一些耗時操作 } else { } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }); } private void initTitles(){ mTitles=new ArrayList<String>(); for(int i=0;i<20;i++){ int index=i+1; mTitles.add("當前是:"+index+""); } } private void refreshTitles(){ List<String> newTitles=new ArrayList<String>(); for(int i=0;i<5;i++){ int index=i+1; newTitles.add("新數據是:"+index+""); } newTitles.addAll(mTitles); mTitles.removeAll(mTitles); mTitles.addAll(newTitles); } private void moreTitles(){ List<String> newTitles=new ArrayList<String>(); for(int i=0;i<8;i++){ int index=i+1; newTitles.add("更多數據是:"+index+""); } mTitles.addAll(newTitles); } class PullAdapter extends BaseAdapter{ @Override public int getCount() { return mTitles.size(); } @Override public Object getItem(int position) { return mTitles.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { Hondler _Hondler=null; if(convertView==null){ _Hondler=new Hondler(); convertView=mInflater.inflate(R.layout.lv_main_item,null); _Hondler.tv_item=(TextView)convertView.findViewById(R.id.tv_item); convertView.setTag(_Hondler); }else { _Hondler=(Hondler)convertView.getTag(); } _Hondler.tv_item.setText(mTitles.get(position)); return convertView; } } static class Hondler{ TextView tv_item; } } ~~~ 以上也是PullToRefreshListView的實現重點代碼和基本使用效果,整個控件的功能實現代碼如下: ~~~ package com.chinaztt.fda.widget; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.animation.LinearInterpolator; import android.view.animation.RotateAnimation; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; import com.chinaztt.fda.ui.R; import com.chinaztt.fda.utils.Log; /** * 當前類注釋:下拉刷新,上拉加載更多組件 * 項目名:FastDev4Android * 包名:com.chinaztt.fda.widget * 作者:江清清 on 15/10/23 13:32 * 郵箱:jiangqqlmj@163.com * QQ: 781931404 * 公司:江蘇中天科技軟件技術有限公司 */ public class PullToRefreshListView extends ListView implements OnScrollListener, OnClickListener { /** * 下拉狀態 */ private static final int PULL_TO_REFRESH = 1; //下拉-默認為初始狀態 準備下拉刷新 private static final int RELEASE_TO_REFRESH = 2; //釋放刷新 private static final int REFRESHING = 3; //正在刷新 private static final String TAG = "PullRefreshListView"; private OnRefreshListener mOnRefreshListener; /** * 組件滑動監聽器 scroll 當view在進行下拉滑動的時候,判斷滑動的距離, * 如果達到可以進行刷新的臨界點時候,回調當前接口中的方法 * Listener that will receive notifications every time the list scrolls. */ private OnScrollListener mOnScrollListener; //下拉刷新的的頭部view private LinearLayout mRefreshView; private ImageView mRefreshViewImage; private ProgressBar mRefreshViewProgress; private TextView mRefreshViewText; private TextView mRefreshViewLastUpdated; private int mRefreshState; private int mCurrentScrollState; private RotateAnimation mFlipAnimation; private RotateAnimation mReverseFlipAnimation; private int mRefreshViewHeight; private int mRefreshOriginalTopPadding; private int mLastMotionY; public PullToRefreshListView(Context context) { super(context); init(context); } public PullToRefreshListView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } private void init(Context context) { mFlipAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); mFlipAnimation.setInterpolator(new LinearInterpolator()); mFlipAnimation.setDuration(250); mFlipAnimation.setFillAfter(true); mReverseFlipAnimation = new RotateAnimation(-180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); mReverseFlipAnimation.setInterpolator(new LinearInterpolator()); mReverseFlipAnimation.setDuration(250); mReverseFlipAnimation.setFillAfter(true); mRefreshView = (LinearLayout) View.inflate(context, R.layout.pull_to_refresh_header, null); mRefreshViewText = (TextView) mRefreshView.findViewById(R.id.pull_to_refresh_text); mRefreshViewImage = (ImageView) mRefreshView.findViewById(R.id.pull_to_refresh_image); mRefreshViewProgress = (ProgressBar) mRefreshView.findViewById(R.id.pull_to_refresh_progress); mRefreshViewLastUpdated = (TextView) mRefreshView.findViewById(R.id.pull_to_refresh_updated_at); mRefreshState = PULL_TO_REFRESH; mRefreshViewImage.setMinimumHeight(50); //設置下拉最小的高度為50 setFadingEdgeLength(0); setHeaderDividersEnabled(false); //把refreshview加入到listview的頭部 addHeaderView(mRefreshView); super.setOnScrollListener(this); mRefreshView.setOnClickListener(this); mRefreshView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); mRefreshViewHeight = mRefreshView.getMeasuredHeight(); mRefreshOriginalTopPadding = -mRefreshViewHeight; resetHeaderPadding(); } /** * Set the listener that will receive notifications every time the list scrolls. * * @param l The scroll listener. */ @Override public void setOnScrollListener(OnScrollListener l) { mOnScrollListener = l; } /** * 注冊listview下拉刷新回到接口 * Register a callback to be invoked when this list should be refreshed. * * @param onRefreshListener The callback to run. */ public void setOnRefreshListener(OnRefreshListener onRefreshListener) { mOnRefreshListener = onRefreshListener; } /** * 進行設置設置上一次更新的時候 * * Set a text to represent when the list was last updated. * @param lastUpdated Last updated at. */ public void setLastUpdated(CharSequence lastUpdated) { if (lastUpdated != null) { mRefreshViewLastUpdated.setVisibility(View.VISIBLE); mRefreshViewLastUpdated.setText(lastUpdated); } else { mRefreshViewLastUpdated.setVisibility(View.GONE); } } /** * touch事件處理 * @param event * @return */ @Override public boolean onTouchEvent(MotionEvent event) { final int y = (int) event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mLastMotionY = y; break; case MotionEvent.ACTION_MOVE: int offsetY = (int) event.getY(); int deltY = Math.round(offsetY - mLastMotionY); mLastMotionY = offsetY; if (getFirstVisiblePosition() == 0 && mRefreshState != REFRESHING) { deltY = deltY / 2; mRefreshOriginalTopPadding += deltY; if (mRefreshOriginalTopPadding < -mRefreshViewHeight) { mRefreshOriginalTopPadding = -mRefreshViewHeight; } resetHeaderPadding(); } break; case MotionEvent.ACTION_UP: //當手指抬開得時候 進行判斷下拉的距離 ,如果>=臨界值,那么進行刷洗,否則回歸原位 if (!isVerticalScrollBarEnabled()) { setVerticalScrollBarEnabled(true); } if (getFirstVisiblePosition() == 0 && mRefreshState != REFRESHING) { if (mRefreshView.getBottom() >= mRefreshViewHeight && mRefreshState == RELEASE_TO_REFRESH) { //準備開始刷新 prepareForRefresh(); } else { // Abort refresh resetHeader(); } } break; } return super.onTouchEvent(event); } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (mCurrentScrollState == SCROLL_STATE_TOUCH_SCROLL && mRefreshState != REFRESHING) { if (firstVisibleItem == 0) { if ((mRefreshView.getBottom() >= mRefreshViewHeight) && mRefreshState != RELEASE_TO_REFRESH) { mRefreshViewText.setText(R.string.pull_to_refresh_release_label_it); mRefreshViewImage.clearAnimation(); mRefreshViewImage.startAnimation(mFlipAnimation); mRefreshState = RELEASE_TO_REFRESH; } else if (mRefreshView.getBottom() < mRefreshViewHeight && mRefreshState != PULL_TO_REFRESH) { mRefreshViewText.setText(R.string.pull_to_refresh_pull_label_it); mRefreshViewImage.clearAnimation(); mRefreshViewImage.startAnimation(mReverseFlipAnimation); mRefreshState = PULL_TO_REFRESH; } } } if (mOnScrollListener != null) { mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); } } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { mCurrentScrollState = scrollState; if (mOnScrollListener != null) { mOnScrollListener.onScrollStateChanged(view, scrollState); } } /** * Sets the header padding back to original size. */ private void resetHeaderPadding() { mRefreshView.setPadding( mRefreshView.getPaddingLeft(), mRefreshOriginalTopPadding, mRefreshView.getPaddingRight(), mRefreshView.getPaddingBottom()); } public void prepareForRefresh() { if (mRefreshState != REFRESHING) { mRefreshState = REFRESHING; mRefreshOriginalTopPadding = 0; resetHeaderPadding(); mRefreshViewImage.clearAnimation(); mRefreshViewImage.setVisibility(View.GONE); mRefreshViewProgress.setVisibility(View.VISIBLE); mRefreshViewText.setText(R.string.pull_to_refresh_refreshing_label_it); onRefresh(); } } private void resetHeader() { mRefreshState = PULL_TO_REFRESH; mRefreshOriginalTopPadding = -mRefreshViewHeight; resetHeaderPadding(); mRefreshViewImage.clearAnimation(); mRefreshViewImage.setVisibility(View.VISIBLE); mRefreshViewProgress.setVisibility(View.GONE); mRefreshViewText.setText(R.string.pull_to_refresh_pull_label_it); } /** * 開始回調刷新 */ public void onRefresh() { Log.d(TAG, "onRefresh"); if (mOnRefreshListener != null) { mOnRefreshListener.onRefresh(); } } /** * Resets the list to a normal state after a refresh. */ public void onRefreshComplete() { Log.d(TAG, "onRefreshComplete"); resetHeader(); } @Override public void onClick(View v) { Log.d(TAG, "onClick"); } /** * Interface definition for a callback to be invoked when list should be * refreshed. */ public interface OnRefreshListener { /** * Called when the list should be refreshed. * <p> * A call to {@link PullToRefreshListView #onRefreshComplete()} is * expected to indicate that the refresh has completed. */ public void onRefresh(); } } ~~~ 核心實現類的代碼就這些,其實整個文件讀下來,實現起來也不難的吧~大家可以根據上面的代碼可以修改定制成自己的控件都沒問題的~希望可以幫助到大家,如果需要整個demo源代碼可以去Github中下載整個項目:[https://github.com/jiangqqlmj/FastDev4Android](https://github.com/jiangqqlmj/FastDev4Android)?同時歡迎大家star和fork整個開源快速開發框架項目~如果有什么意見和反饋,歡迎留言,必定第一時間回復。也歡迎有同樣興趣的童鞋加入到該項目中來,一起維護該項目。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看