国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

使用安卓自帶刷新控件實(shí)現(xiàn)ListView的上拉加載和下拉刷新

2019-11-07 23:29:47
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

前篇已經(jīng)講過(guò)安卓自帶刷新控件沒(méi)有上拉加載需要自己自定義相關(guān)控件才能實(shí)現(xiàn)。先看下效果 這里寫(xiě)圖片描述 xml布局如下:

<?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="com.example.sw接下來(lái)是自定義刷新控件實(shí)現(xiàn)上拉加載了,本文以listView為例 幾點(diǎn)思路: 實(shí)現(xiàn)上拉加載需滿(mǎn)足一下幾點(diǎn)條件: 1.手勢(shì)上劃并達(dá)到一定距離 2.到底底部 3.當(dāng)前為非加載狀態(tài) 該自定義類(lèi)中設(shè)置一個(gè)接口回調(diào)對(duì)象以及里面的抽象方法,listview的滑動(dòng)事件監(jiān)聽(tīng)調(diào)用該借口方法,具體代碼邏輯在某界面中繼承接口實(shí)現(xiàn)該方法 具體代碼奉上

package com.example.swiperefresh4listview;import android.content.Context;import android.support.v4.widget.SwipeRefreshLayout;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.ViewConfiguration;import android.widget.AbsListView;import android.widget.ListView;/** * 自定義View繼承SwipeRefreshLayout,添加上拉加載更多的布局屬性 */public class Swiperefresh4ListView extends SwipeRefreshLayout{
PRivate final int mScaledTouchSlop; private final View mFooterView; private ListView mListView; private OnLoadListener mOnLoadListener; /** 正在加載狀態(tài)*/ private boolean isLoading; public Swiperefresh4ListView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub // 填充底部加載布局 mFooterView = View.inflate(context, R.layout.view_footer, null); // 表示控件移動(dòng)的最小距離,手移動(dòng)的距離大于這個(gè)距離才能拖動(dòng)控件 mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); // 獲取ListView,設(shè)置ListView的布局位置 if (mListView == null) { // 判斷容器有多少個(gè)孩子 if (getChildCount() > 0) { // 判斷第一個(gè)孩子是不是ListView if (getChildAt(0) instanceof ListView) { // 創(chuàng)建ListView對(duì)象 mListView = (ListView) getChildAt(0); // 設(shè)置ListView的滑動(dòng)監(jiān)聽(tīng) setListViewOnScroll(); } } } } /** * 在分發(fā)事件的時(shí)候處理子控件的觸摸事件 * @param ev * @return */ private float mDownY, mUpY; @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: // 移動(dòng)的起點(diǎn) mDownY = ev.getY(); break; case MotionEvent.ACTION_MOVE: // 移動(dòng)過(guò)程中判斷時(shí)候能下拉加載更多 if (canLoadMore()) { // 加載數(shù)據(jù) loadData(); } break; case MotionEvent.ACTION_UP: // 移動(dòng)的終點(diǎn) mUpY = getY(); break; } return super.dispatchTouchEvent(ev); } /** * 判斷是否滿(mǎn)足加載更多條件 * @return */ private boolean canLoadMore() { // 1. 是上拉狀態(tài) boolean condition1 = (mDownY - mUpY) >= mScaledTouchSlop; if (condition1) { System.out.println("是上拉狀態(tài)"); } // 2. 當(dāng)前頁(yè)面可見(jiàn)的item是最后一個(gè)條目 boolean condition2 = false; if (mListView != null && mListView.getAdapter() != null) { condition2 = mListView.getLastVisiblePosition() == (mListView.getAdapter().getCount() - 1); } if (condition2) { System.out.println("是最后一個(gè)條目"); } // 3. 正在加載狀態(tài) boolean condition3 = !isLoading; if (condition3) { System.out.println("不是正在加載狀態(tài)"); } return condition1 && condition2 && condition3; } /** * 處理加載數(shù)據(jù)的邏輯 */ private void loadData() { System.out.println("加載數(shù)據(jù)..."); if (mOnLoadListener != null) { // 設(shè)置加載狀態(tài),讓布局顯示出來(lái) setLoading(true); mOnLoadListener.onLoad(); } } /** * 設(shè)置加載狀態(tài),是否加載傳入boolean值進(jìn)行判斷,后期用來(lái)加載完成后隱藏布局 * @param loading */ public void setLoading(boolean loading) { // 修改當(dāng)前的狀態(tài) isLoading = loading; if (isLoading) { // 顯示布局 mListView.addFooterView(mFooterView); } else { // 隱藏布局 mListView.removeFooterView(mFooterView); // 重置滑動(dòng)的坐標(biāo) mDownY = 0; mUpY = 0; } } /** * 設(shè)置ListView的滑動(dòng)監(jiān)聽(tīng) */ private void setListViewOnScroll() { mListView.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { // 移動(dòng)過(guò)程中判斷能否能上拉加載更多 if (canLoadMore()) { // 加載數(shù)據(jù) loadData(); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }); } /** * 上拉加載的接口回調(diào) */ public interface OnLoadListener { void onLoad(); } public void setOnLoadListener(OnLoadListener listener) { this.mOnLoadListener = listener; }}

上面代碼中有一個(gè)底部布局,可以自己定義就不黏貼上來(lái)了 記下來(lái)具體界面中調(diào)用給接口方法

package com.example.swiperefresh4listview;import java.util.ArrayList;import java.util.List;import java.util.Random;import com.example.swiperefresh4listview.Swiperefresh4ListView.OnLoadListener;import android.os.Bundle;import android.os.Handler;import android.support.v4.widget.SwipeRefreshLayout;import android.support.v7.app.AppCompatActivity;import android.widget.ArrayAdapter;import android.widget.ListView;import android.widget.Toast;/** * 使用谷歌提供的SwipeRefreshLayout下拉控件進(jìn)行下拉刷新和上拉加載 */public class MainActivity extends AppCompatActivity { private List<String> mList; private int mCount; private ArrayAdapter<String> mAdapter; private Swiperefresh4ListView swipeRefreshView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initUI(); reFresh(); } private void initUI() { swipeRefreshView = (Swiperefresh4ListView) findViewById(R.id.srl); ListView listView = (ListView) findViewById(R.id.lv); // 設(shè)置適配器數(shù)據(jù) mList = new ArrayList<>(); for (int i = 0; i < 30; i++) { mList.add("我是laohu" + i + "號(hào)"); mCount++; } mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mList); listView.setAdapter(mAdapter); } private void reFresh() { // 設(shè)置顏色屬性的時(shí)候一定要注意是引用了資源文件還是直接設(shè)置16進(jìn)制的顏色,因?yàn)槎际莍nt值容易搞混 // 設(shè)置下拉進(jìn)度的背景顏色,默認(rèn)就是白色的 swipeRefreshView.setProgressBackgroundColorSchemeResource(android.R.color.white); // 設(shè)置下拉進(jìn)度的主題顏色 swipeRefreshView.setColorSchemeResources(R.color.colorAccent, R.color.colorPrimary, R.color.colorPrimaryDark); // 設(shè)置刷新出現(xiàn)的位置 swipeRefreshView.setProgressViewEndTarget(false,200); // 設(shè)置向下拉多少出現(xiàn)刷新 swipeRefreshView.setDistanceToTriggerSync(30); // 下拉時(shí)觸發(fā)SwipeRefreshLayout的下拉動(dòng)畫(huà),動(dòng)畫(huà)完畢之后就會(huì)回調(diào)這個(gè)方法 swipeRefreshView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { //默認(rèn)會(huì)自動(dòng)刷新無(wú)需調(diào)用這個(gè)屬性setRefreshing(boolean d) // 這里是主線程一些比較耗時(shí)的操作,比如聯(lián)網(wǎng)獲取數(shù)據(jù),需要放到子線程去執(zhí)行 final Random random = new Random(); new Handler().postDelayed(new Runnable() { @Override public void run() {// 刷新數(shù)據(jù)在這里 mList.add(0, "我是天才" + random.nextInt(100) + "號(hào)"); mAdapter.notifyDataSetChanged(); Toast.makeText(MainActivity.this, "刷新了一條數(shù)據(jù)", Toast.LENGTH_SHORT).show(); // 加載完數(shù)據(jù)設(shè)置為不刷新?tīng)顟B(tài),將下拉進(jìn)度收起來(lái) swipeRefreshView.setRefreshing(false); } }, 1200); // 這個(gè)不能寫(xiě)在外邊,不然會(huì)直接收起來(lái) // swipeRefreshLayout.setRefreshing(false); } }); // 設(shè)置下拉加載更多 swipeRefreshView.setOnLoadListener(new OnLoadListener() { @Override public void onLoad() { // TODO Auto-generated method stub new Handler().postDelayed(new Runnable() { @Override public void run() { // 添加數(shù)據(jù) for (int i = 30; i < 35; i++) { mList.add("我是小胡" + i + "號(hào)"); // 這里要放在里面刷新,放在外面會(huì)導(dǎo)致刷新的進(jìn)度條卡住 mAdapter.notifyDataSetChanged(); } Toast.makeText(MainActivity.this, "數(shù)據(jù)加載完成", Toast.LENGTH_SHORT).show(); // 加載完數(shù)據(jù)隱藏掉上拉加載布局 swipeRefreshView.setLoading(false); } }, 1200); } }); }}

思考:使用官方的下拉刷新可以實(shí)現(xiàn)自定義下拉刷新樣式嗎? 好的,上拉加載已經(jīng)實(shí)現(xiàn),后面在實(shí)際刷新過(guò)程中,發(fā)現(xiàn)一個(gè)問(wèn)題,就是下拉刷新在刷新過(guò)程中,如果下拉界面過(guò)短或者刷新顯示時(shí)常短,上拉到底部的時(shí)候,兩個(gè)會(huì)一起顯示,一個(gè)小bug,有待解決,還是第三方刷新比較好用。哪位大神看到能指導(dǎo)一二,以上代碼參考了網(wǎng)上資源,感謝各位大神分享。


發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 博野县| 金山区| 馆陶县| 乌兰察布市| 田林县| 邻水| 西峡县| 黔西县| 泰安市| 维西| 息烽县| 亚东县| 天水市| 巴青县| 北京市| 齐齐哈尔市| 东宁县| 博乐市| 莆田市| 抚州市| 法库县| 固安县| 泰州市| 三穗县| 乐至县| 许昌市| 潼关县| 铜鼓县| 灵山县| 综艺| 鹿邑县| 华亭县| 石柱| 诸暨市| 宁波市| 大厂| 大英县| 唐河县| 迭部县| 钟祥市| 措勤县|