国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android-自定義控件之ListView下拉刷新的實現(xiàn)

2019-12-12 03:38:48
字體:
供稿:網(wǎng)友

自定義控件學了很久了,發(fā)現(xiàn)學了總是忘,于是打算用博客來記錄自己學習的知識點。

今天是自定義ListView來實現(xiàn)下拉刷新,這些文章都是借鑒慕課網(wǎng)上的視頻來寫的.

自定義一個控件,先是看它繼承于那個控件,如果我們繼承View控件的話,那得讓我們寫很多關于ListView的功能,這些東西我自己覺得很麻煩,而且也沒有那個必要因為我們可以直接繼承ListView,在listView的基礎上來加一些我們需要的東西。

1.向ListView加Header布局

  private void initView(Context context)  {    mLayoutInflater = LayoutInflater.from(context);    mHeaerView = mLayoutInflater.inflate(R.layout.header_layout, null, false);    addHeaderView(mHeaerView);  }

2.隱藏Header布局

private void initView(Context context) {    mLayoutInflater = LayoutInflater.from(context);    mHeaerView = mLayoutInflater.inflate(R.layout.header_layout, null, false);    measureView(mHeaerView);    mHeaderViewHeight = mHeaerView.getMeasuredHeight();    setHeaderViewHeightPadding(mHeaderViewHeight);    Log.i("main", mHeaderViewHeight + "");    addHeaderView(mHeaerView);  }  private void measureView(View view)  {    ViewGroup.LayoutParams lp = view.getLayoutParams();    if(lp == null)    {      lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);    }    //mHeaerView.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);    /**     * width 和height里面包含的不僅僅有View的寬和高,還有View控件的測量模式     * 測量模式的產(chǎn)生方式就是如下所示     */    int width = ViewGroup.getChildMeasureSpec(0,0,lp.width);    int height = 0;    int tempHeight = lp.height;    if(tempHeight > 0)    {      height = MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.EXACTLY);    }    view.measure(width, height);  }  private void setHeaderViewHeightPadding(int padding) {    mHeaerView.setPadding(mHeaerView.getPaddingLeft(), -padding, mHeaerView.getPaddingRight(), mHeaerView.getPaddingBottom());    mHeaerView.invalidate();  }

3.實現(xiàn)ListView的下拉刷新(一)

要想實現(xiàn)ListView的下拉刷新,必須監(jiān)聽ListView是否滑動到最頂端,因此要實現(xiàn)ListView的監(jiān)聽接口OnScrollListener,并且要監(jiān)聽ListView的OnTouch事件。根據(jù)滑動的情況來判斷刷新的情況。

首先我們在定義了一個成員變量來保存ListView的狀態(tài)--mState

其次定義了幾個靜態(tài)常量來表示不同的狀態(tài)  

 private final static int NONE = 0; // 無狀態(tài)  private final static int DOWN_UPDATE = 1; // 提示下拉可以刷新  private final static int UPDATE = 2; // 提示松開可以刷新  private final static int REFLASH = 3; // 更新

最后則是根據(jù)不同的滑動來更改mState的狀態(tài)

