版权声明:本文为博主原创文章,未经博主允许不得转载。 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();
}
}
}