পৃষ্ঠার ডেটা সংগ্রহ করুন

এই গাইড পেজিং লাইব্রেরি ওভারভিউ-এর উপর ভিত্তি করে তৈরি করা হয়েছে, যেখানে আপনার অ্যাপের আর্কিটেকচারের প্রয়োজনীয়তা পূরণ করার জন্য কীভাবে অ্যাপের ডেটা-লোডিং সমাধান কাস্টমাইজ করবেন তা আলোচনা করা হয়েছে।

পর্যবেক্ষণযোগ্য তালিকা তৈরি করুন

সাধারণত, আপনার UI কোড একটি LiveData<PagedList> অবজেক্ট (অথবা, আপনি RxJava2 ব্যবহার করলে, একটি Flowable<PagedList> বা Observable<PagedList> অবজেক্ট) পর্যবেক্ষণ করে, যা আপনার অ্যাপের ViewModel-এ থাকে। এই পর্যবেক্ষণযোগ্য অবজেক্টটি আপনার অ্যাপের তালিকা ডেটার প্রেজেন্টেশন এবং কন্টেন্টের মধ্যে একটি কানেকশন তৈরি করে।

এইসব পর্যবেক্ষণযোগ্য PagedList অবজেক্টের মধ্যে একটি তৈরি করতে, DataSource.Factory-এর একটি ইনস্ট্যান্স LivePagedListBuilder বা RxPagedListBuilder অবজেক্টে পাস করুন। DataSource অবজেক্ট একটি PagedList-এর জন্য পৃষ্ঠা লোড করে। ফ্যাক্টরি ক্লাস কন্টেন্ট আপডেটের উত্তরে PagedList-এর নতুন ইনস্ট্যান্স তৈরি করে, যেমন ডেটাবেস টেবিল ইনভ্যালিডেশন ও নেটওয়ার্ক রিফ্রেশ। রুম পারসিসটেন্স লাইব্রেরি আপনার জন্য DataSource.Factory অবজেক্ট প্রদান করতে পারে অথবা আপনি নিজের অবজেক্ট তৈরি করতে পারেন।

নিম্নলিখিত কোড স্নিপেট দেখায় যে কীভাবে Room-এর DataSource.Factory-বিল্ডিং ক্ষমতা ব্যবহার করে আপনার অ্যাপের ViewModel ক্লাসে LiveData<PagedList>-এর নতুন ইনস্ট্যান্স তৈরি করতে হয়:

ConcertDao

Kotlin

@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();
}

ConcertViewModel

Kotlin

// 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 অবজেক্ট পাস করুন, যেমনটি নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে:

ConcertViewModel

Kotlin

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 ব্যবহার করুন। এই ক্লাস আপনার বেছে নেওয়া লোকেশন থেকে শুরু করে ডেটা আইটেমের সেট অনুরোধ করার সুবিধা দেয়। যেমন, অনুরোধটি লোকেশন ১৫০০ থেকে শুরু করে ৫০টি ডেটা আইটেম ফেরত দিতে পারে।

ডেটা ভুল হলে বিজ্ঞপ্তি পান

পেজিং লাইব্রেরি ব্যবহার করার সময়, কোনও টেবিল বা সারি পুরনো হয়ে গেলে, আপনার অ্যাপের অন্যান্য লেয়ারকে বিজ্ঞপ্তি পাঠানোর দায়িত্ব ডেটা লেয়ার-এর উপর বর্তায়। এটি করতে, আপনার অ্যাপের জন্য বেছে নেওয়া DataSource ক্লাস থেকে invalidate() কল করুন।

আপনার নিজস্ব ডেটা সোর্স তৈরি করুন

আপনি যদি কাস্টম লোকাল ডেটা সলিউশন ব্যবহার করেন অথবা নেটওয়ার্ক থেকে সরাসরি ডেটা লোড করেন, তাহলে DataSource সাবক্লাসের মধ্যে কোনও একটি প্রয়োগ করতে পারবেন। নিম্নলিখিত কোড স্নিপেট এমন একটি ডেটা সোর্স দেখায় যা প্রদত্ত কনসার্টের শুরুর সময় অনুযায়ী কী করা হয়েছে:

Kotlin

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 অবজেক্টে লোড করতে পারবেন। নিচের কোড স্নিপেট থেকে জানা যায় যে পূর্ববর্তী কোড স্নিপেটে সংজ্ঞায়িত কাস্টম ডেটা সোর্সের নতুন ইনস্ট্যান্স কীভাবে তৈরি করতে হয়:

Kotlin

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 অবজেক্ট তৈরি করেন, তখন কন্টেন্ট আপডেট কীভাবে কাজ করে তা বিবেচনা করুন। আপনি যদি সরাসরি Room ডেটাবেস থেকে ডেটা লোড করেন, তাহলে আপডেটগুলি আপনার অ্যাপের UI-তে অটোমেটিক পুশ হয়ে যায়।

পেজড নেটওয়ার্ক API ব্যবহার করার সময়, সাধারণত ব্যবহারকারীর ইন্টার‍্যাকশন, যেমন "রিফ্রেশ করতে সোয়াইপ করুন," আপনার সবচেয়ে সম্প্রতি ব্যবহার করা DataSource বাতিল করার সিগন্যাল হিসেবে কাজ করে। তারপর আপনি সেই ডেটা সোর্সের একটি নতুন ইনস্ট্যান্সের জন্য অনুরোধ করেন। নিম্নলিখিত কোড স্নিপেট এই আচরণ প্রদর্শন করে:

Kotlin

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-এর মাধ্যমে লোড করা আইটেমের ক্ষেত্রে পেজিং লাইব্রেরি আইটেম-ভিত্তিক ও পৃষ্ঠা-ভিত্তিক ট্রান্সফর্মেশন সাপোর্ট করে।

নিম্নলিখিত কোড স্নিপেটে, কনসার্টের নাম এবং কনসার্টের তারিখের একটি কম্বিনেশন একটি স্ট্রিংয়ে ম্যাপ করা হয়েছে যাতে নাম এবং তারিখ উভয়ই রয়েছে:

Kotlin

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();
    }
}

আইটেম লোড হওয়ার পরে আপনি যদি সেটি র‍্যাপ, কনভার্ট বা প্রস্তুত করতে চান, তাহলে এটি কাজে লাগতে পারে। এই কাজ ফেচ এক্সিকিউটরে করা হয় বলে, আপনি ডিস্ক থেকে পড়া বা আলাদা ডেটাবেসে কোয়েরি করার মতো সম্ভাব্য ব্যয়বহুল কাজ করতে পারবেন।

মতামত জানান

এইসব রিসোর্সের মাধ্যমে আপনার মতামত ও আইডিয়া আমাদের সাথে শেয়ার করুন:

ইস্যু ট্র্যাকার
সমস্যার ব্যাপারে অভিযোগ জানান যাতে আমরা বাগ ঠিক করতে পারি।

অতিরিক্ত রিসোর্স

পেজিং লাইব্রেরি সম্পর্কে আরও জানতে, নিম্নলিখিত রিসোর্স পরামর্শ করুন।

নমুনা

কোডল্যাবস

ভিডিও