এই নির্দেশিকাটি পেজিং লাইব্রেরি ওভারভিউয়ের উপর ভিত্তি করে তৈরি করে, আলোচনা করে যে আপনি কীভাবে আপনার অ্যাপের আর্কিটেকচারের চাহিদা মেটাতে আপনার অ্যাপের ডেটা-লোডিং সমাধান কাস্টমাইজ করতে পারেন।
একটি পর্যবেক্ষণযোগ্য তালিকা তৈরি করুন
সাধারণত, আপনার UI কোড একটি LiveData<PagedList>
অবজেক্ট পর্যবেক্ষণ করে (অথবা, আপনি যদি RxJava2 , একটি Flowable<PagedList>
বা Observable<PagedList>
অবজেক্ট ব্যবহার করেন), যা আপনার অ্যাপের ViewModel
থাকে। এই পর্যবেক্ষণযোগ্য বস্তুটি আপনার অ্যাপের তালিকা ডেটার উপস্থাপনা এবং বিষয়বস্তুর মধ্যে একটি সংযোগ তৈরি করে।
এই পর্যবেক্ষণযোগ্য PagedList
অবজেক্টগুলির মধ্যে একটি তৈরি করার জন্য, একটি LivePagedListBuilder
বা RxPagedListBuilder
অবজেক্টে DataSource.Factory
এর একটি উদাহরণে পাস করুন। একটি DataSource
অবজেক্ট একটি একক PagedList
জন্য পৃষ্ঠাগুলি লোড করে। ফ্যাক্টরি ক্লাস কন্টেন্ট আপডেটের প্রতিক্রিয়া হিসাবে PagedList
নতুন দৃষ্টান্ত তৈরি করে, যেমন ডাটাবেস টেবিল বাতিলকরণ এবং নেটওয়ার্ক রিফ্রেশ। রুম পারসিসটেন্স লাইব্রেরি আপনার জন্য DataSource.Factory
অবজেক্ট প্রদান করতে পারে, অথবা আপনি নিজের তৈরি করতে পারেন।
নিচের কোড স্নিপেটটি দেখায় কিভাবে আপনার অ্যাপের ViewModel
ক্লাসে রুম এর DataSource.Factory
ফ্যাক্টরি-বিল্ডিং ক্ষমতা ব্যবহার করে LiveData<PagedList>
এর একটি নতুন উদাহরণ তৈরি করতে হয়:
কোটলিন
@Dao interface ConcertDao { // The Int type parameter tells Room to use a PositionalDataSource // object, with position-based loading under the hood. @Query("SELECT * FROM concerts ORDER BY date DESC") fun concertsByDate(): DataSource.Factory<Int, Concert> }
জাভা
@Dao public interface ConcertDao { // The Integer type parameter tells Room to use a PositionalDataSource // object, with position-based loading under the hood. @Query("SELECT * FROM concerts ORDER BY date DESC") DataSource.Factory<Integer, Concert> concertsByDate(); }
কোটলিন
// The Int type argument corresponds to a PositionalDataSource object. val myConcertDataSource : DataSource.Factory<Int, Concert> = concertDao.concertsByDate() val concertList = myConcertDataSource.toLiveData(pageSize = 50)
জাভা
// The Integer type argument corresponds to a PositionalDataSource object. DataSource.Factory<Integer, Concert> myConcertDataSource = concertDao.concertsByDate(); LiveData<PagedList<Concert>> concertList = LivePagedListBuilder(myConcertDataSource, /* page size */ 50).build();
আপনার নিজস্ব পেজিং কনফিগারেশন সংজ্ঞায়িত করুন
উন্নত ক্ষেত্রে একটি LiveData<PagedList>
কনফিগার করতে, আপনি আপনার নিজস্ব পেজিং কনফিগারেশনও সংজ্ঞায়িত করতে পারেন। বিশেষ করে, আপনি নিম্নলিখিত বৈশিষ্ট্যগুলি সংজ্ঞায়িত করতে পারেন:
- পৃষ্ঠার আকার : প্রতিটি পৃষ্ঠায় আইটেমের সংখ্যা।
- প্রিফেচ দূরত্ব : একটি অ্যাপের UI-তে শেষ দৃশ্যমান আইটেমটি দেওয়া, এই শেষ আইটেমের বাইরে আইটেমের সংখ্যা যা পেজিং লাইব্রেরির আগে থেকে আনার চেষ্টা করা উচিত। এই মানটি পৃষ্ঠার আকারের চেয়ে কয়েকগুণ বড় হওয়া উচিত।
- প্লেসহোল্ডারের উপস্থিতি : UI তালিকা আইটেমগুলির জন্য স্থানধারক প্রদর্শন করে কিনা তা নির্ধারণ করে যেগুলি এখনও লোড করা শেষ হয়নি৷ স্থানধারক ব্যবহারের সুবিধা এবং অসুবিধাগুলি সম্পর্কে আলোচনার জন্য, কীভাবে আপনার UI-তে স্থানধারক প্রদান করবেন তা শিখুন।
পেজিং লাইব্রেরি কখন আপনার অ্যাপের ডাটাবেস থেকে একটি তালিকা লোড করে তার উপর আপনি যদি আরও নিয়ন্ত্রণ করতে চান, তাহলে LivePagedListBuilder
এ একটি কাস্টম Executor
অবজেক্ট পাস করুন, যেমনটি নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে:
কোটলিন
val myPagingConfig = Config( pageSize = 50, prefetchDistance = 150, enablePlaceholders = true ) // The Int type argument corresponds to a PositionalDataSource object. val myConcertDataSource : DataSource.Factory<Int, Concert> = concertDao.concertsByDate() val concertList = myConcertDataSource.toLiveData( pagingConfig = myPagingConfig, fetchExecutor = myExecutor )
জাভা
PagedList.Config myPagingConfig = new PagedList.Config.Builder() .setPageSize(50) .setPrefetchDistance(150) .setEnablePlaceholders(true) .build(); // The Integer type argument corresponds to a PositionalDataSource object. DataSource.Factory<Integer, Concert> myConcertDataSource = concertDao.concertsByDate(); LiveData<PagedList<Concert>> concertList = new LivePagedListBuilder<>(myConcertDataSource, myPagingConfig) .setFetchExecutor(myExecutor) .build();
সঠিক তথ্য উৎস টাইপ নির্বাচন করুন
ডেটা উৎসের সাথে সংযোগ করা গুরুত্বপূর্ণ যা আপনার উৎস ডেটার কাঠামোকে সবচেয়ে ভালোভাবে পরিচালনা করে:
- আপনি লোড করা পৃষ্ঠাগুলি পরবর্তী/পূর্ববর্তী কীগুলি এম্বেড করলে
PageKeyedDataSource
ব্যবহার করুন৷ উদাহরণস্বরূপ, আপনি যদি নেটওয়ার্ক থেকে সোশ্যাল মিডিয়া পোস্টগুলি আনছেন, তাহলে আপনাকে একটিnextPage
টোকেন একটি লোড থেকে পরবর্তী লোডে পাস করতে হতে পারে৷ - আইটেম N+1 আনতে আইটেম N থেকে ডেটা ব্যবহার করতে হলে
ItemKeyedDataSource
ব্যবহার করুন। উদাহরণস্বরূপ, আপনি যদি একটি আলোচনা অ্যাপের জন্য থ্রেডেড মন্তব্য আনছেন, তাহলে পরবর্তী মন্তব্যের বিষয়বস্তু পেতে আপনাকে শেষ মন্তব্যের আইডি পাস করতে হতে পারে। - আপনার ডেটা স্টোরে আপনার বেছে নেওয়া যেকোনো অবস্থান থেকে ডেটার পৃষ্ঠাগুলি আনতে হলে
PositionalDataSource
ব্যবহার করুন। এই শ্রেণীটি আপনার নির্বাচন করা যাই হোক না কেন অবস্থান থেকে শুরু করে ডেটা আইটেমগুলির একটি সেটের অনুরোধ সমর্থন করে৷ উদাহরণস্বরূপ, অনুরোধটি অবস্থান 1500 থেকে শুরু করে 50টি ডেটা আইটেম ফেরত দিতে পারে।
তথ্য অবৈধ হলে অবহিত করুন
পেজিং লাইব্রেরি ব্যবহার করার সময়, একটি টেবিল বা সারি বাসি হয়ে গেলে আপনার অ্যাপের অন্যান্য স্তরগুলিকে অবহিত করা ডেটা স্তরের উপর নির্ভর করে৷ এটি করার জন্য, DataSource
ক্লাস থেকে invalidate()
কল করুন যা আপনি আপনার অ্যাপের জন্য বেছে নিয়েছেন।
আপনার নিজস্ব ডেটা উত্স তৈরি করুন
আপনি যদি একটি কাস্টম স্থানীয় ডেটা সলিউশন ব্যবহার করেন, অথবা যদি আপনি সরাসরি একটি নেটওয়ার্ক থেকে ডেটা লোড করেন, আপনি DataSource
সাবক্লাসগুলির একটি বাস্তবায়ন করতে পারেন৷ নিম্নলিখিত কোড স্নিপেট একটি ডেটা উত্স দেখায় যা একটি প্রদত্ত কনসার্টের শুরুর সময় বন্ধ করে দেওয়া হয়:
কোটলিন
class ConcertTimeDataSource() : ItemKeyedDataSource<Date, Concert>() { override fun getKey(item: Concert) = item.startTime override fun loadInitial( params: LoadInitialParams<Date>, callback: LoadInitialCallback<Concert>) { val items = fetchItems(params.requestedInitialKey, params.requestedLoadSize) callback.onResult(items) } override fun loadAfter( params: LoadParams<Date>, callback: LoadCallback<Concert>) { val items = fetchItemsAfter( date = params.key, limit = params.requestedLoadSize) callback.onResult(items) } }
জাভা
public class ConcertTimeDataSource extends ItemKeyedDataSource<Date, Concert> { @NonNull @Override public Date getKey(@NonNull Concert item) { return item.getStartTime(); } @Override public void loadInitial(@NonNull LoadInitialParams<Date> params, @NonNull LoadInitialCallback<Concert> callback) { List<Concert> items = fetchItems(params.key, params.requestedLoadSize); callback.onResult(items); } @Override public void loadAfter(@NonNull LoadParams<Date> params, @NonNull LoadCallback<Concert> callback) { List<Concert> items = fetchItemsAfter(params.key, params.requestedLoadSize); callback.onResult(items); }
তারপর আপনি DataSource.Factory
এর একটি কংক্রিট সাবক্লাস তৈরি করে PagedList
অবজেক্টে এই কাস্টমাইজ করা ডেটা লোড করতে পারেন। নিম্নলিখিত কোড স্নিপেট দেখায় কিভাবে পূর্ববর্তী কোড স্নিপেটে সংজ্ঞায়িত কাস্টম ডেটা উৎসের নতুন উদাহরণ তৈরি করতে হয়:
কোটলিন
class ConcertTimeDataSourceFactory : DataSource.Factory<Date, Concert>() { val sourceLiveData = MutableLiveData<ConcertTimeDataSource>() var latestSource: ConcertDataSource? override fun create(): DataSource<Date, Concert> { latestSource = ConcertTimeDataSource() sourceLiveData.postValue(latestSource) return latestSource } }
জাভা
public class ConcertTimeDataSourceFactory extends DataSource.Factory<Date, Concert> { private MutableLiveData<ConcertTimeDataSource> sourceLiveData = new MutableLiveData<>(); private ConcertDataSource latestSource; @Override public DataSource<Date, Concert> create() { latestSource = new ConcertTimeDataSource(); sourceLiveData.postValue(latestSource); return latestSource; } }
বিষয়বস্তু আপডেট কিভাবে কাজ করে তা বিবেচনা করুন
আপনি পর্যবেক্ষণযোগ্য PagedList
অবজেক্ট তৈরি করার সময়, বিষয়বস্তু আপডেটগুলি কীভাবে কাজ করে তা বিবেচনা করুন। আপনি যদি সরাসরি একটি রুম ডাটাবেস থেকে ডেটা লোড করছেন তাহলে আপডেটগুলি স্বয়ংক্রিয়ভাবে আপনার অ্যাপের UI-তে পুশ হয়ে যাবে।
একটি পেজড নেটওয়ার্ক API ব্যবহার করার সময়, আপনার সাধারণত একটি ব্যবহারকারীর ইন্টারঅ্যাকশন থাকে, যেমন "রিফ্রেশ করতে সোয়াইপ করুন", আপনি সম্প্রতি যে DataSource
ব্যবহার করেছেন তা বাতিল করার জন্য একটি সংকেত হিসাবে কাজ করে৷ তারপরে আপনি সেই ডেটা উত্সের একটি নতুন উদাহরণের অনুরোধ করুন৷ এই নিম্নলিখিত কোড স্নিপেট এই আচরণ প্রদর্শন করে:
কোটলিন
class ConcertActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { // ... concertTimeViewModel.refreshState.observe(this, Observer { // Shows one possible way of triggering a refresh operation. swipeRefreshLayout.isRefreshing = it == MyNetworkState.LOADING }) swipeRefreshLayout.setOnRefreshListener { concertTimeViewModel.invalidateDataSource() } } } class ConcertTimeViewModel(firstConcertStartTime: Date) : ViewModel() { val dataSourceFactory = ConcertTimeDataSourceFactory(firstConcertStartTime) val concertList: LiveData<PagedList<Concert>> = dataSourceFactory.toLiveData( pageSize = 50, fetchExecutor = myExecutor ) fun invalidateDataSource() = dataSourceFactory.sourceLiveData.value?.invalidate() }
জাভা
public class ConcertActivity extends AppCompatActivity { @Override public void onCreate(@Nullable Bundle savedInstanceState) { // ... viewModel.getRefreshState() .observe(this, new Observer<NetworkState>() { // Shows one possible way of triggering a refresh operation. @Override public void onChanged(@Nullable MyNetworkState networkState) { swipeRefreshLayout.isRefreshing = networkState == MyNetworkState.LOADING; } }; swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshListener() { @Override public void onRefresh() { viewModel.invalidateDataSource(); } }); } } public class ConcertTimeViewModel extends ViewModel { private LiveData<PagedList<Concert>> concertList; private DataSource<Date, Concert> mostRecentDataSource; public ConcertTimeViewModel(Date firstConcertStartTime) { ConcertTimeDataSourceFactory dataSourceFactory = new ConcertTimeDataSourceFactory(firstConcertStartTime); mostRecentDataSource = dataSourceFactory.create(); concertList = new LivePagedListBuilder<>(dataSourceFactory, 50) .setFetchExecutor(myExecutor) .build(); } public void invalidateDataSource() { mostRecentDataSource.invalidate(); } }
ডেটা ম্যাপিং প্রদান করুন
পেজিং লাইব্রেরি একটি DataSource
দ্বারা লোড করা আইটেম-ভিত্তিক এবং পৃষ্ঠা-ভিত্তিক রূপান্তর সমর্থন করে।
নিম্নলিখিত কোড স্নিপেটে, কনসার্টের নাম এবং কনসার্টের তারিখের সংমিশ্রণটি নাম এবং তারিখ উভয়ই সমন্বিত একটি একক স্ট্রিং-এ ম্যাপ করা হয়েছে:
কোটলিন
class ConcertViewModel : ViewModel() { val concertDescriptions : LiveData<PagedList<String>> init { val concerts = database.allConcertsFactory() .map { "${it.name} - ${it.date}" } .toLiveData(pageSize = 50) } }
জাভা
public class ConcertViewModel extends ViewModel { private LiveData<PagedList<String>> concertDescriptions; public ConcertViewModel(MyDatabase database) { DataSource.Factory<Integer, Concert> factory = database.allConcertsFactory().map(concert -> concert.getName() + "-" + concert.getDate()); concertDescriptions = new LivePagedListBuilder<>( factory, /* page size */ 50).build(); } }
আপনি যদি আইটেমগুলি লোড হওয়ার পরে মোড়ানো, রূপান্তর করতে বা প্রস্তুত করতে চান তবে এটি কার্যকর হতে পারে। যেহেতু এই কাজটি ফেচ এক্সিকিউটরে করা হয়, আপনি সম্ভাব্য ব্যয়বহুল কাজ করতে পারেন, যেমন ডিস্ক থেকে পড়া বা একটি পৃথক ডাটাবেস অনুসন্ধান করা।
মতামত প্রদান
এই সম্পদগুলির মাধ্যমে আমাদের সাথে আপনার প্রতিক্রিয়া এবং ধারণা শেয়ার করুন:
- ইস্যু ট্র্যাকার
- সমস্যাগুলি রিপোর্ট করুন যাতে আমরা বাগগুলি ঠিক করতে পারি৷
অতিরিক্ত সম্পদ
পেজিং লাইব্রেরি সম্পর্কে আরও জানতে, নিম্নলিখিত সংস্থানগুলি দেখুন৷
নমুনা
কোডল্যাব
ভিডিও
- অ্যান্ড্রয়েড জেটপ্যাক: রিসাইক্লারভিউ এবং পেজিং (গুগল I/O '18) সহ অসীম তালিকা পরিচালনা করুন
- অ্যান্ড্রয়েড জেটপ্যাক: পেজিং
আপনার জন্য প্রস্তাবিত
- দ্রষ্টব্য: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট প্রদর্শিত হয়
- পেজিং 3 এ স্থানান্তর করুন
- পেজিং 2 লাইব্রেরি ওভারভিউ
- পৃষ্ঠাযুক্ত তালিকা প্রদর্শন করুন