diff --git a/analytics/app/src/main/java/com/google/firebase/quickstart/analytics/java/MainActivity.java b/analytics/app/src/main/java/com/google/firebase/quickstart/analytics/java/MainActivity.java index 6b8bceb5bf..b9e52f7ea6 100644 --- a/analytics/app/src/main/java/com/google/firebase/quickstart/analytics/java/MainActivity.java +++ b/analytics/app/src/main/java/com/google/firebase/quickstart/analytics/java/MainActivity.java @@ -21,26 +21,27 @@ package com.google.firebase.quickstart.analytics.java; -import android.annotation.SuppressLint; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; - +import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentPagerAdapter; +import androidx.lifecycle.Lifecycle; import androidx.preference.PreferenceManager; import androidx.viewpager.widget.ViewPager; - +import androidx.viewpager2.adapter.FragmentStateAdapter; +import androidx.viewpager2.widget.ViewPager2; +import com.google.android.material.tabs.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; import com.google.firebase.analytics.FirebaseAnalytics; import com.google.firebase.quickstart.analytics.R; import com.google.firebase.quickstart.analytics.databinding.ActivityMainBinding; - import java.util.Locale; /** @@ -48,7 +49,6 @@ * are shown via {@link ImageFragment}. */ public class MainActivity extends AppCompatActivity { - private static final String TAG = "MainActivity"; private static final String KEY_FAVORITE_FOOD = "favorite_food"; @@ -63,14 +63,14 @@ public class MainActivity extends AppCompatActivity { /** * The {@link androidx.viewpager.widget.PagerAdapter} that will provide fragments for each image. - * This uses a {@link FragmentPagerAdapter}, which keeps every loaded fragment in memory. + * This uses a {@link FragmentStateAdapter}, which keeps every loaded fragment in memory. */ private ImagePagerAdapter mImagePagerAdapter; /** * The {@link ViewPager} that will host the patterns. */ - private ViewPager mViewPager; + private ViewPager2 mViewPager; /** * The {@code FirebaseAnalytics} used to record screen views. @@ -104,28 +104,31 @@ protected void onCreate(Bundle savedInstanceState) { setUserFavoriteFood(userFavoriteFood); } - // Create the adapter that will return a fragment for each image. - mImagePagerAdapter = new ImagePagerAdapter(getSupportFragmentManager(), IMAGE_INFOS); + mImagePagerAdapter = new ImagePagerAdapter(getSupportFragmentManager(), IMAGE_INFOS, getLifecycle()); // Set up the ViewPager with the pattern adapter. mViewPager = binding.viewPager; mViewPager.setAdapter(mImagePagerAdapter); - // Workaround for AppCompat issue not showing ViewPager titles - ViewPager.LayoutParams params = (ViewPager.LayoutParams) - binding.pagerTabStrip.getLayoutParams(); - params.isDecor = true; - - // When the visible image changes, send a screen view hit. - mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { + mViewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override public void onPageSelected(int position) { + super.onPageSelected(position); recordImageView(); recordScreenView(); } }); + TabLayout tabLayout = binding.tabLayout; + + // When the visible image changes, send a screen view hit. + new TabLayoutMediator(tabLayout, mViewPager, new TabLayoutMediator.TabConfigurationStrategy() { + public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) { + tab.setText(IMAGE_INFOS[position].title); + } + }).attach(); + // Send initial screen screen view hit. recordImageView(); } @@ -235,7 +238,7 @@ private String getCurrentImageId() { /** * Record a screen view for the visible {@link ImageFragment} displayed - * inside {@link FragmentPagerAdapter}. + * inside {@link FragmentStateAdapter}. */ private void recordImageView() { String id = getCurrentImageId(); @@ -267,31 +270,18 @@ private void recordScreenView() { } /** - * A {@link FragmentPagerAdapter} that returns a fragment corresponding to + * A {@link FragmentStateAdapter} that returns a fragment corresponding to * one of the sections/tabs/pages. */ - public class ImagePagerAdapter extends FragmentPagerAdapter { + public class ImagePagerAdapter extends FragmentStateAdapter { private final ImageInfo[] infos; - @SuppressLint("WrongConstant") - public ImagePagerAdapter(FragmentManager fm, ImageInfo[] infos) { - super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); + public ImagePagerAdapter(FragmentManager fm, ImageInfo[] infos, Lifecycle lifecyle) { + super(fm, lifecyle); this.infos = infos; } - @Override - public Fragment getItem(int position) { - ImageInfo info = infos[position]; - return ImageFragment.newInstance(info.image); - } - - @Override - public int getCount() { - return infos.length; - } - - @Override public CharSequence getPageTitle(int position) { if (position < 0 || position >= infos.length) { return null; @@ -300,5 +290,17 @@ public CharSequence getPageTitle(int position) { ImageInfo info = infos[position]; return getString(info.title).toUpperCase(l); } + + @NonNull + @Override + public Fragment createFragment(int position) { + ImageInfo info = infos[position]; + return ImageFragment.newInstance(info.image); + } + + @Override + public int getItemCount() { + return infos.length; + } } } diff --git a/analytics/app/src/main/java/com/google/firebase/quickstart/analytics/kotlin/MainActivity.kt b/analytics/app/src/main/java/com/google/firebase/quickstart/analytics/kotlin/MainActivity.kt index f2c4dc4fd9..003fd62fc5 100644 --- a/analytics/app/src/main/java/com/google/firebase/quickstart/analytics/kotlin/MainActivity.kt +++ b/analytics/app/src/main/java/com/google/firebase/quickstart/analytics/kotlin/MainActivity.kt @@ -10,17 +10,23 @@ import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager -import androidx.fragment.app.FragmentPagerAdapter +import androidx.lifecycle.Lifecycle import androidx.preference.PreferenceManager -import androidx.viewpager.widget.ViewPager +import androidx.viewpager2.adapter.FragmentStateAdapter +import androidx.viewpager2.widget.ViewPager2 +import com.google.android.material.tabs.TabLayout +import com.google.android.material.tabs.TabLayoutMediator import com.google.firebase.analytics.FirebaseAnalytics import com.google.firebase.analytics.ktx.analytics import com.google.firebase.analytics.ktx.logEvent import com.google.firebase.ktx.Firebase import com.google.firebase.quickstart.analytics.R import com.google.firebase.quickstart.analytics.databinding.ActivityMainBinding +import com.google.firebase.quickstart.analytics.java.MainActivity +import com.google.firebase.quickstart.analytics.kotlin.MainActivity.Companion.IMAGE_INFOS import java.util.Locale + /** * Activity which displays numerous background images that may be viewed. These background images * are shown via {@link ImageFragment}. @@ -41,8 +47,8 @@ class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding /** - * The [androidx.viewpager.widget.PagerAdapter] that will provide fragments for each image. - * This uses a [FragmentPagerAdapter], which keeps every loaded fragment in memory. + * The [androidx.viewpager2.widget.PagerAdapter] that will provide fragments for each image. + * This uses a [FragmentStateAdapter], which keeps every loaded fragment in memory. */ private lateinit var imagePagerAdapter: ImagePagerAdapter @@ -73,22 +79,24 @@ class MainActivity : AppCompatActivity() { } // Create the adapter that will return a fragment for each image. - imagePagerAdapter = ImagePagerAdapter(supportFragmentManager, IMAGE_INFOS) + imagePagerAdapter = ImagePagerAdapter(supportFragmentManager, IMAGE_INFOS, lifecycle) // Set up the ViewPager with the pattern adapter. binding.viewPager.adapter = imagePagerAdapter - // Workaround for AppCompat issue not showing ViewPager titles - val params = binding.pagerTabStrip.layoutParams as ViewPager.LayoutParams - params.isDecor = true - - // When the visible image changes, send a screen view hit. - binding.viewPager.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() { + val pageChangedCallback = object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { recordImageView() recordScreenView() } - }) + } + + binding.viewPager.registerOnPageChangeCallback(pageChangedCallback) + + val tabLayout: TabLayout = binding.tabLayout + TabLayoutMediator(tabLayout, binding.viewPager) { tab, position -> + tab.setText(IMAGE_INFOS[position].title) + }.attach() // Send initial screen screen view hit. recordImageView() @@ -192,7 +200,7 @@ class MainActivity : AppCompatActivity() { /** * Record a screen view for the visible [ImageFragment] displayed - * inside [FragmentPagerAdapter]. + * inside [FragmentStateAdapter]. */ private fun recordImageView() { val id = getCurrentImageId() @@ -224,29 +232,29 @@ class MainActivity : AppCompatActivity() { } /** - * A [FragmentPagerAdapter] that returns a fragment corresponding to + * A [FragmentStateAdapter] that returns a fragment corresponding to * one of the sections/tabs/pages. */ - @SuppressLint("WrongConstant") inner class ImagePagerAdapter( fm: FragmentManager, - private val infos: Array - ) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { + private val infos: Array, + lifecyle: Lifecycle + ) : FragmentStateAdapter(fm, lifecyle) { - override fun getItem(position: Int): Fragment { - val info = infos[position] - return ImageFragment.newInstance(info.image) - } - - override fun getCount() = infos.size - - override fun getPageTitle(position: Int): CharSequence? { + fun getPageTitle(position: Int): CharSequence? { if (position < 0 || position >= infos.size) { return null } val l = Locale.getDefault() val info = infos[position] - return getString(info.title).toUpperCase(l) + return getString(info.title).uppercase(l) + } + + override fun getItemCount(): Int = infos.size + + override fun createFragment(position: Int): Fragment { + val info = infos[position] + return ImageFragment.newInstance(info.image) } } } diff --git a/analytics/app/src/main/res/layout/activity_main.xml b/analytics/app/src/main/res/layout/activity_main.xml index 25ad2823e5..1afa9cd51f 100644 --- a/analytics/app/src/main/res/layout/activity_main.xml +++ b/analytics/app/src/main/res/layout/activity_main.xml @@ -12,17 +12,26 @@ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> - + android:layout_height="match_parent"> - + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> - + +