SoFunction
Updated on 2025-04-07

Android-Implementation of ListView drop-down refresh of custom controls

I have been learning custom controls for a long time and found that I always forget them after learning them, so I planned to use a blog to record the knowledge points I learned.

Today, we are customizing ListView to achieve drop-down refresh. These articles are written based on videos from MOOC.

To customize a control, we first look at which control it inherits. If we inherit the View control, we have to write a lot of functions about ListView. I think these things are very troublesome, and there is no need because we can directly inherit ListView and add some things we need based on the listView.

1. Add a Header layout to ListView

  private void initView(Context context)
  {
    mLayoutInflater = (context);
    mHeaerView = (.header_layout, null, false);
    addHeaderView(mHeaerView);
  }

2. Hide the Header layout

private void initView(Context context) {
    mLayoutInflater = (context);
    mHeaerView = (.header_layout, null, false);
    measureView(mHeaerView);
    mHeaderViewHeight = ();
    setHeaderViewHeightPadding(mHeaderViewHeight);
    ("main", mHeaderViewHeight + "");
    addHeaderView(mHeaerView);
  }
  private void measureView(View view)
  {
     lp = ();
    if(lp == null)
    {
      lp = new (.MATCH_PARENT, .WRAP_CONTENT);
    }
    //(.MATCH_PARENT, .WRAP_CONTENT);
    /**
      * width and height contain not only the width and height of the View, but also the measurement mode of the View control
      * The measurement mode is generated as follows
      */
    int width = (0,0,);
    int height = 0;
    int tempHeight = ;
    if(tempHeight > 0)
    {
      height = (tempHeight, );
    }
    (width, height);

  }
  private void setHeaderViewHeightPadding(int padding) {
    ((), -padding, (), ());
    ();
  }

3. Implement the drop-down refresh of ListView (I)

To implement the pull-down refresh of ListView, you must listen to whether the ListView slides to the top. Therefore, you must implement the ListView's listening interface OnScrollListener, and listen to the ListView's OnTouch event. Judging the refresh situation based on the sliding situation.

First, we define a member variable to save the state of ListView --mState

Secondly, several static constants are defined to represent different states.

 private final static int NONE = 0; // Statusless  private final static int DOWN_UPDATE = 1; // Tip pull down to refresh  private final static int UPDATE = 2; // Release it to refresh  private final static int REFLASH = 3; // renew

Finally, change the state of mState according to different swipes.

@Override
  public boolean onTouchEvent(MotionEvent ev) {

    switch (()) {
      case MotionEvent.ACTION_DOWN: {
        if (mFirstVisibleItem == 0) {
          mIsRemark = true; // mIsRemark is just a mark, indicating whether the currently visible first Item is the first of all Items          mStartY = (int) ();
          ("main", "I'm in");
        }
        break;
      }
      case MotionEvent.ACTION_MOVE: {
        onMove(ev);
        tempY = (int) (() - mStartY);
        ("main", "tempY = " + tempY);
        break;
      }
      case MotionEvent.ACTION_UP: {

        if(mState == DOWN_UPDATE)
        {
          mState = NONE;
        }
        if(mState == UPDATE)
        {
          mState = REFLASH;
          ();
          ("main", "I am coming");
        }
        ("main", "tempY11 = " + tempY);
        if(tempY <= 0 && mIsRemark)
        {
          ("main", "I'll come in le");
          mState = NONE;
        }

        change();
        break;
      }
    }


    return (ev);
  }

  private void onMove(MotionEvent ev) {
    if (mIsRemark) {
      if (() - mStartY > 0) {
        int dy = (int) (() - mStartY);
        if (dy > mHeaderViewHeight + 20) {
          mState = UPDATE;
        } else {
          mState = DOWN_UPDATE;
        }
        setHeaderViewHeightPadding(mHeaderViewHeight - dy);
        change();
      }
      return;
    }
    return;
  }
/**
  *change method is mainly used to handle events in different states
  *
  */
  private void change() {
    initChildView();
    RotateAnimation ani = new RotateAnimation(0, 180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
    (500);
    (true);
    RotateAnimation ani1 = new RotateAnimation(180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
    (500);
    (true);
    if (mState == UPDATE)
    {
      ();
      ();
      ();
      (ani);
      ("Release refresh!");
      ();
      ("Last updated:" + mUpdateTime);
    }
    if (mState == DOWN_UPDATE)
    {
      ();
      ();
      ();
      ();
      (ani1);
      ("Pull down to refresh");
      ("Last updated:" + mUpdateTime);
    }
    if (mState == REFLASH)
    {
      setHeaderViewHeightPadding(10);
      ();
      ();
      ();
      ("Refreshing...");
      ();
    }
    if(mState == NONE)
    {
      ("main", "workspace");
      setHeaderViewHeightPadding(mHeaderViewHeight);
      mIsRemark = false;
      ();
      ();
      (ani1);
    }
  }
  private void initChildView()
  {
    if(mTextViewFlash == null)
    {
      mTextViewFlash = (TextView) (.id_textView_Flash);
    }
    if(mTextViewTime == null)
    {
      mTextViewTime = (TextView) (.id_textView_Time);
    }
    if(mImageView == null)
    {
      mImageView = (ImageView) (.id_imagView);
    }
    if(mProgressBar == null)
    {
      mProgressBar = (ProgressBar) (.id_progressbar);
    }
  }

4. Implement the pull-down refresh of ListView (II)

After the above process, you can pull down to handle events in different states. Another problem is refreshing, that is, loading new data. The loading and refresh operation must be in the UI thread, so there must be a callback interface in the ListView, which is used for MinaActivity to implement and perform some operations.

Callback interface:

  public void setOnFlashListener(FlashListener listener)
  {
     = listener;
  }

  public interface FlashListener
  {
    void reFlash();
  }

Callback interface calls:

        if(mState == UPDATE)
        {
          mState = REFLASH;
          ();
          ("main", "I am coming");
        }

Implementation of callback interface and interface method in MainActivity:

(new () {
      @Override
      public void reFlash() {
        Handler handler = new Handler();
        (new Runnable() {
          @Override
          public void run() {
            addDatas();
            loadDatas();
            ();
          }
        }, 5000);
      }
    });




 private void addDatas()
  {
    int i = ();
    for(int j = i; j < i + 10; j++)
    {
      (new Bean("Title" + j, "Content" + j, .ic_launcher));
    }
    (mDatas);
  }
  private void loadDatas()
  {
    (myAdapter);
  }

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.