Android Control----About the pull-up refresh pull-up custom control

The first thing to understand is that the commonly used ListView does not have the same browsing effect as the novel chapter reading, to achieve the function of refresh loading. Although there are some open source libraries available on GitHub, this kind of thing can be understood more thoroughly if you have time to experience it. After all, it is available in many Android apps. Not much to say, let's start the code below.

First make the layout of the tail of the head

headview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/head"
        android:orientation="horizontal"
        android:gravity="center"
        android:padding="5dp">
        <ProgressBar
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            style="?android:attr/progressBarStyleInverse"
            android:id="@+id/progressbar"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Sweeping..."
            android:id="@+id/update_info"/>

    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/update_time"
            />

    </LinearLayout>


</LinearLayout>

footview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:id="@+id/foot_load"
        android:padding="5dp"
        android:gravity="center">
        <ProgressBar
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            style="?android:attr/progressBarStyle"
            />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Loading..."./>
    </LinearLayout>

</LinearLayout>

According to these two interface layouts, we can build a custom ListView to achieve the desired effect.

Below we can start writing a custom ListView

package com.yakir.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.example.t210_06.R;

import java.text.SimpleDateFormat;

/**
 * Custom listview implementation pull-up refresh pull-down loading
 */
public class MyListView extends ListView implements AbsListView.OnScrollListener{
    private View footview;
    private View headview;
    private int totaItemCounts;
    private int lasstVisible;
    private int fistVisiable;
    private LoadListener loadListener;
    private int footViewHeight;
    private int headViewHeight;
    private int yload;
    boolean isLoading;
    private TextView updateInfo;
    private TextView updateTime;
    private ProgressBar progressBar;
    public MyListView(Context context) {
        super(context);
        initView(context);
    }
    public MyListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

    private void initView(Context context) {
        / / Get the head layout xmlheadview=LayoutInflater.from(context).inflate(R.layout.headview,null);
        updateInfo=(TextView)headview.findViewById(R.id.update_info);
        updateTime=(TextView)headview.findViewById(R.id.update_time);
        progressBar=(ProgressBar)headview.findViewById(R.id.progressbar);
        updateTime.setText("Updated on:"+new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss").format(System.currentTimeMillis()));
        / / Get the tail layout xmlfootview=LayoutInflater.from(context).inflate(R.layout.footview,null);
        / / Measure the height of the footview | | | footview.measure (
        footview.measure(0,0);
        / / Get the height | | | footViewHeight = footview.getMeasuredHeight ();
        footViewHeight=footview.getMeasuredHeight();
        //Hide viewfootview.setPadding(0,-footViewHeight,0,0);
        headview.measure(0,0);
        headViewHeight=headview.getMeasuredHeight();
        headview.setPadding(0,-headViewHeight,0,0);
        //Settings are not visible
        // footview.findViewById(R.id.foot_load).setVisibility(View.GONE);
        // headview.findViewById(R.id.head).setVisibility(View.GONE);
        / / Add to the bottom of the listview
        this.addFooterView(footview);
        / / Add to the listview header
        this.addHeaderView(headview);
        / / Set the pull monitor
        this.setOnScrollListener(this);


    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                yload=(int)ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                int moveY=(int)ev.getY();
                int paddingY=-headViewHeight+(moveY-yload)/2;

                if (paddingY<0){
                    updateInfo.setText("Pull down refresh...".);
                    progressBar.setVisibility(View.GONE);
                }if (paddingY>0){
                    updateInfo.setText("Let the refresh...".);
                    progressBar.setVisibility(View.GONE);
                }

                headview.setPadding(0,paddingY,0,0);

                break;
        }
        return super.onTouchEvent(ev);
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (totaItemCounts==lasstVisible&&scrollState==SCROLL_STATE_IDLE) {
            if (!isLoading) {
                isLoading=true;
                footview.setPadding(0,0,0,0);
                / / Load data | | | loadListener.onLoad ();

            }
        }
                loadListener.onLoad();

            }
        }
        if (fistVisiable==0){
            headview.setPadding(0,0,0,0);
            updateInfo.setText("Sweeping...");
            progressBar.setVisibility(View.VISIBLE);
            loadListener.pullLoad();
        }
    }@Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        this.fistVisiable=firstVisibleItem;
        this.lasstVisible=firstVisibleItem+visibleItemCount;
        this.totaItemCounts=totalItemCount;

    }
    //Loading completed
    public void loadComplete(){
        isLoading=false;
        footview.setPadding(0,-footViewHeight,0,0);
        headview.setPadding(0,-headViewHeight,0,0);


    }
    public void setInterface(LoadListener loadListener){
        this.loadListener=loadListener;

    }
    / / Interface callback
    public interface LoadListener{

        void onLoad();
        void pullLoad();


    }
}

Then call this plugin we wrote ourselves in the layout of the main interface outside.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.yakir.view.MyListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/list_view">
    </com.yakir.view.MyListView>


</RelativeLayout>

MainActivity.java

package com.example.t210_06;

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.widget.ArrayAdapter;

import com.yakir.view.MyListView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements MyListView.LoadListener{
    private MyListView listview;
    private List<Integer>list=new ArrayList<>();
    private ArrayAdapter adapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        for (int i=1;i<20;i++){
            list.add(i);
        }
        initView();
        adapter=new ArrayAdapter<>(this,android.R.layout.simple_expandable_list_item_1,list);
        listview.setAdapter(adapter);

    }

    private void initView() {
        listview=(MyListView) findViewById(R.id.list_view);
        listview.setInterface(this);
    }

    @Override
    public void onLoad() {
        / / Set a three-second delay to simulate the delay to obtain data
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                //Download Data
                for (int j=1;j<11;j++){

                    list.add(j);
                }
                / / Update data | | | adapter.notifyDataSetChanged ();
                adapter.notifyDataSetChanged();
                //Load completedlistview.loadComplete();

            }
        },3000);


    }

    @Override
    public void pullLoad() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                list.clear();
                for (int i=1;i<20;i++){
                    list.add(i+1);
                }
                adapter.notifyDataSetChanged();
                listview.loadComplete();

            }
        },2000);
    }
}

This must be noted at 1 point: In the initView (context) method through LayoutInfalter.from (context).from (your xml, null); get xml. Return a View object, ListView has a setfootView () method, use it to set the View to the bottom of the ListView, of course, these two steps are not enough, we also need to do an interactive operation on this View, when the user slides At the bottom, this View shows that the View disappears after the data is loaded. Here you can set the focus position of the bottom view to hide it, and trigger the event when you pull down to achieve our effect.