@Override  public boolean onTouchEvent(MotionEvent ev) {    switch (ev.getAction()) {      case MotionEvent.ACTION_DOWN: {        if (mFirstVisibleItem == 0) {          mIsRemark = true; // mIsRemark只是一個標記,表示當前可見的第一個Item是不是所有的Item中的第一個          mStartY = (int) ev.getY();          Log.i("main", "我進來了");        }        break;      }      case MotionEvent.ACTION_MOVE: {        onMove(ev);        tempY = (int) (ev.getY() - mStartY);        Log.i("main", "tempY = " + tempY);        break;      }      case MotionEvent.ACTION_UP: {        if(mState == DOWN_UPDATE)        {          mState = NONE;        }        if(mState == UPDATE)        {          mState = REFLASH;          mListener.reFlash();          Log.i("main", "我來了");        }        Log.i("main", "tempY11 = " + tempY);        if(tempY <= 0 && mIsRemark)        {          Log.i("main", "我進來le");          mState = NONE;        }        change();        break;      }    }    return super.onTouchEvent(ev);  }  private void onMove(MotionEvent ev) {    if (mIsRemark) {      if (ev.getY() - mStartY > 0) {        int dy = (int) (ev.getY() - mStartY);        if (dy > mHeaderViewHeight + 20) {          mState = UPDATE;        } else {          mState = DOWN_UPDATE;        }        setHeaderViewHeightPadding(mHeaderViewHeight - dy);        change();      }      return;    }    return;  }/** *change方法主要是用來處理不同狀態(tài)下的事件 * */  private void change() {    initChildView();    RotateAnimation ani = new RotateAnimation(0, 180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);    ani.setDuration(500);    ani.setFillAfter(true);    RotateAnimation ani1 = new RotateAnimation(180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);    ani1.setDuration(500);    ani1.setFillAfter(true);    if (mState == UPDATE)    {      mProgressBar.setVisibility(View.GONE);      mImageView.setVisibility(View.VISIBLE);      mImageView.clearAnimation();      mImageView.setAnimation(ani);      mTextViewFlash.setText("松開可以刷新!");      mTextViewTime.setVisibility(View.VISIBLE);      mTextViewTime.setText("上次更新的時間:" + mUpdateTime);    }    if (mState == DOWN_UPDATE)    {      mProgressBar.setVisibility(View.GONE);      mImageView.setVisibility(View.VISIBLE);      mTextViewTime.setVisibility(View.VISIBLE);      mImageView.clearAnimation();      mImageView.setAnimation(ani1);      mTextViewFlash.setText("下拉可以刷新");      mTextViewTime.setText("上次更新的時間:" + mUpdateTime);    }    if (mState == REFLASH)    {      setHeaderViewHeightPadding(10);      mProgressBar.setVisibility(View.VISIBLE);      mImageView.setVisibility(View.GONE);      mTextViewTime.setVisibility(View.GONE);      mTextViewFlash.setText("正在刷新...");      mImageView.clearAnimation();    }    if(mState == NONE)    {      Log.i("main", "workspace");      setHeaderViewHeightPadding(mHeaderViewHeight);      mIsRemark = false;      mProgressBar.setVisibility(View.GONE);      mImageView.setVisibility(View.VISIBLE);      mImageView.setAnimation(ani1);    }  }  private void initChildView()  {    if(mTextViewFlash == null)    {      mTextViewFlash = (TextView) mHeaerView.findViewById(R.id.id_textView_Flash);    }    if(mTextViewTime == null)    {      mTextViewTime = (TextView) mHeaerView.findViewById(R.id.id_textView_Time);    }    if(mImageView == null)    {      mImageView = (ImageView) mHeaerView.findViewById(R.id.id_imagView);    }    if(mProgressBar == null)    {      mProgressBar = (ProgressBar) mHeaerView.findViewById(R.id.id_progressbar);    }  }

4.實現(xiàn)ListView的下拉刷新(二)

 經(jīng)過上面的過程,是可以下拉的,處理不同狀態(tài)下的事件。還有一個問題就是刷新,也就是加載新的數(shù)據(jù)。加載刷新的操作肯定必須在UI線程中,因此ListView中必須得有一個回調(diào)接口,用來MinaActivity來實現(xiàn),并且來進行一些操作。

  回調(diào)接口:

  public void setOnFlashListener(FlashListener listener)  {    this.mListener = listener;  }  public interface FlashListener  {    void reFlash();  }

回調(diào)接口的調(diào)用:

        if(mState == UPDATE)        {          mState = REFLASH;          mListener.reFlash();          Log.i("main", "我來了");        }

MainActivity中回調(diào)接口的實現(xiàn)和接口方法的實現(xiàn):

mListView.setOnFlashListener(new FlashListView.FlashListener() {      @Override      public void reFlash() {        Handler handler = new Handler();        handler.postDelayed(new Runnable() {          @Override          public void run() {            addDatas();            loadDatas();            mListView.reFalshComplete();          }        }, 5000);      }    });   private void addDatas()  {    int i = mDatas.size();    for(int j = i; j < i + 10; j++)    {      mDatas.add(new Bean("Title" + j, "Content" + j, R.mipmap.ic_launcher));    }    myAdapter.dataChange(mDatas);  }  private void loadDatas()  {    mListView.setAdapter(myAdapter);  }

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 肃北| 蒙阴县| 四子王旗| 南漳县| 安达市| 天峻县| 徐水县| 平塘县| 凉山| 华坪县| 洪泽县| 宁晋县| 和静县| 太白县| 安化县| 普格县| 乡宁县| 华宁县| 溧阳市| 武邑县| 顺义区| 苏尼特左旗| 宜兰县| 叙永县| 中超| 永修县| 兴隆县| 蓬莱市| 桂阳县| 海晏县| 桂东县| 封开县| 榆社县| 福泉市| 富顺县| 太湖县| 平罗县| 沅江市| 东山县| 汉源县| 准格尔旗|