下拉刷新(二)!

2024-08-31 23:48
文章标签 刷新

本文主要是介绍下拉刷新(二)!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


先看主布局activity_main.xml

<RelativeLayout 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"android:background="@color/white"tools:context=".MainActivity" ><com.imooc.listviewfrashdemo1.ReFlashListViewandroid:id="@+id/listview"android:layout_width="fill_parent"android:layout_height="fill_parent"android:background="@color/white"android:cacheColorHint="#00000000"android:dividerHeight="5dip" />
</RelativeLayout>

再看头布局header_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical" ><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:paddingBottom="10dip"android:paddingTop="10dip" ><LinearLayoutandroid:id="@+id/layout"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:gravity="center"android:orientation="vertical" ><TextViewandroid:id="@+id/tip"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="下拉可以刷新!" /><TextViewandroid:id="@+id/lastupdate_time"android:layout_width="wrap_content"android:layout_height="wrap_content" /></LinearLayout><ImageViewandroid:id="@+id/arrow"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_toLeftOf="@id/layout"android:layout_marginRight="20dip"android:src="@drawable/pull_to_refresh_arrow" /><ProgressBarandroid:id="@+id/progress"style="?android:attr/progressBarStyleSmall"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_toLeftOf="@id/layout"android:layout_marginRight="20dip"android:visibility="gone" /></RelativeLayout></LinearLayout>

在看listview的每个item的布局

item_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="60dip"android:gravity="center_vertical"android:background="@drawable/app_item_bg"android:orientation="horizontal" ><ImageViewandroid:id="@+id/item3_apkiv"android:layout_width="50dip"android:layout_height="50dip"android:background="@drawable/test_icon"android:layout_marginLeft="10dip" /><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"android:layout_marginLeft="10dip"android:orientation="vertical" ><TextViewandroid:id="@+id/item3_apkname"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="应用程序名字"android:textColor="@color/black"android:textSize="18dip" /><TextViewandroid:id="@+id/item3_apkinfo"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="5dip"android:text="应用程序信息"android:textSize="14dip" /></LinearLayout><Buttonandroid:layout_width="60dip"android:layout_height="30dip"android:background="@drawable/ic_launcher"android:id="@+id/item3_dlbtn"android:layout_marginRight="10dip"android:text="安装"/></LinearLayout><TextViewandroid:id="@+id/item3_apkdes"android:layout_width="fill_parent"android:layout_height="30dip"android:layout_marginLeft="5dip"android:layout_marginRight="5dip"android:gravity="center_vertical"android:text="应用程序描述"android:textSize="14dip" /></LinearLayout>

以上的三个布局可以看截图,知道个大概,这个不是主要的


接下来看bean类

ApkEntity

package com.imooc.listviewfrashdemo1;public class ApkEntity {private String name;private String des;private String info;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDes() {return des;}public void setDes(String des) {this.des = des;}public String getInfo() {return info;}public void setInfo(String info) {this.info = info;}}

接下来看主程代码

MainActivity

