【达内课程】自定义控件(下拉刷新)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010356768/article/details/89432504

这一节要实现的效果是下拉刷新

首先需要一个布局头部listview_header
在这里插入图片描述

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context=".MainActivity"
    android:gravity="center">

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <FrameLayout
            android:id="@+id/framelayout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/img_arrow"
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:src="@mipmap/down_arrow"/>

            <ProgressBar
                android:id="@+id/progress_circular"
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:visibility="gone"/>

        </FrameLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/framelayout"
            android:orientation="vertical"
            android:gravity="center">
            <TextView
                android:id="@+id/tv_tip_one"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="下拉刷新"
                android:textColor="#2c2c2c"
                android:textSize="17dp"/>

            <TextView
                android:id="@+id/tv_tip_two"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="下拉刷新"

                android:textColor="#bfbfbf"
                android:layout_below="@+id/tv_tip_one"
                android:textSize="15dp"/>


        </LinearLayout>


    </RelativeLayout>

</LinearLayout>

现在先显示几条测试数据
在这里插入图片描述

创建MyAdapter

public class MyAdapter extends BaseAdapter {
    private Context context;
    private ArrayList<String> list;

    public MyAdapter(Context context, ArrayList<String> list) {
        this.context = context;
        if(list == null){
            list = new ArrayList<>();
        }else {
            this.list = list;
        }
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public String getItem(int i) {
        return list.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        TextView tv = new TextView(context);
        tv.setText(list.get(i));
        return tv;
    }
}

创建CustomListView

public class CustomListView extends ListView {
    public CustomListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
}

在布局activity_main中使用

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.xx.customlistview.CustomListView
        android:id="@+id/customListView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

MainActivity

public class MainActivity extends Activity {
    private ArrayList<String> list = new ArrayList<>();
    private MyAdapter myAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        CustomListView customListView = findViewById(R.id.customListView);
        //准备测试数据
        for(int i=0;i<10;i++){
            list.add("data"+i);
        }

        myAdapter = new MyAdapter(this,list);
        customListView.setAdapter(myAdapter);
    }
}

现在增加下拉刷新的头部,并且隐藏起来
修改CustomListView

public class CustomListView extends ListView {
    View view;
    int height;
    public CustomListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        view = View.inflate(context,R.layout.listview_header,null);
        //如果控件已经在屏幕显示了,可以用getHeight()拿高度
        //height = view.getHeight();

        //控件没有显示出来,用Measure测量
        //0是一种测量方式,不指定大小。必须先调用这个方法
        view.measure(0,0);
        //用getMeasuredHeight测量
        height = view.getMeasuredHeight();

        view.setPadding(0,-height,0,0);
        addHeaderView(view);
    }
}

现在增加下拉效果
在这里插入图片描述

public class CustomListView extends ListView {
    public static final String TAG = "CustomListView";
    View view;
    int height;

    TextView tvState;
    ImageView downArrow;
    ProgressBar progressBar;

    public static final int STATE_DONE = 1;
    public static final int STATE_PULL = 2;
    public static final int STATE_RELEASE = 3;
    public static final int STATE_REFRESHING = 4;

    int currentState;
    int downY;

    public CustomListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        view = View.inflate(context,R.layout.listview_header,null);
        tvState = view.findViewById(R.id.tv_tip_one);
        downArrow = view.findViewById(R.id.img_arrow);
        progressBar = view.findViewById(R.id.progress_circular);
        //设置初始状态
        currentState = STATE_DONE;

        //如果控件已经在屏幕显示了,可以用getHeight()拿高度
        //height = view.getHeight();

        //控件没有显示出来,用Measure测量
        //0是一种测量方式,不指定大小。必须先调用这个方法
        view.measure(0,0);
        //用getMeasuredHeight测量
        height = view.getMeasuredHeight();

        view.setPadding(0,-height,0,0);
        addHeaderView(view);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action){
            case MotionEvent.ACTION_DOWN://按下
                if(currentState == STATE_DONE){
                    downY = (int) ev.getY();
                    currentState = STATE_PULL;//状态改为下拉
                }
                break;
            case MotionEvent.ACTION_MOVE://移动
                if(currentState == STATE_PULL){
                    int currentY = (int) ev.getY();
                    //currentY:当前手指的Y坐标
                    //downY:手指按下时的Y坐标
                    int top = currentY - downY - height;
                    Log.d(TAG,"currentY:"+currentY+",downY:"+downY);
                    view.setPadding(0,top,0,0);

                    //拉到一定程度
                    if((currentY - downY)>height){
                        currentState = STATE_RELEASE;
                        tvState.setText("松开刷新");
                    }
                }
                break;
            case MotionEvent.ACTION_UP://抬起,松开
                if(currentState == STATE_RELEASE){
                    currentState = STATE_REFRESHING;
                    tvState.setText("刷新中");
                    progressBar.setVisibility(VISIBLE);
                    downArrow.setVisibility(GONE);
                }
                break;
        }
        return super.onTouchEvent(ev);
    }
}

当下拉,然后松开手指时,应该进行联网操作,请求数据,这里我们写一个接口

修改CustomListView

扫描二维码关注公众号,回复: 6189726 查看本文章
public class CustomListView extends ListView {
    ......

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action){
            ......
            case MotionEvent.ACTION_UP://抬起,松开
                if(currentState == STATE_RELEASE){
                    currentState = STATE_REFRESHING;
                    tvState.setText("刷新中");
                    progressBar.setVisibility(VISIBLE);
                    downArrow.setVisibility(GONE);

                    //4、调实现类
                    if(this.onRefreshListener != null){
                        //面向接口编程
                        this.onRefreshListener.onRefresh(this);
                    }
                }
                break;
        }
        return super.onTouchEvent(ev);
    }

    //1、定义接口
    interface OnRefreshListener{
        public void onRefresh(CustomListView customListView);
    }
    //2、声明接口中对象
    OnRefreshListener onRefreshListener;
    //3、写一个方法接收实现类
    public void setOnRefreshListener(OnRefreshListener onRefreshListener){
        this.onRefreshListener = onRefreshListener;
    }
    
    //刷新完成,隐藏头部
    public void refreshComplete(){
        view.setPadding(0,-height,0,0);
        currentState = STATE_DONE;
        tvState.setText("下拉刷新");
        downArrow.setVisibility(VISIBLE);
        progressBar.setVisibility(GONE);
    }
}

作为用框架的人,需要写一个实现类

public class MainActivity extends Activity {
    ......
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ......

        MyOnRefreshListener myOnRefreshListener = new MyOnRefreshListener();
        customListView.setOnRefreshListener(myOnRefreshListener);
    }

     class MyOnRefreshListener implements CustomListView.OnRefreshListener{

        @Override
        public void onRefresh(final CustomListView customListView) {
            Log.d(TAG,"进行联网操作,刷新数据");
            new Thread(){
                @Override
                public void run() {
                    try{
                        //模拟联网获得数据
                        String data = "联网获得数据";
                        list.add(data);
                        //操作ui,确保执行在主线程
                        MainActivity.this.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                customListView.refreshComplete();
                                myAdapter.notifyDataSetChanged();
                            }
                        });

                    }catch (Exception e){

                    };
                }
            }.start();
        }
    }
}

Demo下载

https://download.csdn.net/download/u010356768/11135658

猜你喜欢

转载自blog.csdn.net/u010356768/article/details/89432504
今日推荐