当前位置:网站首页>Pull down refresh and pull up to load more listviews
Pull down refresh and pull up to load more listviews
2022-06-22 19:26:00 【Liuyichu】
PullToRefreshListView
- Customize ListView
- With simple pull-down refresh and pull-up load more functions
Implementation process
Inherit existing controls (ListView) Implement custom control , Pull down to refresh the three states. The effect is as follows :



to ListView Add head and feet
- Head layout
<?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="60dp"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_arrow"
android:layout_width="20dp"
android:layout_height="45dp"
android:layout_marginRight="20dp"
android:src="@drawable/common_listview_headview_red_arrow" />
<ImageView
android:id="@+id/iv_loading"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/action_progress_image"
android:visibility="gone" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="45dp"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="25dp"
android:text=" The drop-down refresh "
android:textSize="18sp" />
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:text=" Last refresh time :mm:hh:ss" />
</LinearLayout>
</LinearLayout>
- Foot layout
<?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:gravity="center"
android:orientation="horizontal">
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" Playing with life loading ..." />
</LinearLayout>
- The following post PullToRefreshListView Complete code , as follows :
public class PullToRefreshListView extends ListView implements AbsListView.OnScrollListener { private View header; private int headerMeasuredHeight; private TextView tvTitle; private TextView tvTime; private ImageView ivArrow; private ImageView ivLoading; private RotateAnimation pullAnimaton; private RotateAnimation releaseAnimation; private RotateAnimation loadingAnimation; private onPullToRefreshListener onPullToRefreshListener; private View footer; private int footerMeasureHeight; public void setOnPullToRefreshListener(cn.com.bsoft.pulltorefreshlistview.view.onPullToRefreshListener onPullToRefreshListener) { this.onPullToRefreshListener = onPullToRefreshListener; } public PullToRefreshListView(Context context) { this(context, null); } public PullToRefreshListView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public PullToRefreshListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // to ListView Add head initHeader(); initFooter(); } private void initFooter() { footer = View.inflate(getContext(), R.layout.footer_view, null); footer.measure(0, 0); footerMeasureHeight = footer.getMeasuredHeight(); footer.setPadding(0, -footerMeasureHeight, 0, 0); addFooterView(footer); setOnScrollListener(this); } private void initHeader() { header = View.inflate(getContext(), R.layout.header_view, null); header.measure(0, 0);// Also run in the constructor , At this time, you cannot directly obtain header Height , So call the measurement , Get more header Height headerMeasuredHeight = header.getMeasuredHeight(); header.setPadding(0, -headerMeasuredHeight, 0, 0); addHeaderView(header); tvTitle = ((TextView) header.findViewById(R.id.tv_title)); tvTime = ((TextView) header.findViewById(R.id.tv_time)); ivArrow = ((ImageView) header.findViewById(R.id.iv_arrow)); ivLoading = ((ImageView) header.findViewById(R.id.iv_loading)); // Release refresh animation releaseAnimation = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); releaseAnimation.setDuration(300); releaseAnimation.setFillAfter(true);// Stop there after the animation // Pull down animation pullAnimaton = new RotateAnimation(180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); pullAnimaton.setDuration(300); pullAnimaton.setFillAfter(true); // Refreshing animation loadingAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); loadingAnimation.setDuration(300); loadingAnimation.setRepeatCount(Animation.INFINITE); loadingAnimation.setInterpolator(new LinearInterpolator());// Set the animation inserter with uniform speed loadingAnimation.setFillAfter(true); } private int downY; @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN:
downY = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
int moveY = (int) ev.getY();
int dy = moveY - downY;
downY = moveY;
int headerPaddingTop = header.getPaddingTop();
//1. Judge whether the currently fully displayed item is listview The first entry of
//2. Judge the sliding state . Slide down to show listview Slide up to hide listview
if (state != State.REFRESHING && getFirstVisiblePosition() == 0 && (dy > 0 || headerPaddingTop > -headerMeasuredHeight)) {
headerPaddingTop += dy;
header.setPadding(0, headerPaddingTop, 0, 0);
if (headerPaddingTop >= 0) {
setState(State.RELEASE_TO_REFRESH);
} else {
setState(State.PULL_TO_REFRESH);
}
return true;
}
break;
case MotionEvent.ACTION_UP:
// Restore header
resetHeader();
break;
default:
break;
}
return super.onTouchEvent(ev);
}
private void resetHeader() {
if (state == State.PULL_TO_REFRESH) {// When you raise your hand In the pull-down refresh state
header.setPadding(0, -headerMeasuredHeight, 0, 0);
} else if (state == State.RELEASE_TO_REFRESH) {// When you raise your hand In release refresh state
// Enter refresh in progress
header.setPadding(0, 0, 0, 0);
setState(State.REFRESHING);
if (onPullToRefreshListener != null) {
onPullToRefreshListener.onRefresh();
}
}
}
private boolean isLoading = false;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
int count = view.getAdapter().getCount();
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE
&& getLastVisiblePosition() == count - 1
&& isLoading == false) {
isLoading = true;
footer.setPadding(0, 0, 0, 0);
setSelection(count - 1);
// Load more data
if (onPullToRefreshListener==null) {
onPullToRefreshListener.loadMore();
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
private enum State {
RELEASE_TO_REFRESH, PULL_TO_REFRESH, REFRESHING, START
}
private State state = State.START;
/**
* Set up listview current state
* @param state
*/
private void setState(State state) {
if (this.state != state) {
if (state == State.RELEASE_TO_REFRESH) {// Release refresh
tvTitle.setText(" Release refresh ");
ivArrow.setAnimation(releaseAnimation);
} else if (state == State.PULL_TO_REFRESH) {
tvTitle.setText(" The drop-down refresh ");
ivArrow.setAnimation(pullAnimaton);
} else if (state == State.REFRESHING) {
tvTitle.setText(" Refreshing ");
ivArrow.setVisibility(View.GONE);
ivArrow.clearAnimation();
ivLoading.setVisibility(View.VISIBLE);
ivLoading.setAnimation(loadingAnimation);
java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat("hh:mm:ss");
String date = dateFormat.format(new Date());
tvTime.setText(date);
}
this.state = state;
}
}
// Refresh complete
public void completeRefresh() {
ivLoading.clearAnimation();
ivLoading.setVisibility(View.GONE);
ivArrow.setVisibility(View.VISIBLE);
setState(State.PULL_TO_REFRESH);
header.setPadding(0, -headerMeasuredHeight, 0, 0);
}
// Loading complete
public void completeLoadMore(){
isLoading=false;
footer.setPadding(0,-footerMeasureHeight,0,0);
}
}- Interface implementation :onPullToRefreshListener
public interface onPullToRefreshListener {
public void onRefresh();
public void loadMore();
}Usage method
- 1. Direct reference in layout PullToRefreshListView that will do
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="cn.com.bsoft.pulltorefreshlistview.activity.MainActivity">
<cn.com.bsoft.pulltorefreshlistview.view.PullToRefreshListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/ptr_listview" />
</RelativeLayout>
- 2. Find the control input interface in the interface :setOnPullToRefreshListener
public class MainActivity extends AppCompatActivity { private PullToRefreshListView pullToRefreshListView; private ArrayAdapter<String> adapter; private List<String> dataList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); pullToRefreshListView = ((PullToRefreshListView) findViewById(R.id.ptr_listview)); List<String> datas = getDatas(); adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, datas); pullToRefreshListView.setAdapter(adapter); // Set callback monitor pullToRefreshListView.setOnPullToRefreshListener(new onPullToRefreshListener() { // Pulldown refresh callback @Override public void onRefresh() { // Analog data acquisition new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } final String addData = " You are the only one for me in this multifarious world "; // Refresh adapter in main thread runOnUiThread(new Runnable() { @Override public void run() { dataList.add(0, addData); adapter.notifyDataSetChanged(); // Call after data acquisition completeRefresh() Method pullToRefreshListView.completeRefresh(); } }); } }).start(); } // Pull up to load more callbacks @Override public void loadMore() { // Analog data acquisition new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } final String addData = " A little cold comes first Then the gun came out like a dragon "; runOnUiThread(new Runnable() { @Override public void run() { dataList.add(0, addData); adapter.notifyDataSetChanged(); // Call after data acquisition completeLoadMore() Method pullToRefreshListView.completeLoadMore(); } }); } }).start(); } }); } public List<String> getDatas() { dataList = new ArrayList<>(); for (int i = 0; i < 20; i++) { dataList.add(" Most afraid of life mediocrity , But comfort yourself to say that ordinary is valuable !"); } return dataList; } }GIF effect