package com.imooc.listviewfrashdemo1;import java.util.ArrayList;import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;import com.example.listviewfrashdemo1.R;
import com.imooc.listviewfrashdemo1.ReFlashListView.IReflashListener;public class MainActivity extends Activity implements IReflashListener {ArrayList<ApkEntity> apk_list;MyAdapter adapter;ReFlashListView listview;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 加载布局--只有一个listViewsetContentView(R.layout.activity_main);// 设置数据setData();//填充数据showList(apk_list);}/*** 设置数据源*/private void setData() {apk_list = new ArrayList<ApkEntity>();for (int i = 0; i < 10; i++) {ApkEntity entity = new ApkEntity();entity.setName("默认数据");entity.setInfo("50w用户");entity.setDes("这是一个神奇的应用");apk_list.add(entity);}}private void showList(ArrayList<ApkEntity> apk_list) {if (adapter == null) {listview = (ReFlashListView) findViewById(R.id.listview);//为本类设置监听,然后implements IReflashListenerlistview.setInterface(this);adapter = new MyAdapter(this, apk_list);//如果适配器为null,设置适配器即可listview.setAdapter(adapter);} else {//如果适配器不为null,就更新数据源,进行notifyDataSetChanged()adapter.onDateChange(apk_list);}}/*** 实现刷新操作的回调方法*/@Overridepublic void onReflush () {Handler handler = new Handler();handler.postDelayed(new Runnable() {@Overridepublic void run() {// 获取最新数据setReflashData();// 通知界面显示showList(apk_list);// 通知listview 刷新数据完毕!!!!!!!!!!!!!!listview.reflashComplete();}}, 2000);}private void setReflashData() {for (int i = 0; i < 2; i++) {ApkEntity entity = new ApkEntity();entity.setName("刷新数据");entity.setDes("这是一个神奇的应用");entity.setInfo("50w用户");apk_list.add(0, entity);}}}

接下来看适配器代码

MyAdapter

package com.imooc.listviewfrashdemo1;import java.util.ArrayList;import com.example.listviewfrashdemo1.R;import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;public class MyAdapter extends BaseAdapter {ArrayList<ApkEntity> apk_list;LayoutInflater inflater;public MyAdapter(Context context, ArrayList<ApkEntity> apk_list) {this.apk_list = apk_list;this.inflater = LayoutInflater.from(context);}public void onDateChange(ArrayList<ApkEntity> apk_list) {this.apk_list = apk_list;this.notifyDataSetChanged();}@Overridepublic int getCount() {return apk_list.size();}@Overridepublic Object getItem(int position) {return apk_list.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ApkEntity entity = apk_list.get(position);ViewHolder holder;if (convertView == null) {holder = new ViewHolder();convertView = inflater.inflate(R.layout.item_layout, null);holder.name_tv = (TextView) convertView.findViewById(R.id.item3_apkname);holder.des_tv = (TextView) convertView.findViewById(R.id.item3_apkdes);holder.info_tv = (TextView) convertView.findViewById(R.id.item3_apkinfo);convertView.setTag(holder);}else{holder = (ViewHolder) convertView.getTag();}holder.name_tv.setText(entity.getName());holder.des_tv.setText(entity.getDes());holder.info_tv.setText(entity.getInfo());return convertView;}class ViewHolder {TextView name_tv;TextView des_tv;TextView info_tv;}
}
接下来看自定义listview类了(里面代码详细)

ReFlashListView

package com.imooc.listviewfrashdemo1;import java.text.SimpleDateFormat;
import java.util.Date;import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;import com.example.listviewfrashdemo1.R;
/*** 隐藏头布局--先测量父布局,获取头布局高度,设置padding,然后隐藏头布局,listview在添加头布局* 设置监听事件* 判断ontouch时间* 设置监听加载刷新的数据*/
public class ReFlashListView extends ListView implements OnScrollListener {View header;// 顶部布局文件;int headerHeight;// 顶部布局文件的高度;int firstVisibleItem;// 当前第一个可见的item的位置;int scrollState;// listview 当前滚动状态;boolean isRemark;// 标记,当前是在listview最顶端摁下的;int startY;// 摁下时的Y值;int state;// 当前的状态;final int NONE = 0;// 正常状态;final int PULL = 1;// 提示下拉状态;final int RELESE = 2;// 提示释放状态;final int REFLASHING = 3;// 刷新状态;IReflashListener iReflushListener;//刷新数据的接口/*** 三个构造方法,并且初始化视图*/public ReFlashListView(Context context) {super(context);initView(context);}public ReFlashListView(Context context, AttributeSet attrs) {super(context, attrs);initView(context);}public ReFlashListView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);initView(context);}/*** 初始化界面,添加顶部布局文件到 listview*/private void initView(Context context) {LayoutInflater inflater = LayoutInflater.from(context);header = inflater.inflate(R.layout.header_layout, null);//先测量父布局,不然headerHeight为0measureView(header);//获取头布局文件的高度headerHeight = header.getMeasuredHeight();Log.i("tag", "headerHeight = " + headerHeight);//隐藏头布局文件topPadding(-headerHeight);//listview添加头布局this.addHeaderView(header);//设置滑动监听this.setOnScrollListener(this);}/*** 通知父布局,占用的宽,高;*/private void measureView(View view) {ViewGroup.LayoutParams p = view.getLayoutParams();if (p == null) {p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);}/*** 因为listView不限制高度。child有多高,listView就给它多高的空间* 但是listView是限制宽度的,所以需要getChildMeasureSpec*/int width = ViewGroup.getChildMeasureSpec(0, 0, p.width);int height;//获取itme的高度值int tempHeight = p.height;if (tempHeight > 0) {height = MeasureSpec.makeMeasureSpec(tempHeight,MeasureSpec.EXACTLY);} else {height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);}view.measure(width, height);}/*** 设置header 布局 上边距;--站在父布局的角度看待问题*/private void topPadding(int topPadding) {header.setPadding(header.getPaddingLeft(), topPadding,header.getPaddingRight(), header.getPaddingBottom());header.invalidate();}/*** 实现接口方法*/@Overridepublic void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {this.firstVisibleItem = firstVisibleItem;}@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {this.scrollState = scrollState;}/*** 实现touch方法*/@Overridepublic boolean onTouchEvent(MotionEvent ev) {switch (ev.getAction()) {/*** 如果手指按下,如果firstVisibleItem == 0就设置标记为true,代表是在最顶端按下的* 并且获取按下的坐标Y轴距离*/case MotionEvent.ACTION_DOWN:if (firstVisibleItem == 0) {isRemark = true;startY = (int) ev.getY();}break;case MotionEvent.ACTION_MOVE:/*** 判断移动过程操作;*/onMove(ev);break;case MotionEvent.ACTION_UP:if (state == RELESE) {state = REFLASHING;// 加载最新数据;reflashViewByState();iReflushListener.onReflush();} else if (state == PULL) {state = NONE;isRemark = false;reflashViewByState();}break;}return super.onTouchEvent(ev);}/*** 当手指按下*/private void onMove(MotionEvent ev) {//如果不是在listview在最顶端时候按下的,直接返回,不做处理if (!isRemark) {return;}int tempY = (int) ev.getY();//获取移动的距离int space = tempY - startY;//获取最新的头布局的padding值int topPadding = space - headerHeight;switch (state) {/*** 判断刷新箭头的状态值*/case NONE://如果稍微移动就改成状态是--下拉可以刷新if (space > 0) {//如果是正常状态,就修改状态为下拉可以刷新state = PULL;//根据当前状态,改变界面显示;reflashViewByState();}break;case PULL://重绘最新的头布局隐藏程度topPadding(topPadding);//如果比头布局高度还大于30就直接改变状态值if (space-headerHeight>  30&& scrollState == SCROLL_STATE_TOUCH_SCROLL) {//修改状态为--松开可以刷新state = RELESE;reflashViewByState();}break;case RELESE://重绘最新的头布局隐藏程度topPadding(topPadding);if (space-headerHeight < 30) {//改变状态--下拉可以刷新state = PULL;reflashViewByState();} else if (space <= 0) {//当space<=0,即可见的item索引不是0state = NONE;//还原isRemark = false;reflashViewByState();}break;}}/*** 根据当前状态,改变界面显示;*/private void reflashViewByState() {TextView tip = (TextView) header.findViewById(R.id.tip);ImageView arrow = (ImageView) header.findViewById(R.id.arrow);ProgressBar progress = (ProgressBar) header.findViewById(R.id.progress);RotateAnimation anim = new RotateAnimation(0, 180,RotateAnimation.RELATIVE_TO_SELF, 0.5f,RotateAnimation.RELATIVE_TO_SELF, 0.5f);anim.setDuration(500);anim.setFillAfter(true);RotateAnimation anim1 = new RotateAnimation(180, 0,RotateAnimation.RELATIVE_TO_SELF, 0.5f,RotateAnimation.RELATIVE_TO_SELF, 0.5f);anim1.setDuration(500);anim1.setFillAfter(true);switch (state) {case NONE:arrow.clearAnimation();topPadding(-headerHeight);break;case PULL:arrow.setVisibility(View.VISIBLE);progress.setVisibility(View.GONE);tip.setText("下拉可以刷新!");arrow.clearAnimation();arrow.setAnimation(anim1);break;case RELESE:arrow.setVisibility(View.VISIBLE);progress.setVisibility(View.GONE);tip.setText("松开可以刷新!");arrow.clearAnimation();arrow.setAnimation(anim);break;case REFLASHING:topPadding(50);arrow.setVisibility(View.GONE);progress.setVisibility(View.VISIBLE);tip.setText("正在刷新...");arrow.clearAnimation();break;}}/*** 获取完数据;*/public void reflashComplete() {//将刷新状态还原成正常状态state = NONE;//还原状态isRemark = false;reflashViewByState();TextView lastupdatetime = (TextView) header.findViewById(R.id.lastupdate_time);SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");Date date = new Date(System.currentTimeMillis());String time = format.format(date);lastupdatetime.setText(time);}public void setInterface(IReflashListener iReflushListener){this.iReflushListener = iReflushListener;}/*** 刷新数据接口* @author Administrator*/public interface IReflashListener{public void onReflush();}
}



这篇关于下拉刷新(二)!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1125339

相关文章

自定义布局实现listview上拉加载下拉刷新

listview布局有时加载数据偏多,需要上拉加载第二页等更多数据,下拉刷新数据等功能,也有开源的框架XRefreshView ,可以参考http://www.w2bc.com/Article/44291,当初开发项目时,便于自己控制,就自定义布局实现这功能。 1、自定义布局用来管理三个子控件:下拉头,包含内容的自定义listview,上拉头(代码有详细介绍) public class Pul

vue列表数据删除后刷新页面

目录 背景页面刷新方式1.原始方法2.vue自带的路由跳转3.重新调用获取数据列表的接口4.使用provide和inject实现页面刷新使用方式总结 背景 在页面进行增删改列表后,页面需要进行刷新,在进行这些操作后,需要手动刷新才能更新列表。本文主要讨论进行增删改查相关操作后如何使当前页面显示操作后的最新数据。 参考:vue实现在进行增删改操作后刷新页面 页面刷新方式

button 提交后再次刷新页面

button,input type=button按钮在IE和w3c,firefox浏览器区别 当在IE浏览器下面时,button标签按钮,input标签type属性为button的按钮是一样的功能,不会对表单进行任何操作。 但是在W3C浏览器,如Firefox下就需要注意了,button标签按钮会提交表单,而input标签type属性为button不会对表单进行任何操作。 解决方案:

C1-2 ABB二次SDK开发——手把手教登录对应的机器人控制器(图片引导操作)登录机器人控制器和刷新机器人列表

1.完成配置后我们开始进行操作 C1-1 ABB二次SDK开发——C#Window窗体-环境配置(带ABB二次开发SDK资源包)-CSDN博客文章浏览阅读95次。3.记住路径,右键C#引用,然后导入ABB.Robotics.Controllers.PC.dll。2.安装资源文件PCABB二次开发的SDK,并打开安装路径。1.新建VSC#的windowfrom项目。4.在框架代码主界面代码中添加。

动态刷新ListView

要刷新ListView,只需要调用其适配器的notifyDataSetChanged()方法即可。 下面的例子是在“ListView的例子”的基础上演化而言,本文仅给出变化的部分。 布局文件:增加了一个按钮,动态增加一个学生记录。 <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http:

jsp页面点击页签自动刷新解决方案

问题:在一个projectInfoMain.jsp的界面定义了多个页签,怎么实现在一个页签的jsp页面保存完以后点击每个页签时自动刷新改界面。 解决方案:可以在每次点击页签时,修改页签的url地址,使它再次向服务器发送请求,以实现自动刷新的功能 具体解决方案: projectInfoMain.jsp主界面实现代码: <%@ page language="java" cont

bug系列-------home界面自动刷新

最近遇到一个bug,setting里将display设置为never sleep之后返回home界面,系统会不断刷新,看了一下log发现下面一段有问题 09-20 03:41:42.013  5974  5974 D PowerSaverUpdateIcon: send broadcast to update animated icon 09-20 03:41:42.013  5974  597

ajax学习之xml数据处理实例(网页注册用户名无刷新检测)

文件 reg.php <html> <head> <title>用户注册</title> <meta http-equiv="content-type" content="text/html;charset=utf-8"/> </head> <body> <form action="???" method="post">     用户名字:<input type="text"  οnkey

XRefreshView集成以及自定义下拉刷新动画

 XRefreshView集成以及自定义GIF动画 1继承第三方库    compile 'com.huxq17.xrefreshview:xrefreshview:3.6.9'     //依赖下面的库不然会报错    compile 'com.android.support:recyclerview-v7:23.0.1' 2项目xml使用

flutter key和globalkey如何使用及局部刷新

key和globalkey的使用,在实际开发中还是经常使用到的,尤其是globalkey设置到局部刷新会经常用到,例如TextView局部刷新等,还有其它任何控件需要局部刷新的也可以通过globalkey来实现,下面会有详细介绍。 key是标识widget的唯一性,组件能不能复用和更新主要通过key和组件的类型(runtimeType)来判断,如果key不传,则会判断组件的类型,globalke