AI Assistant Multiple Documents: ViewPager
Example demonstrating AI chat for multiple documents analysis and interaction using ViewPager. You must also run the AI Assistant demo server on your Machine.
/* * Copyright © 2025-2026 PSPDFKit GmbH. All rights reserved. * * The PSPDFKit Sample applications are licensed with a modified BSD license. * Please see License for details. This notice may not be removed from this file. */
package com.pspdfkit.catalog.examples.kotlin
import android.content.Contextimport android.content.Intentimport android.graphics.RectFimport android.os.Bundleimport androidx.appcompat.app.AppCompatActivityimport androidx.appcompat.widget.Toolbarimport androidx.fragment.app.Fragmentimport androidx.viewpager2.adapter.FragmentStateAdapterimport androidx.viewpager2.widget.ViewPager2import com.google.android.material.tabs.TabLayoutMediatorimport com.pspdfkit.ai.showAiAssistantimport com.pspdfkit.catalog.Rimport com.pspdfkit.catalog.SdkExampleimport com.pspdfkit.catalog.SdkExample.Companion.WELCOME_DOCimport com.pspdfkit.catalog.examples.kotlin.AiAssistantComposeActivity.Companion.PREFERENCES_NAMEimport com.pspdfkit.catalog.examples.kotlin.AiAssistantComposeActivity.Companion.PREF_AI_IP_ADDRESSimport com.pspdfkit.catalog.examples.kotlin.AiAssistantViewPagerActivity.Companion.EXTRA_CONFIGURATIONimport com.pspdfkit.catalog.utils.JwtGeneratorimport com.pspdfkit.configuration.PdfConfigurationimport com.pspdfkit.configuration.activity.PdfActivityConfigurationimport com.pspdfkit.document.providers.AssetDataProviderimport com.pspdfkit.document.providers.getDataProviderFromDocumentSourceimport com.pspdfkit.ui.DocumentDescriptorimport com.pspdfkit.ui.PdfFragmentimport com.pspdfkit.utils.getSupportParcelableExtraimport io.nutrient.domain.ai.AiAssistantimport io.nutrient.domain.ai.AiAssistantProvider
/** * Shows how to implement AI Assistant chat supporting multiple documents analysis and interaction inside a ViewPager. */class AiAssistantViewPagerExample(context: Context) : SdkExample(context, R.string.aiAssistantViewPagerExampleTitle, R.string.aiAssistantViewPagerExampleDescription) {
override fun launchExample(context: Context, configuration: PdfActivityConfiguration.Builder) { val intent = Intent(context, AiAssistantViewPagerActivity::class.java) configuration.setAiAssistantEnabled(true) intent.putExtra( EXTRA_CONFIGURATION, configuration.build().configuration )
context.startActivity(intent) }}
class AiAssistantViewPagerActivity : AppCompatActivity(), AiAssistantProvider {
private lateinit var pager: ViewPager2 private lateinit var fragmentAdapter: ViewPagerPdfFragmentAdapter private var selectedPage = 0 private val sessionId = AiAssistantViewPagerActivity::class.java.simpleName var ipAddressValue = ""
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_view_pager_ai_assistant) findViewById<Toolbar>(R.id.main_toolbar).let { it.setOnMenuItemClickListener { _ -> showAiAssistant(this@AiAssistantViewPagerActivity) false } } val preferences = getSharedPreferences(PREFERENCES_NAME, MODE_PRIVATE) ipAddressValue = preferences.getString(PREF_AI_IP_ADDRESS, "") ?: "" fragmentAdapter = ViewPagerPdfFragmentAdapter(this@AiAssistantViewPagerActivity, documentDescriptors) pager = findViewById<ViewPager2>(R.id.view_pager).apply { this.adapter = fragmentAdapter isUserInputEnabled = false registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { super.onPageSelected(position) selectedPage = position // Save the selected page. }
override fun onPageScrollStateChanged(state: Int) { super.onPageScrollStateChanged(state) // Refresh the fragment when the user stops scrolling. if (state == 0) supportFragmentManager.findFragmentByTag("f$selectedPage")?.let { if (it is PdfFragment) it.refreshPages() } } }) }
TabLayoutMediator(findViewById(R.id.tab_layout), pager) { tab, position -> tab.text = "Tab ${position + 1}" }.attach() }
companion object { val assetFiles = listOf(WELCOME_DOC, "Scientific-paper.pdf", "Teacher.pdf", "The-Cosmic-Context-for-Life.pdf") internal const val EXTRA_CONFIGURATION = "Nutrient.AIAssistantViewPagerActivity.configuration" } var assistant: AiAssistant? = null
override fun getAiAssistant(): AiAssistant { return assistant ?: initialiseAiAssistant().also { assistant = it } }
val documentDescriptors = assetFiles.map { DocumentDescriptor.fromDataProviders(listOf(AssetDataProvider(it)), listOf(), listOf()) }
fun initialiseAiAssistant(): AiAssistant { return com.pspdfkit.ai.createAiAssistant( context = this, documentsDescriptors = documentDescriptors, serverUrl = "http://$ipAddressValue:4000", sessionId = sessionId, jwtToken = { documentIds -> JwtGenerator.generateJwtToken( this@AiAssistantViewPagerActivity, claims = mapOf( "document_ids" to documentIds, "session_ids" to listOf(sessionId), "request_limit" to mapOf( "requests" to 160, "time_period_s" to 1000 * 60 * 10 ) ) ) } ) }
@OptIn(ExperimentalStdlibApi::class) override fun navigateTo( documentRect: List<RectF>, pageIndex: Int, documentIndex: Int ) { val fragment = fragmentAdapter.fragments[documentIndex] pager.setCurrentItem(documentIndex, true) fragment.highlight(this@AiAssistantViewPagerActivity, documentRect, pageIndex) }}
/** Minimal [FragmentStateAdapter] to provide [PdfFragment] for each page. */class ViewPagerPdfFragmentAdapter(val activity: AiAssistantViewPagerActivity, descriptors: List<DocumentDescriptor>) : FragmentStateAdapter(activity) {
val configuration = activity.intent.getSupportParcelableExtra(EXTRA_CONFIGURATION, PdfConfiguration::class.java) ?: throw IllegalStateException("Activity Intent was missing configuration extra!")
override fun getItemCount(): Int = 4 val fragments = descriptors.map { val dataProvider = it.documentSource.getDataProviderFromDocumentSource() PdfFragment.newInstance(dataProvider, null, configuration) }
override fun createFragment(position: Int): Fragment { return fragments[position] }}This code sample is an example that illustrates how to use our SDK. Please adapt it to your specific use case.