Conclusion
- Play for the first time GIF chart , It took half an hour to fix it , Pulling and loading more data is over before it comes out .
- It is also the first time to use Markdown Editor , Not skilled yet .
- The above is a very simple pull-down refresh and pull-up load ListView.
- Dare not compare with the custom controls of various gods , Post it as a summary of your study , Of course , Can help beginners Android It would be better if we were new people .
边栏推荐
- Iplook and SBC establish long-term cooperation
- China's games are "harvesting" foreigners
- 牛客网:最小覆盖子串
- Shell programming specification and variables
- 2022 Chongqing preschool education industry exhibition 𞓜 hi tech Toy Puzzle decompression Toy Expo
- Some technical ideas:
- jniLibs. Srcdirs = ['LIBS'] what's the use?
- jniLibs.srcDirs = [‘libs‘]有什么用?
- PostgreSQL reconfigure from library
- Set of redis data structure
猜你喜欢

3GPP 5G R17标准冻结,RedCap作为重要特性值得关注!

Notes on new reports

shell脚本(五)——函数

Shell script explanation (IV) -- while loop and until loop of loop statements (additional examples and analysis)

2022 t elevator repair recurrent training question bank and answers

Flutter2.0运行在web上不同渲染器的问题

5GC和卫星融合通信方案

一款支持HomeKit的摄像头?智汀 IPC摄像头IC1开箱体验

机械设备行业数字化供应链集采平台解决方案:优化资源配置,实现降本增效

Active Directory用户登录报告
随机推荐
codeup最长回文子串
同花顺难开户么?网上开户安全么?
如何更改Apple Watch上的表盘
chrome突然无法复制粘贴了
3GPP 5G R17标准冻结,RedCap作为重要特性值得关注!
RobotFramework 安装教程
回文数(简单版)
5G 短消息解决方案
Shell编程规范与变量
AIOps 智能运维经验分享
2022 t elevator repair recurrent training question bank and answers
2022 R2 mobile pressure vessel filling test question simulation test platform operation
新人报道的笔记
Some technical ideas:
wpa_ State machine migration of supplicant
shell脚本详解(七)——正则表达式、sort、uniq、tr
Modèle de langage de pré - formation, Bert, roformer Sim aussi connu sous le nom de simbertv2
数字赋能机械制造业,供应链协同管理系统解决方案助力企业供应链再升级
China's two meteorological "new stars" data products are shared with global users
2022 G2 power plant boiler stoker question bank and online simulation examination