मुख्य बातें
Pull-to-Refresh एक यूजर इंटरफ़ेस पैटर्न है जहां यूजर सामग्री को रिफ्रेश करने के लिए किसी लिस्ट या स्क्रोल करने योग्य क्षेत्र को नीचे खींचता है (पुल डाउन)। दृश्य रूप से, इशारे के साथ एक लोडिंग संकेतक (स्पिनर) होता है जो स्क्रीन के शीर्ष पर दिखाई देता है और डेटा प्राप्त होने के बाद गायब हो जाता है। इस पैटर्न को Tweetie एप द्वारा iPhone (2008) के लिए लोकप्रिय बनाया गया और बाद में Apple (iOS 6 — UIRefreshControl) और Google (Android Support Library — SwipeRefreshLayout) द्वारा मानकीकृत किया गया।
तकनीकी दृष्टिकोण से, Pull-to-Refresh पैनिंग (उंगली के विस्थापन को ट्रैक करना) और एक सीमा तक पहुंचने पर एक ट्रिगर का संयोजन है। यूजर प्रतिरोध (प्रतिरोधी ओवरस्क्रॉल) को पार करते हुए लिस्ट को नीचे खींचता है, और सीमा (~80px iOS पर, ~64dp Android पर) पार करने पर, संकेतक एनिमेशन और असिंक लोडिंग शुरू होता है। यदि यूजर सीमा से पहले अपनी उंगली छोड़ देता है — तो लिस्ट बिना अपडेट किए अपनी मूल स्थिति में लौट जाती है।
Material Design गाइडलाइंस के अनुसार, Pull-to-Refresh का उपयोग नहीं किया जाना चाहिए नेविगेशन या टैब स्विचिंग के लिए — इसका एकमात्र उद्देश्य डेटा रिफ्रेश है। IT Sectr में, हम Pull-to-Refresh का उपयोग समाचार फीड, ऑर्डर फीड और चैट में करते हैं जहां डेटा की ताजगी यूजर अनुभव के लिए महत्वपूर्ण है।
UIRefreshControl iOS में Pull-to-Refresh के लिए एक मानक नियंत्रण है, जो iOS 6 से उपलब्ध है। UIRefreshControl को refreshControl प्रॉपर्टी (iOS 10+) के माध्यम से UITableViewController में या पुराने संस्करणों में टेबल के subview के रूप में जोड़ा जाता है। इसमें एक बिल्ट-इन स्पिनर है जिसमें अनुकूलन योग्य रंग (tintColor), title विशेषता और एक कॅप्शन के साथ एक गुणात्मक स्ट्रिंग (उदाहरण के लिए, “अपडेट हो रहा है...”) शामिल है।
UIRefreshControl टार्गेट-एक्शन तंत्र के माध्यम से काम करता है: जब इशारा सक्रिय होता है, तो एक निर्दिष्ट विधि को बुलाया जाता है (उदाहरण के लिए, refresh(_:)) । विधि के अंदर, असिंक डेटा लोडिंग की जाती है। पूरा होने पर, endRefreshing() को बुलाया जाता है, जो एनिमेशन के साथ संकेतक को छुपाता है। UIRefreshControl स्वचालित रूप से इशारे की संवेदनशीलता का प्रबंधन करता है — यह केवल तब ही सक्रिय होता है जब टेबल शीर्ष स्थिति में हो (contentOffset.y <= 0) ।
tintColor प्रॉपर्टी स्पिनर का रंग निर्धारित करती है। title विशेषताएँ पूरा होने पर “2 मिनट पहले अपडेट किया गया” जैसे टेक्स्ट दिखाने की अनुमति देती हैं। iOS 10 से शुरू करके, UIRefreshControl UIActivityIndicatorView या स्थायी कस्टम व्यू के माध्यम से कस्टम एनिमेशन का समर्थन करता है। IT Sectr में, हम ब्रांड के अनुसार tintColor कॉन्फ़िगर करते हैं और attributedTitle के माध्यम से अंतिम अपडेट समय दिखाते हैं — इससे डेटा में यूजर का विश्वास बढ़ता है।
SwipeRefreshLayout Android Support Library (androidx.swiperefreshlayout) से एक ViewGroup है जो स्क्रोल करने योग्य सामग्री (RecyclerView, NestedScrollView, ListView) को लपेटता है और Pull-to-Refresh कार्यक्षमता जोड़ता है। UIRefreshControl (जो एक नियंत्रण है, कंटेनर नहीं) के विपरीत, SwipeRefreshLayout एक कंटेनर है जो चाइल्ड के टच इवेंट को इंटरसेप्ट करता है और सीमा पार होने पर रिफ्रेश संकेतक को ट्रिगर करता है।
SwipeRefreshLayout setColorSchemeColors() के माध्यम से रंग अनुकूलन के साथ एक गोलाकार Material Design प्रगति संकेतक का उपयोग करता है। setOnRefreshListener विधि onRefresh() कॉलबैक स्थापित करती है, जिसमें असिंक लोडिंग की जाती है। पूरा होने पर, संकेतक को छुपाने के लिए setRefreshing(false) को बुलाया जाता है। महत्वपूर्ण: setRefreshing(true) onRefresh() को फिर से बुलाता है — इसलिए प्रोग्रामेटिक रिफ्रेश के लिए, एक फ़्लैग या post विधि का उपयोग करें।
setProgressBackgroundColorSchemeResource प्रॉपर्टी संकेतक की पृष्ठभूमि को बदलती है। setSize(SwipeRefreshLayout.LARGE) — स्पिनर का आकार। XML लेआउट में, SwipeRefreshLayout RecyclerView को लपेटता है: swipe_refresh_layout → recycler_view। Google I/O 2024 के अनुसार, SwipeRefreshLayout का उपयोग सामग्री फीड वाले 85% Android एप में किया जाता है। IT Sectr में, हम असिंक रूप से लोड की गई सूचियों के साथ सभी स्क्रीन को SwipeRefreshLayout में लपेटते हैं — यह सभी Android संस्करणों में एक समान UX प्रदान करता है।
Android 12 (Material You) से शुरू करते हुए, Google material-1.6.0+ लाइब्रेरी (कंपोज़ के लिए androidx.compose.material3.pulltorefresh) से नए Material Pull-to-Refresh का उपयोग करने की अनुशंसा करती है। नया API स्प्रिंग एनिमेशन समर्थन और वालपेपर पर आधारित अनुकूलन रंग के साथ एक एनिमेटेड संकेतक का उपयोग करता है। SwipeRefreshLayout Android 12 से नीचे के संस्करणों के लिए संगत बना रहता है।
Pull-to-Refresh लागू करने में एक सरल पैटर्न है, लेकिन इसमें कई सामान्य गलतियाँ हैं जो UX को ख़राब करती हैं। आइए उन्हें और उन्हें रोकने के तरीकों की समीक्षा करें।
IT Sectr में, हमने परीक्षण सर्वर लॉग में डबलिकेट अनुरोधों की खोज के बाद प्रत्येक परियोजना में isRefreshing जाँच जोड़ी — पता चला कि तेज़ उंगलियों वाले यूजर लगातार 3 बार तक रिफ्रेश कर रहे थे।
कस्टम स्पिनर रंग और attributed title के साथ UITableViewController में Pull-to-Refresh जोड़ता है। डेटा लोड होने के बाद, संकेतक गायब हो जाता है।
import UIKit
class FeedTableViewController: UITableViewController {
private var items: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.refreshControl = UIRefreshControl()
refreshControl?.tintColor = .systemBlue
refreshControl?.attributedTitle = NSAttributedString(
string: "Pull down to refresh"
)
refreshControl?.addTarget(
self,
action: #selector(refreshData),
for: .valueChanged
)
}
@objc private func refreshData() {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
self.items = FeedService().fetchLatest()
self.tableView.reloadData()
self.refreshControl?.endRefreshing()
}
}
}
प्रॉपर्टी tableView.refreshControl (iOS 10+) UIRefreshControl सेट करती है। addTarget इवेंट .valueChanged के साथ इशारा सक्रिय होने पर ट्रिगर होता है। endRefreshing() अनिवार्य है — इसके बिना, संकेतक अनंत रूप से घूमता रहेगा। असिंक लोडिंग को DispatchQueue.main.asyncAfter के साथ अनुकृत किया गया है — एक वास्तविक परियोजना में, URLSession या async/await का उपयोग करें।
RecyclerView को कस्टम संकेतक रंगों के साथ SwipeRefreshLayout में लपेटता है। onRefresh लोडिंग शुरू करता है और पूरा होने पर संकेतक छुपाता है।
class FeedFragment : Fragment() {
private var _binding: FragmentFeedBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentFeedBinding.inflate(inflater, container, false)
binding.swipeRefreshLayout.setColorSchemeColors(
resources.getColor(R.color.brand_blue, null),
resources.getColor(R.color.brand_green, null)
)
binding.swipeRefreshLayout.setOnRefreshListener {
loadData()
}
return binding.root
}
private fun loadData() {
viewModelScope.launch {
try {
val result = repository.getLatestFeed()
adapter.submitList(result)
} finally {
binding.swipeRefreshLayout.isRefreshing = false
}
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
setColorSchemeColors घूमते Material Design संकेतक के रंग निर्धारित करता है। लोडिंग त्रुटि पर भी संकेतक छुपाने के लिए finally में isRefreshing = false अनिवार्य है। ViewModelScope.launch फ़्रैगमेंट के जीवनचक्र के भीतर एक कोरूटीन निष्पादित करता है — जब फ़्रैगमेंट नष्ट हो जाता है, तो कोरूटीन स्वचालित रूप से रद्द हो जाती है, मेमरी लीक को रोकते हुए।
आधुनिक SwiftUI .refreshable मॉडिफायर प्रदान करता है, जो स्वचालित रूप से List या ScrollView में Pull-to-Refresh जोड़ता है।
import SwiftUI
struct FeedView: View {
@State private var items: [String] = []
var body: some View {
List(items, id: \.self) { item in
Text(item)
}
.refreshable {
items = await FeedService().fetchLatestAsync()
}
}
}
.refreshable मॉडिफायर एक async-closure स्वीकार करता है जो Pull-to-Refresh पर निष्पादित होता है। SwiftUI स्वचालित रूप से रिफ्रेश संकेतक को दिखाता और छुपाता है, स्थिति दौड़ का प्रबंधन करता है (वर्तमान लोड पूरा होने तक लोडिंग पुनरारम्भ नहीं करता), और एनिमेशन को प्लेटफ़ॉर्म के अनुसार ढलता है। iOS 15+ के लिए, SwiftUI में Pull-to-Refresh लागू करने का यह पसंदीदा तरीका है।
अक्सर पूछे जाने वाले प्रश्न
हाँ, SwiftUI List या ScrollView के लिए .refreshable मॉडिफायर प्रदान करता है, जो iOS 15 से उपलब्ध है। closure के अंदर, असिंक डेटा लोडिंग कोड निष्पादित होता है। SwiftUI स्वचालित रूप से रिफ्रेश संकेतक का प्रबंधन करता है और वर्तमान लोड पूरा होने तक बार-बार लॉन्च को ब्लॉक करता है — नए प्रोजेक्ट के लिए यह मानक अनुशंसित दृष्टिकोण है।
isRefreshing फ़्लैग का उपयोग करें: लोडिंग शुरू होने पर इसे true और पूरा होने पर false सेट करें। iOS में, UIRefreshControl endRefreshing() के बुलाए जाने तक बार-बार की कॉल को स्वचालित रूप से ब्लॉक करता है। Android में, onRefresh() की शुरुआत में SwipeRefreshLayout.isRefreshing की जाँच करें: यदि true है — return करें। यह प्रति इशारे एक अनुरोध की गारंटी देता है।
UIRefreshControl और SwipeRefreshLayout केवल तब ही ट्रिगर होते हैं जब लिस्ट शीर्ष स्थिति में हो (contentOffset == 0)। आर्किटेक्चर टकराव को समाप्त करती है: जब तक लिस्ट 1पिक्सल भी स्क्रोल की जाती है, Pull-to-Refresh इशारा सक्रिय नहीं होता है। यदि टकराव होता है — Android में nestedScrollingEnabled या टच को इंटरसेप्ट करने वाले कस्टम GestureRecognizers की जाँच करें।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें