自定義SwipeRefreshLayout 巢狀listview 並解決item點選事件焦點衝突問題
最近專案需要實現上拉載入更多,為了不引入第三方庫,可以使用自定義SwipeRefreshLayout 來實現,
作品摘自 簡書:http://www.jianshu.com/p/d23b42b6360b
但是在使用的時候發現有個bug,就是當頁面顯示最後一條資料的時候 ,listview 的點選事件不響應了,但是響應的是正在載入。所以我就在原來的基礎上稍加改動:
一下是自定義的全部程式碼:
import android.content.Context;
import android.support.v4.widget.SwipeRefreshLayout; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.widget.AbsListView; import android.widget.ListView; import .R; /** * @author: qiaohao * time: 2017/11/14 15:57 * desc:PulltoRefreshView */ public class PulltoRefreshView extends SwipeRefreshLayout implements AbsListView.OnScrollListener { /** * 滑動到最下面時的上拉操作 */ private int mTouchSlop; /** * listview例項 */ private ListView mListView; /** * 上拉監聽器, 到了最底部的上拉載入操作 */ private OnLoadListener mOnLoadListener; /** * ListView的載入中footer */ private View mListViewFooter; /** * 按下時的y座標 */ private int mYDown; /** * 擡起時的y座標, 與mYDown一起用於滑動到底部時判斷是上拉還是下拉 */ private int mLastY; /** * 是否在載入中 ( 上拉載入更多 ) */ private boolean isLoading = false; private boolean isActionDown; public PulltoRefreshView(Context context, AttributeSet attrs) { super(context, attrs); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); mListViewFooter = LayoutInflater.from(context).inflate(R.layout.listview_footer, null, false); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); // 初始化ListView物件 if (mListView == null) { getListView(); } } /** * 獲取ListView物件 */ private void getListView() { int childs = getChildCount(); if (childs > 0) { View childView = getChildAt(1); if (childView instanceof ListView) { mListView = (ListView) childView; // 設定滾動監聽器給ListView, 使得滾動的情況下也可以自動載入 mListView.setOnScrollListener(this); } } } /* * (non-Javadoc) * @see android.view.ViewGroup#dispatchTouchEvent(android.view.MotionEvent) */ @Override public boolean dispatchTouchEvent(MotionEvent event) { final int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: // 按下 mYDown = (int) event.getRawY(); isActionDown=true; break; //注意這裡的程式碼跟原文的程式碼有點區別是為了上拉的時候顯示Loadding佈局 case MotionEvent.ACTION_MOVE: // 移動 if (canLoadMore()) { loadData(); } break; case MotionEvent.ACTION_UP: // 擡起 isActionDown=false; mLastY = (int) event.getRawY(); break; default: break; } return super.dispatchTouchEvent(event); } /** * 判斷是否滿足載入更多條件 * * @return */ private boolean canLoadMore() { // 1. 是上拉狀態 boolean condition1 = (mYDown - mLastY) >= mTouchSlop; if (condition1) { System.out.println("是上拉狀態"); } // 2. 當前頁面可見的item是最後一個條目 boolean condition2 = false; if (mListView != null && mListView.getAdapter() != null) { condition2 = mListView.getLastVisiblePosition() == (mListView.getAdapter().getCount() - 1); } if (condition2) { System.out.println("是最後一個條目"); } // 3. 正在載入狀態 boolean condition3 = !isLoading; if (condition3) { System.out.println("不是正在載入狀態"); } return condition1 && condition2 && condition3; } /** * 處理載入資料的邏輯 */ private void loadData() { System.out.println("載入資料..."); if (mOnLoadListener != null) { // 設定載入狀態,讓佈局顯示出來 setLoading(true); mOnLoadListener.onLoad(); } } /** * @param loading */ public void setLoading(boolean loading) { isLoading = loading; if (isLoading) { mListView.addFooterView(mListViewFooter); } else { mListView.removeFooterView(mListViewFooter); mYDown = 0; mLastY = 0; } } /** * @param loadListener */ public void setOnLoadListener(OnLoadListener loadListener) { mOnLoadListener = loadListener; } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // 滾動時到了最底部也可以載入更多 // if (canLoadMore()) { // loadData(); // } } /** * 載入更多的監聽器 * * @author mrsimple */ public static interface OnLoadListener { public void onLoad(); } }
使用方法:
xml
java:<com.view.custom.PulltoRefreshView android:id="@+id/refresh_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:background="@color/white" android:id="@+id/rv_record_list" android:layout_width="match_parent" android:layout_height="match_parent" ></ListView> </com.view.custom.PulltoRefreshView>
refreshLayout = (PulltoRefreshView) findViewById(R.id.refresh_layout); //設定重新整理時動畫的顏色,可以設定4個 refreshLayout.setColorSchemeResources(android.R.color.holo_blue_light, android.R.color.holo_red_light, android.R.color.holo_orange_light, android.R.color.holo_green_light); refreshLayout.setOnRefreshListener(this); refreshLayout.setOnLoadListener(this);
分別去實現
SwipeRefreshLayout.OnRefreshListener,PulltoRefreshView.OnLoadListener
這兩個介面,然後重寫onRefresh(){}
和 onLoad(){}
載入更多佈局 R.layout.listview_footer xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@color/white" android:gravity="center" android:paddingBottom="8dip" android:paddingTop="5dip" android:focusable="false"> <ProgressBar android:id="@+id/pull_to_refresh_load_progress" style="@android:style/Widget.ProgressBar.Small.Inverse" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_centerHorizontal="true" android:paddingRight="100dp" android:indeterminate="true" /> <TextView android:layout_marginLeft="17dp" android:id="@+id/pull_to_refresh_loadmore_text" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:paddingTop="5dip" android:text="正在載入更多..." android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="@android:color/darker_gray" android:textSize="14sp" android:textStyle="bold" /> </RelativeLayout>
解決item點選事件焦點衝突的方法:item 佈局的根佈局中加入android:descendantFocusability="blocksDescendants"
相關推薦
自定義SwipeRefreshLayout 巢狀listview 並解決item點選事件焦點衝突問題
最近專案需要實現上拉載入更多,為了不引入第三方庫,可以使用自定義SwipeRefreshLayout 來實現,作品摘自 簡書:http://www.jianshu.com/p/d23b42b6360b但是在使用的時候發現有個bug,就是當頁面顯示最後一條資料的時候 ,lis
YII框架的自定義佈局(巢狀式佈局,版本是1.1.20)
0x01 建立控制器 0x02 建立資料夾,之後建立檢視檔案 0x03 瀏覽器訪問cxy/index控制器,驗證 以上就是使用預設的佈局,非常簡單,那麼如果我不想用YII框架預設的佈局呢,我想用自定義的佈局,可以通過修改CController類中的$la
Android開發之ScrollView中巢狀ListView的解決方案
import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.widget.BaseAdapter;
在select parameterType自定義型別巢狀迴圈List資料
因為要做內容統計資訊,就將要傳入的引數放在一個Bean中去了,有一個欄位為狀態值,型別為List型別,但一直執行不成功, 最後發現的問題是 <![CDATA[ ]]>用這個符號將for
Flutter SingleChildScrollView 巢狀 ListView 或者其他可以滾動weiget 滑動滾動衝突問題
場景 當我們使用SingleChildScrollView 整個佈局包含了ListView 滑動時會產生衝突 滾動卡頓,不流暢 原因 SingleChildScrollView 和 ListView 都有滾動屬性physics 他們預設是都是可以滾動的 解決方式 禁用
com4j學習(2):Visio自定義模具和形狀,並新增連線點
前言: 既然我們想繪製跟自己業務相關的圖形,並讀取Visio圖形中的結構資訊,那麼我們自然會想到要自定義圖形,本文詳細講解如何自定義圖形。 正文: 首先我們要明白什麼是模具,什麼是形狀,以及兩者之間的關係?模具就相當於一個容器,裡面有很多個形狀,我們可
百度地圖根據座標自定義覆蓋物,並實現其點選事件
在很多APP中都會用到百度地圖,以實現各種功能,本片文章介紹在百度地圖中新增自定義覆蓋物並新增其點選事件 public class NearByFragment extends Fragment { private MapView mapView;
ListView中自定義Item點選事件處理
開發中很常見的一個問題,專案中的listview不僅僅是簡單的文字,常常需要自己定義listview的Item,自己的Adapter去繼承BaseAdapter,在adapter中按照需求進行編寫,問題就出現了,可能會發生點選每一個item的時候沒有反應,無法獲
Android成長實戰系列文章之ListView Item和Button點選事件的衝突原因和解決方案
筆者熱衷於技術,也是一名在Android方向上滾爬的程式設計師,以下是我技術總結系列文章: 此係列文章屬於Android成長實戰系列,主要以專案中實際用到的東西分享出來,更注重於實戰程式設計能力的培養。 在我們實際專案開發過程中難免遇到各種事件分發有關問題,
listview的item裡面有Button,並給其設定了點選事件,而且有效可點選,但是listview的item點選事件卻失效了
問題:listview的item裡面有Button,並給其設定了點選事件,而且有效可點選, 但是listview的item點選事件卻失效了 解決方案一,測試有效:android:descendantF
swing 自定義最小化按鈕後,實現點選工作列圖示,使窗體重新顯示
jf.setUndecorated(true); // 去掉視窗的裝飾 jf.getRootPane().setWindowDecorationStyle(JRootPane.NONE)
Android自定義控制元件:Android L控制元件點選水波紋的實現(原始碼 + Demo)
Demo: 一、控制元件的流程: 大致上如下,實際是有些偏差的大家可以自己畫畫 RevealLayout()--->init()--->onMeasure()--->onLayout()--->onDraw()--->dispat
Recyclerview或Listview實時重新整理,item點選事件失效的解決方法
問題場景: 本人最近在做一個關於藍芽開發的Demo,在掃描藍芽裝置的時候會產生回撥,並會返回BluetoothDevice和rssi,這個rssi就是掃描到的這個裝置的訊號。 注意,這個回撥不是搜尋到1個裝置後就只回調一次這個裝置,而是隻要掃描到了就會回
解決ListView中Item的子控制元件(比如Button)與Item點選事件衝突
經常會碰到在ListView中點選其中一個Item,會一併觸發其子控制元件的點選事件,例如Item中的Button、ImageButton等,導致了點選Item中Button以外區域也會觸發Button點選事件。在網上找了相關方法,這裡記錄下,親測可行.. 1、在Item
popupwindow中ListView item點選事件無效的解決方案
在Popupwindow中佈局ListView後,如果popupwindow的focusable設定為false 的話,ListView的item的點選事件 出現如下情況: API < 19 :onItemClick 事件無效 API >=19:
Android Listview中Button按鈕點選事件衝突解決辦法
今天做專案時,ListView中含有了Button元件,心裡一早就知道肯定會有衝突,因為以前就遇到過,並解決過,可惜當時沒有記錄下來。 今天在做的時候,繼續被這個問題鬱悶了一把,後來解決後,趕緊來記錄下,以便日後參考。 首先,其實Listview中Button按
android捕獲ListView中每個item點擊事件
ont app eat sta cell undle android number stat package com.wps.android; import java.util.ArrayList; import android.app.Activity;
Activity中響應ListView內部按鈕的點選事件
最近交流群裡面有人問到一個問題:如何在Activity中響應ListView內部按鈕的點選事件,不要在Adapter中響應? 對於這個問題,我最初給他的解答是,在Adapter中定義一個回撥介面,在Activity中實現該介面,從而實現對點選事件的響應。 下班後思考了一下,覺得有兩種方式都能
點選div外區域隱藏div(解決與點選按鈕觸發衝突)
$(document).ready(function() { $(".B").hide(); $(".A").click(function() { $(".B").toggle(); }); }).click(function(e) { e = e || window.event; if(e
Android Studio ListView的item點選事件彈出AlertDialog,和item的滑動
首先看看效果圖: 點選彈出AlertDialog的確認框! (一)第一步,建立一個xml檔案顯示item的佈局 student_item.xml <?xml version="1.0" encoding="utf-8"?> <LinearLa