0
点赞
收藏
分享

微信扫一扫

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

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

首先需要一个布局头部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>

现在先显示几条测试数据
【达内课程】自定义控件(下拉刷新)_ide_02

创建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);
}
}

现在增加下拉效果
【达内课程】自定义控件(下拉刷新)_ide_03

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

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下载


举报

相关推荐

0 条评论