From 6387a9cb0017c945d5aa22fb0094eb4af9946b9d Mon Sep 17 00:00:00 2001 From: Sungjun Date: Wed, 26 Jan 2022 17:29:16 +0900 Subject: [PATCH] [Hotfix] jitpack build error (#51) * Fix jitpack jdk version errors * Add java11 installment to jitpack.yml * Replace deprecated kotlin-android-extensions with view binding * Fix simpledemo app * Fix demo app * Fix an ui bug * Remove warnings * Fix a lint error * Add jcenter() at the last of the repository list * Upgrade libraries * Restore a missing library * Fix errors * Fix errors * Fix errors * Fix errors * Fix errors * Add MavenPublication * Change the location of MavenPublication * enable org.gradle.parallel=true for faster build --- app/build.gradle | 38 +++-- .../pixleeandroidsdk/ui/IndexFragment.kt | 41 +++-- .../ui/analytics/KtxAnalyticsFragment.kt | 152 +++++++++--------- .../ui/gallery/GalleryFragment.kt | 113 ++++++------- .../ui/gallery/KtxGalleryGridFragment.kt | 118 +++++++------- .../ui/gallery/KtxGalleryListFragment.kt | 132 +++++++-------- .../ui/uioptions/ProductViewFragment.kt | 34 ++-- .../ui/widgets/HotspotsActivity.kt | 13 +- .../ui/widgets/PXLPhotoViewFragment.kt | 67 ++++---- .../PXLPhotoViewInRecyclerViewFragment.kt | 26 +-- .../ui/widgets/ViewerActivity.kt | 18 ++- .../main/res/layout/fragment_analytics.xml | 2 +- app/src/main/res/layout/fragment_gallery.xml | 2 +- .../res/layout/fragment_ktx_gallery_grid.xml | 2 +- .../res/layout/fragment_ktx_gallery_list.xml | 2 +- app/src/main/res/layout/module_search.xml | 4 +- build.gradle | 24 +-- gradle.properties | 7 +- jitpack.yml | 6 + pixleesdk/build.gradle | 51 ++++-- .../com/pixlee/pixleesdk/data/PXLProduct.java | 2 +- .../network/annotation/FieldBigDecimal.java | 2 +- .../pixleesdk/ui/adapter/PXLPhotoAdapter.kt | 14 +- .../pixleesdk/ui/adapter/ProductAdapter.kt | 9 +- .../ui/viewholder/LoadMoreViewHolder.kt | 27 ++-- .../ui/viewholder/PXLPhotoViewHolder.kt | 34 ++-- .../ui/viewholder/ProductViewHolder.kt | 48 +++--- .../ui/viewholder/TextHeaderViewHolder.kt | 29 ++-- .../ui/widgets/PXLPhotoProductView.kt | 70 ++++---- .../com/pixlee/pixleesdk/util/ImageViewExt.kt | 3 - simpleapp/build.gradle | 33 ++-- .../pixleeandroidsdk/DynamicDemoActivity.kt | 126 ++++++++------- .../pixlee/pixleeandroidsdk/IndexActivity.kt | 18 ++- .../pixleeandroidsdk/SimpleGridActivity.kt | 28 ++-- .../pixleeandroidsdk/SimpleListActivity.kt | 27 ++-- .../pixlee/pixleeandroidsdk/ViewerActivity.kt | 17 +- .../res/layout/activity_dynamic_photos.xml | 5 +- .../src/main/res/layout/module_search.xml | 10 +- 38 files changed, 747 insertions(+), 607 deletions(-) create mode 100644 jitpack.yml diff --git a/app/build.gradle b/app/build.gradle index c016135e..70dcd464 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,15 +1,15 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' -androidExtensions { - experimental = true +plugins { + id 'com.android.application' + id 'kotlin-android' + id 'kotlin-parcelize' } + android { - compileSdkVersion 31 + compileSdkVersion COMPILE_SDK_VERSION as int defaultConfig { applicationId "com.pixlee.pixleeandroidsdk" - minSdkVersion 21 - targetSdkVersion 30 + minSdkVersion MIN_SDK_VERSION as int + targetSdkVersion TARGET_SDK_VERSION as int versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -18,8 +18,8 @@ android { buildConfigField "String", "PIXLEE_ALBUM_ID", "\"" + PIXLEE_ALBUM_ID + "\"" buildConfigField "String", "PIXLEE_SKU", "\"" + PIXLEE_SKU + "\"" } - viewBinding { - enabled = true + buildFeatures { + viewBinding true } buildTypes { release { @@ -29,8 +29,8 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } testOptions { @@ -46,18 +46,22 @@ android { } } } + packagingOptions { + exclude 'META-INF/AL2.0' + exclude 'META-INF/LGPL2.1' + } } tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { kotlinOptions { - jvmTarget = "1.8" + jvmTarget = "11" } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - testImplementation 'junit:junit:4.13' + testImplementation "junit:junit:$junit" /** * testing @@ -68,8 +72,8 @@ dependencies { //testImplementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.9.8" testImplementation "com.squareup.okhttp3:mockwebserver:$okhttp3" - androidTestImplementation 'androidx.test:runner:1.3.0' - androidTestImplementation 'androidx.test:rules:1.3.0' + androidTestImplementation "androidx.test:runner:$androidxRunner" + androidTestImplementation "androidx.test:rules:$androidXrules" androidTestImplementation 'androidx.test.ext:junit:' + rootProject.extJUnitVersion androidTestImplementation "androidx.test.ext:junit-ktx:" + rootProject.extJUnitVersion @@ -99,7 +103,7 @@ dependencies { implementation "com.github.bumptech.glide:okhttp3-integration:$glide" annotationProcessor "com.github.bumptech.glide:compiler:$glide" - implementation 'androidx.recyclerview:recyclerview:1.1.0' + implementation "androidx.recyclerview:recyclerview:$recyclerview" implementation "com.squareup.retrofit2:converter-gson:$retrofit2" implementation project(':pixleesdk') diff --git a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/IndexFragment.kt b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/IndexFragment.kt index 9128ce57..8568d992 100644 --- a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/IndexFragment.kt +++ b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/IndexFragment.kt @@ -8,6 +8,7 @@ import com.pixlee.pixleeandroidsdk.MainActivity import com.pixlee.pixleeandroidsdk.R import com.pixlee.pixleeandroidsdk.data.LocalDataSource import com.pixlee.pixleeandroidsdk.data.LocalRepository.Companion.getInstance +import com.pixlee.pixleeandroidsdk.databinding.FragmentIndexBinding import com.pixlee.pixleeandroidsdk.ui.analytics.AnalyticsFragment import com.pixlee.pixleeandroidsdk.ui.analytics.KtxAnalyticsFragment import com.pixlee.pixleeandroidsdk.ui.gallery.GalleryFragment @@ -16,7 +17,6 @@ import com.pixlee.pixleeandroidsdk.ui.gallery.KtxGalleryListFragment import com.pixlee.pixleeandroidsdk.ui.uioptions.ProductViewFragment import com.pixlee.pixleeandroidsdk.ui.uploader.ImageUploaderFragment import com.pixlee.pixleeandroidsdk.ui.widgets.HotspotsActivity -import kotlinx.android.synthetic.main.fragment_index.* /** * This is an index page of the app. @@ -28,8 +28,21 @@ class IndexFragment : BaseFragment() { return R.string.app_name } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.fragment_index, container, false) + private var _binding: FragmentIndexBinding? = null + private val binding get() = _binding!! + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + _binding = FragmentIndexBinding.inflate(inflater, container, false) + return binding.root } private val localDataSource: LocalDataSource by lazy { @@ -44,49 +57,49 @@ class IndexFragment : BaseFragment() { } fun initKtxButtons() { - btKtxAlbumList.setOnClickListener { + binding.btKtxAlbumList.setOnClickListener { addFragmentToActivity(KtxGalleryListFragment()) } - btKtxAlbumGrid.setOnClickListener { + binding.btKtxAlbumGrid.setOnClickListener { addFragmentToActivity(KtxGalleryGridFragment()) } - btKtxAnalytics.setOnClickListener { + binding.btKtxAnalytics.setOnClickListener { addFragmentToActivity(KtxAnalyticsFragment()) } - btnProductView.setOnClickListener { + binding.btnProductView.setOnClickListener { addFragmentToActivity(ProductViewFragment()) } - btnHotspots.setOnClickListener { + binding.btnHotspots.setOnClickListener { context?.let { HotspotsActivity.launch(it) } } } fun initJavaButtons() { - btAlbum.setOnClickListener { + binding.btAlbum.setOnClickListener { addFragmentToActivity(GalleryFragment.getInstance(false)) } - btImageUploader.setOnClickListener { + binding.btImageUploader.setOnClickListener { addFragmentToActivity(ImageUploaderFragment()) } - btAnalytics.setOnClickListener { + binding.btAnalytics.setOnClickListener { addFragmentToActivity(AnalyticsFragment()) } } fun initWidgetButtons() { localDataSource.getConfig().also { - switchDarkMode.isChecked = it.isDarkMode + binding.switchDarkMode.isChecked = it.isDarkMode } - switchDarkMode.setOnClickListener { + binding.switchDarkMode.setOnClickListener { (localDataSource.getConfig()).also { - it.isDarkMode = switchDarkMode.isChecked + it.isDarkMode = binding.switchDarkMode.isChecked localDataSource.setConfig(it) (activity as MainActivity).setConfig(it) } diff --git a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/analytics/KtxAnalyticsFragment.kt b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/analytics/KtxAnalyticsFragment.kt index e21d604c..345ca9ae 100644 --- a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/analytics/KtxAnalyticsFragment.kt +++ b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/analytics/KtxAnalyticsFragment.kt @@ -12,6 +12,7 @@ import androidx.core.widget.NestedScrollView import com.google.android.material.radiobutton.MaterialRadioButton import com.pixlee.pixleeandroidsdk.BuildConfig import com.pixlee.pixleeandroidsdk.R +import com.pixlee.pixleeandroidsdk.databinding.FragmentAnalyticsBinding import com.pixlee.pixleeandroidsdk.ui.BaseFragment import com.pixlee.pixleeandroidsdk.ui.BaseViewModel import com.pixlee.pixleesdk.client.PXLClient @@ -25,8 +26,6 @@ import com.pixlee.pixleesdk.enums.PXLContentType import com.pixlee.pixleesdk.enums.PXLWidgetType import com.pixlee.pixleesdk.ui.widgets.ImageScaleType import com.pixlee.pixleesdk.util.EventObserver -import kotlinx.android.synthetic.main.fragment_analytics.* -import kotlinx.android.synthetic.main.module_search.* import java.util.* /** @@ -39,7 +38,7 @@ class KtxAnalyticsFragment : BaseFragment() { } override fun isBackInUse(): Boolean { - return if (vWidgetBox.isShown) { + return if (binding.vWidgetBox.isShown) { closeWidget() true } else { @@ -53,8 +52,17 @@ class KtxAnalyticsFragment : BaseFragment() { KtxAnalyticsViewModel(album) } + private var _binding: FragmentAnalyticsBinding? = null + private val binding get() = _binding!! + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.fragment_analytics, container, false) + _binding = FragmentAnalyticsBinding.inflate(inflater, container, false) + return binding.root } override fun onActivityCreated(savedInstanceState: Bundle?) { @@ -72,28 +80,28 @@ class KtxAnalyticsFragment : BaseFragment() { fun initFilterClickListeners() { // set filter buttons - fabFilter.setOnClickListener { drawerLayout.openDrawer(GravityCompat.END) } - btnCloseFilter.setOnClickListener { drawerLayout.closeDrawer(GravityCompat.END) } - btnApply.setOnClickListener { - drawerLayout.closeDrawer(GravityCompat.END) + binding.fabFilter.setOnClickListener { binding.drawerLayout.openDrawer(GravityCompat.END) } + binding.moduleSearchLayout.btnCloseFilter.setOnClickListener { binding.drawerLayout.closeDrawer(GravityCompat.END) } + binding.moduleSearchLayout.btnApply.setOnClickListener { + binding.drawerLayout.closeDrawer(GravityCompat.END) loadPixleeAlbum() } } fun setViewModelListener() { viewModel.loading.observe(viewLifecycleOwner, androidx.lifecycle.Observer { - vProgress.visibility = if (it) View.VISIBLE else View.INVISIBLE - if (it) tvStatus.setText(R.string.album_loading_ing) + binding.vProgress.visibility = if (it) View.VISIBLE else View.INVISIBLE + if (it) binding.tvStatus.setText(R.string.album_loading_ing) enableAlbumButtons(!it) }) viewModel.searchResultEvent.observe(viewLifecycleOwner, EventObserver { when (it) { is BaseViewModel.Command.Data -> { it.list.firstOrNull()?.also { - pxlPhotoView.setContent(it.pxlPhoto, ImageScaleType.FIT_CENTER) + binding.pxlPhotoView.setContent(it.pxlPhoto, ImageScaleType.FIT_CENTER) } - tvStatus.setText(R.string.album_loading_complete) - tvStatus.text = if (it.isFirstPage) "First Load" else "Loaded More..." + binding.tvStatus.setText(R.string.album_loading_complete) + binding.tvStatus.text = if (it.isFirstPage) "First Load" else "Loaded More..." if (it.isFirstPage) { // fire analytics after you received more pages viewModel.loadMore() @@ -102,7 +110,7 @@ class KtxAnalyticsFragment : BaseFragment() { } is BaseViewModel.Command.Error -> { it.message?.also { - tvStatus.text = getString(R.string.album_loading_failed, it) + binding.tvStatus.text = getString(R.string.album_loading_failed, it) showToast(getString(R.string.album_loading_failed, it)) } @@ -115,9 +123,9 @@ class KtxAnalyticsFragment : BaseFragment() { context?.also { var searchId: PXLKtxBaseAlbum.SearchId? = null // initiate album - for (i in 0 until radioGroupAlbum.childCount) { - val rb = radioGroupAlbum.getChildAt(i) as MaterialRadioButton - if (radioGroupAlbum.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupAlbum.childCount) { + val rb = binding.moduleSearchLayout.radioGroupAlbum.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupAlbum.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == getString(R.string.radio_album)) { searchId = PXLKtxBaseAlbum.SearchId.Album(BuildConfig.PIXLEE_ALBUM_ID) @@ -155,34 +163,34 @@ class KtxAnalyticsFragment : BaseFragment() { } private fun setClickListeners() { - btWidgetExample.setOnClickListener(View.OnClickListener { openWidget() }) - btOpenWidget.setOnClickListener(View.OnClickListener { + binding.btWidgetExample.setOnClickListener(View.OnClickListener { openWidget() }) + binding.btOpenWidget.setOnClickListener(View.OnClickListener { showMessage("openedWidget(..)") viewModel.openedWidget(PXLWidgetType.photowall) // Alternative: album.openedWidget(""); }) - btWidgetVisible.setOnClickListener(View.OnClickListener { + binding.btWidgetVisible.setOnClickListener(View.OnClickListener { showMessage("widgetVisible(..)") viewModel.widgetVisible(PXLWidgetType.photowall) // Alternative: album.widgetVisible(""); }) - btLoadMore.setOnClickListener(View.OnClickListener { + binding.btLoadMore.setOnClickListener(View.OnClickListener { viewModel.getNextPage() }) - btOpenedLightbox.setOnClickListener(View.OnClickListener { + binding.btOpenedLightbox.setOnClickListener(View.OnClickListener { showMessage("openedLightbox()") viewModel.openedLightbox() }) - btActionClicked.setOnClickListener(View.OnClickListener { + binding.btActionClicked.setOnClickListener(View.OnClickListener { showMessage("actionClicked()") viewModel.actionClicked("") }) - btAddToCart.setOnClickListener(View.OnClickListener { + binding.btAddToCart.setOnClickListener(View.OnClickListener { showMessage("addToCart()") viewModel.addToCart(BuildConfig.PIXLEE_SKU, "12000", 3) // Alternative: viewModel.addToCart("13000",2, "AUD"); }) - btConversion.setOnClickListener(View.OnClickListener { + binding.btConversion.setOnClickListener(View.OnClickListener { showMessage("conversion()") val cartContents: ArrayList> = ArrayList() val cart1: HashMap = HashMap() @@ -199,16 +207,16 @@ class KtxAnalyticsFragment : BaseFragment() { fun openWidget() { viewModel.openedWidget(PXLWidgetType.photowall) - vWidgetBox.setVisibility(View.VISIBLE) + binding.vWidgetBox.setVisibility(View.VISIBLE) val openedWidgetStatus = "openedWidget success" addWidgetStaus(true, openedWidgetStatus) showToast("$openedWidgetStatus!!\n\nScroll down to fire Widget Visible") widgetVisible = false val scrollBounds = Rect() - scrollWidget.getHitRect(scrollBounds) - scrollWidget.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY -> - if (pxlPhotoView != null) { - if (pxlPhotoView.getLocalVisibleRect(scrollBounds)) { + binding.scrollWidget.getHitRect(scrollBounds) + binding.scrollWidget.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY -> + if (binding.pxlPhotoView != null) { + if (binding.pxlPhotoView.getLocalVisibleRect(scrollBounds)) { if (!widgetVisible) { viewModel.widgetVisible(PXLWidgetType.photowall) val visibleWidgetStatus = "visibleWidget success" @@ -216,8 +224,8 @@ class KtxAnalyticsFragment : BaseFragment() { showToast("$visibleWidgetStatus!!") widgetVisible = true } - if (!pxlPhotoView.getLocalVisibleRect(scrollBounds) - || scrollBounds.height() < pxlPhotoView.height) { + if (!binding.pxlPhotoView.getLocalVisibleRect(scrollBounds) + || scrollBounds.height() < binding.pxlPhotoView.height) { Log.i("PXLAnalytics", "btn appears partially") } else { Log.i("PXLAnalytics", "btn appears FULLY!!!") @@ -228,20 +236,20 @@ class KtxAnalyticsFragment : BaseFragment() { } fun closeWidget() { - scrollWidget.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY -> }) - scrollWidget.fullScroll(ScrollView.FOCUS_UP) - vWidgetBox.setVisibility(View.GONE) + binding.scrollWidget.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY -> }) + binding.scrollWidget.fullScroll(ScrollView.FOCUS_UP) + binding.vWidgetBox.setVisibility(View.GONE) } fun addWidgetStaus(clearHistory: Boolean, message: String) { if (widgetStatus == null || clearHistory) widgetStatus = StringBuilder() widgetStatus!!.append("- $message").append("\n") - tvWidgetStatus.setText(widgetStatus.toString()) + binding.tvWidgetStatus.setText(widgetStatus.toString()) } fun setScrollView() { - tvMsg1.setText(getListMsg("Before Widget Visible", false)) - tvMsg2.setText(getListMsg("After Widget Visible", true)) + binding.tvMsg1.setText(getListMsg("Before Widget Visible", false)) + binding.tvMsg2.setText(getListMsg("After Widget Visible", true)) } fun getListMsg(text: String, isASC: Boolean): String { @@ -260,25 +268,25 @@ class KtxAnalyticsFragment : BaseFragment() { private fun enableAlbumButtons(enabled: Boolean) { // This conditional means that you can use openWidget() and widgetVisible() on PXLPdpAlbum after receiving album data by firing loadNextPageOfPhotos() is successfully done. - btOpenWidget.isEnabled = enabled - btWidgetVisible.isEnabled = enabled - btWidgetExample.isEnabled = enabled + binding.btOpenWidget.isEnabled = enabled + binding.btWidgetVisible.isEnabled = enabled + binding.btWidgetExample.isEnabled = enabled - btLoadMore.isEnabled = enabled - btOpenedLightbox.isEnabled = enabled - btActionClicked.isEnabled = enabled + binding.btLoadMore.isEnabled = enabled + binding.btOpenedLightbox.isEnabled = enabled + binding.btActionClicked.isEnabled = enabled } private fun showMessage(methodName: String) { val message = getString(R.string.xxx_is_called, methodName) - tvStatus.setText(message) + binding.tvStatus.setText(message) showToast(message) } fun readPerPage(): Int { // Set textViewPerPage filter if text is not empty - val minTwitterFollowers = textViewPerPage.text.toString() + val minTwitterFollowers = binding.moduleSearchLayout.textViewPerPage.text.toString() return if (!minTwitterFollowers.isEmpty()) { Integer.valueOf(minTwitterFollowers) } else 20 @@ -287,7 +295,7 @@ class KtxAnalyticsFragment : BaseFragment() { } fun readRegionIdFromUI(): Int?{ - val data = textViewRegionId.text.toString() + val data = binding.moduleSearchLayout.textViewRegionId.text.toString() return if (data.isNotEmpty()) { Integer.valueOf(data) } else null @@ -296,9 +304,9 @@ class KtxAnalyticsFragment : BaseFragment() { fun readSortOptionsFromUI(): PXLAlbumSortOptions { val sortOptions = PXLAlbumSortOptions() // Set sortType filter if a radio button is selected - for (i in 0 until radioGroupSortType.childCount) { - val rb = radioGroupSortType.getChildAt(i) as MaterialRadioButton - if (radioGroupSortType.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupSortType.childCount) { + val rb = binding.moduleSearchLayout.radioGroupSortType.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupSortType.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == PXLAlbumSortType.RECENCY.value) sortOptions.sortType = PXLAlbumSortType.RECENCY else if (text == PXLAlbumSortType.APPROVED_TIME.value) sortOptions.sortType = PXLAlbumSortType.APPROVED_TIME @@ -312,8 +320,8 @@ class KtxAnalyticsFragment : BaseFragment() { } // Set sorting direction - if (radioGroupSortDirection.checkedRadioButtonId == radioGroupSortDirectionASC.id) sortOptions.descending = false - else if (radioGroupSortDirection.checkedRadioButtonId == radioGroupSortDirectionDESC.id) sortOptions.descending = true + if (binding.moduleSearchLayout.radioGroupSortDirection.checkedRadioButtonId == binding.moduleSearchLayout.radioGroupSortDirectionASC.id) sortOptions.descending = false + else if (binding.moduleSearchLayout.radioGroupSortDirection.checkedRadioButtonId == binding.moduleSearchLayout.radioGroupSortDirectionDESC.id) sortOptions.descending = true return sortOptions } @@ -321,21 +329,21 @@ class KtxAnalyticsFragment : BaseFragment() { val filterOptions = PXLAlbumFilterOptions() // Set minTwitterFollowers filter if text is not empty - val minTwitterFollowers = textViewMinTwitterFollowers.text.toString() + val minTwitterFollowers = binding.moduleSearchLayout.textViewMinTwitterFollowers.text.toString() if (!minTwitterFollowers.isEmpty()) { filterOptions.minTwitterFollowers = Integer.valueOf(minTwitterFollowers) } // Set minInstagramFollowers filter if text is not empty - val minInstagramFollowers = textViewMinInstagramFollowers.text.toString() + val minInstagramFollowers = binding.moduleSearchLayout.textViewMinInstagramFollowers.text.toString() if (!minInstagramFollowers.isEmpty()) { filterOptions.minInstagramFollowers = Integer.valueOf(minInstagramFollowers) } // Set hasProduct filter if false or not true is set - for (i in 0 until radioGroupHasPermission.childCount) { - val rb = radioGroupHasPermission.getChildAt(i) as MaterialRadioButton - if (radioGroupHasPermission.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupHasPermission.childCount) { + val rb = binding.moduleSearchLayout.radioGroupHasPermission.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupHasPermission.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == getString(R.string.radio_false)) filterOptions.hasPermission = false else if (text == getString(R.string.radio_true)) filterOptions.hasPermission = true break @@ -343,9 +351,9 @@ class KtxAnalyticsFragment : BaseFragment() { } // Set hasProduct filter if false or not true is set - for (i in 0 until radioGroupHasProduct.childCount) { - val rb = radioGroupHasProduct.getChildAt(i) as MaterialRadioButton - if (radioGroupHasProduct.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupHasProduct.childCount) { + val rb = binding.moduleSearchLayout.radioGroupHasProduct.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupHasProduct.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == getString(R.string.radio_false)) filterOptions.hasProduct = false else if (text == getString(R.string.radio_true)) filterOptions.hasProduct = true break @@ -353,9 +361,9 @@ class KtxAnalyticsFragment : BaseFragment() { } // Set inStockOnly filter if false or not true is set - for (i in 0 until radioGroupInStockOnly.childCount) { - val rb = radioGroupInStockOnly.getChildAt(i) as MaterialRadioButton - if (radioGroupInStockOnly.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupInStockOnly.childCount) { + val rb = binding.moduleSearchLayout.radioGroupInStockOnly.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupInStockOnly.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == getString(R.string.radio_false)) filterOptions.inStockOnly = false else if (text == getString(R.string.radio_true)) filterOptions.inStockOnly = true break @@ -364,19 +372,19 @@ class KtxAnalyticsFragment : BaseFragment() { // Set contentSource filter if any of its check boxes is selected val contentSource: ArrayList = ArrayList() - if (radioGroupContentSourceInstagramFeed.isChecked) contentSource.add(PXLContentSource.INSTAGRAM_FEED) - if (radioGroupContentSourceInstagramStory.isChecked) contentSource.add(PXLContentSource.INSTAGRAM_STORY) - if (radioGroupContentSourceTwitter.isChecked) contentSource.add(PXLContentSource.TWITTER) - if (radioGroupContentSourceFacebook.isChecked) contentSource.add(PXLContentSource.FACEBOOK) - if (radioGroupContentSourceApi.isChecked) contentSource.add(PXLContentSource.API) - if (radioGroupContentSourceDesktop.isChecked) contentSource.add(PXLContentSource.DESKTOP) - if (radioGroupContentSourceEmail.isChecked) contentSource.add(PXLContentSource.EMAIL) + if (binding.moduleSearchLayout.radioGroupContentSourceInstagramFeed.isChecked) contentSource.add(PXLContentSource.INSTAGRAM_FEED) + if (binding.moduleSearchLayout.radioGroupContentSourceInstagramStory.isChecked) contentSource.add(PXLContentSource.INSTAGRAM_STORY) + if (binding.moduleSearchLayout.radioGroupContentSourceTwitter.isChecked) contentSource.add(PXLContentSource.TWITTER) + if (binding.moduleSearchLayout.radioGroupContentSourceFacebook.isChecked) contentSource.add(PXLContentSource.FACEBOOK) + if (binding.moduleSearchLayout.radioGroupContentSourceApi.isChecked) contentSource.add(PXLContentSource.API) + if (binding.moduleSearchLayout.radioGroupContentSourceDesktop.isChecked) contentSource.add(PXLContentSource.DESKTOP) + if (binding.moduleSearchLayout.radioGroupContentSourceEmail.isChecked) contentSource.add(PXLContentSource.EMAIL) if (contentSource.isNotEmpty()) filterOptions.contentSource = contentSource // Set contentType filter if any of its check boxes is selected val contentType: ArrayList = ArrayList() - if (radioGroupContentTypeImage.isChecked) contentType.add(PXLContentType.IMAGE) - if (radioGroupContentTypeVideo.isChecked) contentType.add(PXLContentType.VIDEO) + if (binding.moduleSearchLayout.radioGroupContentTypeImage.isChecked) contentType.add(PXLContentType.IMAGE) + if (binding.moduleSearchLayout.radioGroupContentTypeVideo.isChecked) contentType.add(PXLContentType.VIDEO) if (contentType.isNotEmpty()) filterOptions.contentType = contentType // Apart from the examples above, there are more filters you can implement in you app. diff --git a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/gallery/GalleryFragment.kt b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/gallery/GalleryFragment.kt index 1971698c..c9ef5393 100644 --- a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/gallery/GalleryFragment.kt +++ b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/gallery/GalleryFragment.kt @@ -13,6 +13,8 @@ import androidx.recyclerview.widget.RecyclerView import com.google.android.material.radiobutton.MaterialRadioButton import com.pixlee.pixleeandroidsdk.BuildConfig import com.pixlee.pixleeandroidsdk.R +import com.pixlee.pixleeandroidsdk.databinding.FragmentGalleryBinding +import com.pixlee.pixleeandroidsdk.databinding.ModuleSearchBinding import com.pixlee.pixleeandroidsdk.ui.BaseFragment import com.pixlee.pixleeandroidsdk.ui.widgets.PXLPhotoViewInRecyclerViewFragment import com.pixlee.pixleeandroidsdk.ui.widgets.ViewerActivity @@ -33,8 +35,6 @@ import com.pixlee.pixleesdk.ui.widgets.ImageScaleType import com.pixlee.pixleesdk.ui.widgets.PXLPhotoView import com.pixlee.pixleesdk.ui.widgets.TextViewStyle import com.pixlee.pixleesdk.util.px -import kotlinx.android.synthetic.main.fragment_gallery.* -import kotlinx.android.synthetic.main.module_search.* /** * This shows how you can load photos of Pixlee using PXLAlbum.java @@ -53,30 +53,34 @@ class GalleryFragment : BaseFragment(), RequestHandlers?> { photoList = ArrayList() } + private var _binding: FragmentGalleryBinding? = null + private val binding get() = _binding!! + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.fragment_gallery, container, false) + _binding = FragmentGalleryBinding.inflate(inflater, container, false) + return binding.root } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) // set filter buttons - radioGroupContentTypeVideo.isChecked = false + binding.moduleSearchLayout.radioGroupContentTypeVideo.isChecked = false - fabFilter.setOnClickListener { drawerLayout.openDrawer(GravityCompat.END) } - btnCloseFilter.setOnClickListener { drawerLayout.closeDrawer(GravityCompat.END) } - btnApply.setOnClickListener { - drawerLayout.closeDrawer(GravityCompat.END) + binding.fabFilter.setOnClickListener { binding.drawerLayout.openDrawer(GravityCompat.END) } + binding.moduleSearchLayout.btnCloseFilter.setOnClickListener { binding.drawerLayout.closeDrawer(GravityCompat.END) } + binding.moduleSearchLayout.btnApply.setOnClickListener { + binding.drawerLayout.closeDrawer(GravityCompat.END) loadAlbum() } - gridToggleButton.setImageResource(lastImg) - gridToggleButton.setOnClickListener { - viewSwitcher.showNext() + binding.gridToggleButton.setImageResource(lastImg) + binding.gridToggleButton.setOnClickListener { + binding.viewSwitcher.showNext() lastImg = if (lastImg == R.drawable.grid_2x) { R.drawable.column_2x } else { R.drawable.grid_2x } - gridToggleButton.setImageResource(lastImg) + binding.gridToggleButton.setImageResource(lastImg) } if (gridAdapter == null) { loadAlbum() @@ -96,9 +100,9 @@ class GalleryFragment : BaseFragment(), RequestHandlers?> { val client = PXLClient.getInstance(it) // initiate album - for (i in 0 until radioGroupAlbum.childCount) { - val rb = radioGroupAlbum.getChildAt(i) as MaterialRadioButton - if (radioGroupAlbum.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupAlbum.childCount) { + val rb = binding.moduleSearchLayout.radioGroupAlbum.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupAlbum.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == getString(R.string.radio_album)) album = PXLAlbum(BuildConfig.PIXLEE_ALBUM_ID, client) else if (text == getString(R.string.radio_pdp)) album = PXLPdpAlbum(BuildConfig.PIXLEE_SKU, client.basicDataSource, client.analyticsDataSource) break @@ -128,7 +132,7 @@ class GalleryFragment : BaseFragment(), RequestHandlers?> { fun readPerPage(): Int { // Set textViewPerPage filter if text is not empty - val minTwitterFollowers = textViewPerPage.text.toString() + val minTwitterFollowers = binding.moduleSearchLayout.textViewPerPage.text.toString() return if (!minTwitterFollowers.isEmpty()) { Integer.valueOf(minTwitterFollowers) } else 20 @@ -137,7 +141,7 @@ class GalleryFragment : BaseFragment(), RequestHandlers?> { } fun readRegionIdFromUI(): Int?{ - val data = textViewRegionId.text.toString() + val data = binding.moduleSearchLayout.textViewRegionId.text.toString() return if (data.isNotEmpty()) { Integer.valueOf(data) } else null @@ -146,9 +150,9 @@ class GalleryFragment : BaseFragment(), RequestHandlers?> { fun readSortOptionsFromUI(): PXLAlbumSortOptions { val sortOptions = PXLAlbumSortOptions() // Set sortType filter if a radio button is selected - for (i in 0 until radioGroupSortType.childCount) { - val rb = radioGroupSortType.getChildAt(i) as MaterialRadioButton - if (radioGroupSortType.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupSortType.childCount) { + val rb = binding.moduleSearchLayout.radioGroupSortType.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupSortType.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == PXLAlbumSortType.RECENCY.value) sortOptions.sortType = PXLAlbumSortType.RECENCY else if (text == PXLAlbumSortType.APPROVED_TIME.value) sortOptions.sortType = PXLAlbumSortType.APPROVED_TIME else if (text == PXLAlbumSortType.RANDOM.value) sortOptions.sortType = PXLAlbumSortType.RANDOM else if (text == PXLAlbumSortType.PIXLEE_SHARES.value) sortOptions.sortType = PXLAlbumSortType.PIXLEE_SHARES else if (text == PXLAlbumSortType.PIXLEE_LIKES.value) sortOptions.sortType = PXLAlbumSortType.PIXLEE_LIKES else if (text == PXLAlbumSortType.POPULARITY.value) sortOptions.sortType = PXLAlbumSortType.POPULARITY else if (text == PXLAlbumSortType.DYNAMIC.value) sortOptions.sortType = PXLAlbumSortType.DYNAMIC break @@ -156,7 +160,7 @@ class GalleryFragment : BaseFragment(), RequestHandlers?> { } // Set sorting direction - if (radioGroupSortDirection.checkedRadioButtonId == radioGroupSortDirectionASC.id) sortOptions.descending = false else if (radioGroupSortDirection.checkedRadioButtonId == radioGroupSortDirectionDESC.id) sortOptions.descending = true + if (binding.moduleSearchLayout.radioGroupSortDirection.checkedRadioButtonId == binding.moduleSearchLayout.radioGroupSortDirectionASC.id) sortOptions.descending = false else if (binding.moduleSearchLayout.radioGroupSortDirection.checkedRadioButtonId == binding.moduleSearchLayout.radioGroupSortDirectionDESC.id) sortOptions.descending = true return sortOptions } @@ -164,21 +168,21 @@ class GalleryFragment : BaseFragment(), RequestHandlers?> { val filterOptions = PXLAlbumFilterOptions() // Set minTwitterFollowers filter if text is not empty - val minTwitterFollowers = textViewMinTwitterFollowers.text.toString() + val minTwitterFollowers = binding.moduleSearchLayout.textViewMinTwitterFollowers.text.toString() if (!minTwitterFollowers.isEmpty()) { filterOptions.minTwitterFollowers = Integer.valueOf(minTwitterFollowers) } // Set minInstagramFollowers filter if text is not empty - val minInstagramFollowers = textViewMinInstagramFollowers.text.toString() + val minInstagramFollowers = binding.moduleSearchLayout.textViewMinInstagramFollowers.text.toString() if (!minInstagramFollowers.isEmpty()) { filterOptions.minInstagramFollowers = Integer.valueOf(minInstagramFollowers) } // Set hasProduct filter if false or not true is set - for (i in 0 until radioGroupHasPermission.childCount) { - val rb = radioGroupHasPermission.getChildAt(i) as MaterialRadioButton - if (radioGroupHasPermission.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupHasPermission.childCount) { + val rb = binding.moduleSearchLayout.radioGroupHasPermission.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupHasPermission.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == getString(R.string.radio_false)) filterOptions.hasPermission = false else if (text == getString(R.string.radio_true)) filterOptions.hasPermission = true break @@ -186,9 +190,9 @@ class GalleryFragment : BaseFragment(), RequestHandlers?> { } // Set hasProduct filter if false or not true is set - for (i in 0 until radioGroupHasProduct.childCount) { - val rb = radioGroupHasProduct.getChildAt(i) as MaterialRadioButton - if (radioGroupHasProduct.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupHasProduct.childCount) { + val rb = binding.moduleSearchLayout.radioGroupHasProduct.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupHasProduct.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == getString(R.string.radio_false)) filterOptions.hasProduct = false else if (text == getString(R.string.radio_true)) filterOptions.hasProduct = true break @@ -196,9 +200,9 @@ class GalleryFragment : BaseFragment(), RequestHandlers?> { } // Set inStockOnly filter if false or not true is set - for (i in 0 until radioGroupInStockOnly.childCount) { - val rb = radioGroupInStockOnly.getChildAt(i) as MaterialRadioButton - if (radioGroupInStockOnly.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupInStockOnly.childCount) { + val rb = binding.moduleSearchLayout.radioGroupInStockOnly.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupInStockOnly.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == getString(R.string.radio_false)) filterOptions.inStockOnly = false else if (text == getString(R.string.radio_true)) filterOptions.inStockOnly = true break @@ -207,19 +211,19 @@ class GalleryFragment : BaseFragment(), RequestHandlers?> { // Set contentSource filter if any of its check boxes is selected val contentSource: ArrayList = ArrayList() - if (radioGroupContentSourceInstagramFeed.isChecked) contentSource.add(PXLContentSource.INSTAGRAM_FEED) - if (radioGroupContentSourceInstagramStory.isChecked) contentSource.add(PXLContentSource.INSTAGRAM_STORY) - if (radioGroupContentSourceTwitter.isChecked) contentSource.add(PXLContentSource.TWITTER) - if (radioGroupContentSourceFacebook.isChecked) contentSource.add(PXLContentSource.FACEBOOK) - if (radioGroupContentSourceApi.isChecked) contentSource.add(PXLContentSource.API) - if (radioGroupContentSourceDesktop.isChecked) contentSource.add(PXLContentSource.DESKTOP) - if (radioGroupContentSourceEmail.isChecked) contentSource.add(PXLContentSource.EMAIL) + if (binding.moduleSearchLayout.radioGroupContentSourceInstagramFeed.isChecked) contentSource.add(PXLContentSource.INSTAGRAM_FEED) + if (binding.moduleSearchLayout.radioGroupContentSourceInstagramStory.isChecked) contentSource.add(PXLContentSource.INSTAGRAM_STORY) + if (binding.moduleSearchLayout.radioGroupContentSourceTwitter.isChecked) contentSource.add(PXLContentSource.TWITTER) + if (binding.moduleSearchLayout.radioGroupContentSourceFacebook.isChecked) contentSource.add(PXLContentSource.FACEBOOK) + if (binding.moduleSearchLayout.radioGroupContentSourceApi.isChecked) contentSource.add(PXLContentSource.API) + if (binding.moduleSearchLayout.radioGroupContentSourceDesktop.isChecked) contentSource.add(PXLContentSource.DESKTOP) + if (binding.moduleSearchLayout.radioGroupContentSourceEmail.isChecked) contentSource.add(PXLContentSource.EMAIL) if (contentSource.isNotEmpty()) filterOptions.contentSource = contentSource // Set contentType filter if any of its check boxes is selected val contentType: ArrayList = ArrayList() - if (radioGroupContentTypeImage.isChecked) contentType.add(PXLContentType.IMAGE) - if (radioGroupContentTypeVideo.isChecked) contentType.add(PXLContentType.VIDEO) + if (binding.moduleSearchLayout.radioGroupContentTypeImage.isChecked) contentType.add(PXLContentType.IMAGE) + if (binding.moduleSearchLayout.radioGroupContentTypeVideo.isChecked) contentType.add(PXLContentType.VIDEO) if (contentType.isNotEmpty()) filterOptions.contentType = contentType // Apart from the examples above, there are more filters you can implement in you app. @@ -249,7 +253,7 @@ class GalleryFragment : BaseFragment(), RequestHandlers?> { } fun setLoading(visible: Boolean) { - lottieView?.also{ + binding.lottieView?.also{ if (visible) { it.visibility = View.VISIBLE } else { @@ -266,12 +270,12 @@ class GalleryFragment : BaseFragment(), RequestHandlers?> { var gridAdapter: GridAdapter? = null var listAdapter: ListAdapter? = null private fun configureViews() { - gridView.setHasFixedSize(true) - listView.setHasFixedSize(true) + binding.gridView.setHasFixedSize(true) + binding.listView.setHasFixedSize(true) val gridLayoutManager: RecyclerView.LayoutManager = GridLayoutManager(requireContext().applicationContext, 2) val listLayoutManager: RecyclerView.LayoutManager = GridLayoutManager(requireContext().applicationContext, 1) - gridView.layoutManager = gridLayoutManager - listView.layoutManager = listLayoutManager + binding.gridView.layoutManager = gridLayoutManager + binding.listView.layoutManager = listLayoutManager val li = GalleryClickListener { view, photo -> moveToViewer(view, photo) } if (gridAdapter == null) { gridAdapter = GridAdapter(requireContext().applicationContext, photoList, li) @@ -280,8 +284,8 @@ class GalleryFragment : BaseFragment(), RequestHandlers?> { }else{ menuList?.apply { findItem(R.id.action_live_list).isVisible = true } } - gridView.adapter = gridAdapter - listView.adapter = listAdapter + binding.gridView.adapter = gridAdapter + binding.listView.adapter = listAdapter val gridScrollListener: RecyclerViewEndlessScrollListener = object : RecyclerViewEndlessScrollListener(gridLayoutManager) { override fun onLoadMore(page: Int, totalItemsCount: Int, view: RecyclerView) { loadMorePhotos() @@ -292,10 +296,10 @@ class GalleryFragment : BaseFragment(), RequestHandlers?> { loadMorePhotos() } } - gridView.addOnScrollListener(gridScrollListener) - listView.addOnScrollListener(listScrollListener) + binding.gridView.addOnScrollListener(gridScrollListener) + binding.listView.addOnScrollListener(listScrollListener) listMode.also { - if (!it.isGridMode) viewSwitcher.showNext() + if (!it.isGridMode) binding.viewSwitcher.showNext() } } @@ -430,8 +434,8 @@ class GalleryFragment : BaseFragment(), RequestHandlers?> { //album.loadMore(); photoList!!.clear() photoList!!.addAll(photos) - gridView.adapter!!.notifyDataSetChanged() - listView.adapter!!.notifyDataSetChanged() + binding.gridView.adapter!!.notifyDataSetChanged() + binding.listView.adapter!!.notifyDataSetChanged() if (photos.size > 0) { samplePhotoLoad(photos[0]) } @@ -456,7 +460,7 @@ class GalleryFragment : BaseFragment(), RequestHandlers?> { } override fun onOptionsItemSelected(item: MenuItem): Boolean { - viewSwitcher.showNext() + binding.viewSwitcher.showNext() when (item.itemId) { R.id.action_grid -> { changeMenuForList(false) @@ -490,6 +494,7 @@ class GalleryFragment : BaseFragment(), RequestHandlers?> { override fun onDestroyView() { super.onDestroyView() menuList = null + _binding = null } companion object { diff --git a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/gallery/KtxGalleryGridFragment.kt b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/gallery/KtxGalleryGridFragment.kt index b007fb2c..f934328a 100644 --- a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/gallery/KtxGalleryGridFragment.kt +++ b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/gallery/KtxGalleryGridFragment.kt @@ -19,8 +19,8 @@ import androidx.lifecycle.Observer import androidx.lifecycle.lifecycleScope import com.google.android.material.radiobutton.MaterialRadioButton import com.pixlee.pixleeandroidsdk.BuildConfig -import com.pixlee.pixleesdk.util.EventObserver import com.pixlee.pixleeandroidsdk.R +import com.pixlee.pixleeandroidsdk.databinding.FragmentKtxGalleryGridBinding import com.pixlee.pixleeandroidsdk.ui.BaseFragment import com.pixlee.pixleeandroidsdk.ui.BaseViewModel import com.pixlee.pixleeandroidsdk.ui.widgets.PXLPhotoViewFragment @@ -40,15 +40,8 @@ import com.pixlee.pixleesdk.ui.widgets.TextViewStyle import com.pixlee.pixleesdk.ui.widgets.list.BaseRecyclerView import com.pixlee.pixleesdk.ui.widgets.list.ListHeader import com.pixlee.pixleesdk.ui.widgets.list.Space +import com.pixlee.pixleesdk.util.EventObserver import com.pixlee.pixleesdk.util.px -import kotlinx.android.synthetic.main.fragment_ktx_gallery_grid.* -import kotlinx.android.synthetic.main.fragment_ktx_gallery_grid.drawerLayout -import kotlinx.android.synthetic.main.fragment_ktx_gallery_grid.fabFilter -import kotlinx.android.synthetic.main.fragment_ktx_gallery_grid.fabUpload -import kotlinx.android.synthetic.main.fragment_ktx_gallery_grid.lottieView -import kotlinx.android.synthetic.main.fragment_ktx_gallery_grid.tvDebugText -import kotlinx.android.synthetic.main.fragment_ktx_gallery_grid.v_body -import kotlinx.android.synthetic.main.module_search.* import kotlinx.coroutines.launch import org.json.JSONArray import org.json.JSONException @@ -67,29 +60,38 @@ class KtxGalleryGridFragment : BaseFragment(), LifecycleObserver { KtxGalleryViewModel(PXLKtxAlbum(requireContext())) } + private var _binding: FragmentKtxGalleryGridBinding? = null + private val binding get() = _binding!! + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.fragment_ktx_gallery_grid, container, false) + _binding = FragmentKtxGalleryGridBinding.inflate(inflater, container, false) + return binding.root } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) listenAnalyticsForInstrumentTesting() setDataForAutoAnalytics() - radioGroupContentTypeVideo.isChecked = true + binding.moduleSearchLayout.radioGroupContentTypeVideo.isChecked = true initRecyclerView() addViewModelListeners() initFilterClickListeners() - v_body.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { + binding.vBody.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { try { - if (v_body == null) + if (binding.vBody == null) return - val cellHeightInPixel = v_body.measuredHeight * 0.5f + val cellHeightInPixel = binding.vBody.measuredHeight * 0.5f viewModel.cellHeightInPixel = cellHeightInPixel.toInt() loadAlbum() - v_body.viewTreeObserver.removeOnGlobalLayoutListener(this) + binding.vBody.viewTreeObserver.removeOnGlobalLayoutListener(this) } catch (e: Exception) { e.printStackTrace() } @@ -100,14 +102,14 @@ class KtxGalleryGridFragment : BaseFragment(), LifecycleObserver { fun listenAnalyticsForInstrumentTesting(){ viewLifecycleOwner.lifecycleScope.launch { - AnalyticsObserver.observe("Obsev.GalleryGrid", tvDebugText) + AnalyticsObserver.observe("Obsev.GalleryGrid", binding.tvDebugText) } } fun setDataForAutoAnalytics() { // if you want to delegate firing 'VisibleWidget' and 'OpenedWidget' analytics event to PXLPhotoRecyclerViewInGrid, use this code. // Prerequisite: PXLClient.autoAnalyticsEnabled = true located in in your application level. please check AppApplication.kt - pxlPhotoRecyclerViewInGrid.albumForAutoAnalytics = BaseRecyclerView.AlbumForAutoAnalytics(viewModel.pxlKtxAlbum, PXLWidgetType.photowall.type) + binding.pxlPhotoRecyclerViewInGrid.albumForAutoAnalytics = BaseRecyclerView.AlbumForAutoAnalytics(viewModel.pxlKtxAlbum, PXLWidgetType.photowall.type) // if you want to manually fire the two events, you don't use this and do need to implement our own analytics codes. Please check out KtxAnalyticsFragment.kt to get the sample codes. } @@ -118,18 +120,18 @@ class KtxGalleryGridFragment : BaseFragment(), LifecycleObserver { }) viewModel.uploadStatus.observe(viewLifecycleOwner, Observer{ - fabUpload.isEnabled = !it + binding.fabUpload.isEnabled = !it }) viewModel.loading.observe(viewLifecycleOwner, Observer { - lottieView.visibility = if (it) View.VISIBLE else View.GONE + binding.lottieView.visibility = if (it) View.VISIBLE else View.GONE }) viewModel.searchResultEvent.observe(viewLifecycleOwner, EventObserver { when (it) { is BaseViewModel.Command.Data -> { if (it.isFirstPage) { - pxlPhotoRecyclerViewInGrid.replaceList(it.list) + binding.pxlPhotoRecyclerViewInGrid.replaceList(it.list) if (it.list.isNotEmpty()) { it.list.firstOrNull()?.pxlPhoto?.also { viewModel.getPhotoWithId(it) // add your own region id @@ -139,11 +141,11 @@ class KtxGalleryGridFragment : BaseFragment(), LifecycleObserver { // if no result in the first page, open search panel so that the SDK developers will try out different filters if (it.list.isEmpty()) { Toast.makeText(context, "success!! but you got an empty list.\nwhat about trying different searching options here?", Toast.LENGTH_LONG).show() - drawerLayout.openDrawer(GravityCompat.END) + binding.drawerLayout.openDrawer(GravityCompat.END) } } else { - pxlPhotoRecyclerViewInGrid.addList(it.list) + binding.pxlPhotoRecyclerViewInGrid.addList(it.list) } } @@ -214,7 +216,7 @@ class KtxGalleryGridFragment : BaseFragment(), LifecycleObserver { } } // you can customize color, size if you need - pxlPhotoRecyclerViewInGrid.initiate(gridSpan = 2, // the number of cells in a row in the grid list + binding.pxlPhotoRecyclerViewInGrid.initiate(gridSpan = 2, // the number of cells in a row in the grid list lineSpace = Space().apply { lineWidthInPixel = 4.px.toInt() // space in pixel between cells includingEdge = false // true: if you want to have the space out side of the list, false: no space out side of the list @@ -237,11 +239,11 @@ class KtxGalleryGridFragment : BaseFragment(), LifecycleObserver { fun initFilterClickListeners() { // set filter buttons - fabUpload.setOnClickListener { setupExternalStoragePermission() } - fabFilter.setOnClickListener { drawerLayout.openDrawer(GravityCompat.END) } - btnCloseFilter.setOnClickListener { drawerLayout.closeDrawer(GravityCompat.END) } - btnApply.setOnClickListener { - drawerLayout.closeDrawer(GravityCompat.END) + binding.fabUpload.setOnClickListener { setupExternalStoragePermission() } + binding.fabFilter.setOnClickListener { binding.drawerLayout.openDrawer(GravityCompat.END) } + binding.moduleSearchLayout.btnCloseFilter.setOnClickListener { binding.drawerLayout.closeDrawer(GravityCompat.END) } + binding.moduleSearchLayout.btnApply.setOnClickListener { + binding.drawerLayout.closeDrawer(GravityCompat.END) loadAlbum() } } @@ -278,9 +280,9 @@ class KtxGalleryGridFragment : BaseFragment(), LifecycleObserver { context?.also { var searchId: PXLKtxBaseAlbum.SearchId? = null // initiate album - for (i in 0 until radioGroupAlbum.childCount) { - val rb = radioGroupAlbum.getChildAt(i) as MaterialRadioButton - if (radioGroupAlbum.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupAlbum.childCount) { + val rb = binding.moduleSearchLayout.radioGroupAlbum.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupAlbum.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == getString(R.string.radio_album)) { searchId = PXLKtxBaseAlbum.SearchId.Album(BuildConfig.PIXLEE_ALBUM_ID) @@ -314,7 +316,7 @@ class KtxGalleryGridFragment : BaseFragment(), LifecycleObserver { fun readPerPage(): Int { // Set textViewPerPage filter if text is not empty - val minTwitterFollowers = textViewPerPage.text.toString() + val minTwitterFollowers = binding.moduleSearchLayout.textViewPerPage.text.toString() return if (!minTwitterFollowers.isEmpty()) { Integer.valueOf(minTwitterFollowers) } else 20 @@ -323,7 +325,7 @@ class KtxGalleryGridFragment : BaseFragment(), LifecycleObserver { } fun readRegionIdFromUI(): Int? { - val data = textViewRegionId.text.toString() + val data = binding.moduleSearchLayout.textViewRegionId.text.toString() return if (data.isNotEmpty()) { Integer.valueOf(data) } else null @@ -332,9 +334,9 @@ class KtxGalleryGridFragment : BaseFragment(), LifecycleObserver { fun readSortOptionsFromUI(): PXLAlbumSortOptions { val sortOptions = PXLAlbumSortOptions() // Set sortType filter if a radio button is selected - for (i in 0 until radioGroupSortType.childCount) { - val rb = radioGroupSortType.getChildAt(i) as MaterialRadioButton - if (radioGroupSortType.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupSortType.childCount) { + val rb = binding.moduleSearchLayout.radioGroupSortType.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupSortType.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == PXLAlbumSortType.RECENCY.value) sortOptions.sortType = PXLAlbumSortType.RECENCY else if (text == PXLAlbumSortType.APPROVED_TIME.value) sortOptions.sortType = PXLAlbumSortType.APPROVED_TIME @@ -348,8 +350,8 @@ class KtxGalleryGridFragment : BaseFragment(), LifecycleObserver { } // Set sorting direction - if (radioGroupSortDirection.checkedRadioButtonId == radioGroupSortDirectionASC.id) sortOptions.descending = false - else if (radioGroupSortDirection.checkedRadioButtonId == radioGroupSortDirectionDESC.id) sortOptions.descending = true + if (binding.moduleSearchLayout.radioGroupSortDirection.checkedRadioButtonId == binding.moduleSearchLayout.radioGroupSortDirectionASC.id) sortOptions.descending = false + else if (binding.moduleSearchLayout.radioGroupSortDirection.checkedRadioButtonId == binding.moduleSearchLayout.radioGroupSortDirectionDESC.id) sortOptions.descending = true return sortOptions } @@ -357,21 +359,21 @@ class KtxGalleryGridFragment : BaseFragment(), LifecycleObserver { val filterOptions = PXLAlbumFilterOptions() // Set minTwitterFollowers filter if text is not empty - val minTwitterFollowers = textViewMinTwitterFollowers.text.toString() + val minTwitterFollowers = binding.moduleSearchLayout.textViewMinTwitterFollowers.text.toString() if (!minTwitterFollowers.isEmpty()) { filterOptions.minTwitterFollowers = Integer.valueOf(minTwitterFollowers) } // Set minInstagramFollowers filter if text is not empty - val minInstagramFollowers = textViewMinInstagramFollowers.text.toString() + val minInstagramFollowers = binding.moduleSearchLayout.textViewMinInstagramFollowers.text.toString() if (!minInstagramFollowers.isEmpty()) { filterOptions.minInstagramFollowers = Integer.valueOf(minInstagramFollowers) } // Set hasProduct filter if false or not true is set - for (i in 0 until radioGroupHasPermission.childCount) { - val rb = radioGroupHasPermission.getChildAt(i) as MaterialRadioButton - if (radioGroupHasPermission.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupHasPermission.childCount) { + val rb = binding.moduleSearchLayout.radioGroupHasPermission.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupHasPermission.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == getString(R.string.radio_false)) filterOptions.hasPermission = false else if (text == getString(R.string.radio_true)) filterOptions.hasPermission = true break @@ -379,9 +381,9 @@ class KtxGalleryGridFragment : BaseFragment(), LifecycleObserver { } // Set hasProduct filter if false or not true is set - for (i in 0 until radioGroupHasProduct.childCount) { - val rb = radioGroupHasProduct.getChildAt(i) as MaterialRadioButton - if (radioGroupHasProduct.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupHasProduct.childCount) { + val rb = binding.moduleSearchLayout.radioGroupHasProduct.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupHasProduct.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == getString(R.string.radio_false)) filterOptions.hasProduct = false else if (text == getString(R.string.radio_true)) filterOptions.hasProduct = true break @@ -389,9 +391,9 @@ class KtxGalleryGridFragment : BaseFragment(), LifecycleObserver { } // Set inStockOnly filter if false or not true is set - for (i in 0 until radioGroupInStockOnly.childCount) { - val rb = radioGroupInStockOnly.getChildAt(i) as MaterialRadioButton - if (radioGroupInStockOnly.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupInStockOnly.childCount) { + val rb = binding.moduleSearchLayout.radioGroupInStockOnly.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupInStockOnly.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == getString(R.string.radio_false)) filterOptions.inStockOnly = false else if (text == getString(R.string.radio_true)) filterOptions.inStockOnly = true break @@ -400,19 +402,19 @@ class KtxGalleryGridFragment : BaseFragment(), LifecycleObserver { // Set contentSource filter if any of its check boxes is selected val contentSource: ArrayList = ArrayList() - if (radioGroupContentSourceInstagramFeed.isChecked) contentSource.add(PXLContentSource.INSTAGRAM_FEED) - if (radioGroupContentSourceInstagramStory.isChecked) contentSource.add(PXLContentSource.INSTAGRAM_STORY) - if (radioGroupContentSourceTwitter.isChecked) contentSource.add(PXLContentSource.TWITTER) - if (radioGroupContentSourceFacebook.isChecked) contentSource.add(PXLContentSource.FACEBOOK) - if (radioGroupContentSourceApi.isChecked) contentSource.add(PXLContentSource.API) - if (radioGroupContentSourceDesktop.isChecked) contentSource.add(PXLContentSource.DESKTOP) - if (radioGroupContentSourceEmail.isChecked) contentSource.add(PXLContentSource.EMAIL) + if (binding.moduleSearchLayout.radioGroupContentSourceInstagramFeed.isChecked) contentSource.add(PXLContentSource.INSTAGRAM_FEED) + if (binding.moduleSearchLayout.radioGroupContentSourceInstagramStory.isChecked) contentSource.add(PXLContentSource.INSTAGRAM_STORY) + if (binding.moduleSearchLayout.radioGroupContentSourceTwitter.isChecked) contentSource.add(PXLContentSource.TWITTER) + if (binding.moduleSearchLayout.radioGroupContentSourceFacebook.isChecked) contentSource.add(PXLContentSource.FACEBOOK) + if (binding.moduleSearchLayout.radioGroupContentSourceApi.isChecked) contentSource.add(PXLContentSource.API) + if (binding.moduleSearchLayout.radioGroupContentSourceDesktop.isChecked) contentSource.add(PXLContentSource.DESKTOP) + if (binding.moduleSearchLayout.radioGroupContentSourceEmail.isChecked) contentSource.add(PXLContentSource.EMAIL) if (contentSource.isNotEmpty()) filterOptions.contentSource = contentSource // Set contentType filter if any of its check boxes is selected val contentType: ArrayList = ArrayList() - if (radioGroupContentTypeImage.isChecked) contentType.add(PXLContentType.IMAGE) - if (radioGroupContentTypeVideo.isChecked) contentType.add(PXLContentType.VIDEO) + if (binding.moduleSearchLayout.radioGroupContentTypeImage.isChecked) contentType.add(PXLContentType.IMAGE) + if (binding.moduleSearchLayout.radioGroupContentTypeVideo.isChecked) contentType.add(PXLContentType.VIDEO) if (contentType.isNotEmpty()) filterOptions.contentType = contentType // Apart from the examples above, there are more filters you can implement in you app. diff --git a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/gallery/KtxGalleryListFragment.kt b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/gallery/KtxGalleryListFragment.kt index affc5c72..47bba5af 100644 --- a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/gallery/KtxGalleryListFragment.kt +++ b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/gallery/KtxGalleryListFragment.kt @@ -17,15 +17,14 @@ import androidx.lifecycle.lifecycleScope import com.google.android.material.radiobutton.MaterialRadioButton import com.pixlee.pixleeandroidsdk.BuildConfig import com.pixlee.pixleeandroidsdk.R +import com.pixlee.pixleeandroidsdk.databinding.FragmentKtxGalleryListBinding import com.pixlee.pixleeandroidsdk.ui.BaseFragment import com.pixlee.pixleeandroidsdk.ui.BaseViewModel import com.pixlee.pixleeandroidsdk.ui.widgets.PXLPhotoViewFragment import com.pixlee.pixleeandroidsdk.ui.widgets.ViewerActivity -import com.pixlee.pixleesdk.client.PXLBaseAlbum.RequestHandlers import com.pixlee.pixleesdk.client.PXLClient import com.pixlee.pixleesdk.client.PXLKtxAlbum import com.pixlee.pixleesdk.client.PXLKtxBaseAlbum -import com.pixlee.pixleesdk.data.MediaResult import com.pixlee.pixleesdk.data.PXLAlbumFilterOptions import com.pixlee.pixleesdk.data.PXLAlbumSortOptions import com.pixlee.pixleesdk.enums.* @@ -37,11 +36,8 @@ import com.pixlee.pixleesdk.ui.widgets.TextViewStyle import com.pixlee.pixleesdk.ui.widgets.list.BaseRecyclerView import com.pixlee.pixleesdk.util.EventObserver import com.pixlee.pixleesdk.util.px -import kotlinx.android.synthetic.main.fragment_ktx_gallery_list.* -import kotlinx.android.synthetic.main.module_search.* import kotlinx.coroutines.launch import org.json.JSONArray -import org.json.JSONException import org.json.JSONObject @@ -58,37 +54,47 @@ class KtxGalleryListFragment : BaseFragment(), LifecycleObserver { KtxGalleryViewModel(PXLKtxAlbum(requireContext())) } + private var _binding: FragmentKtxGalleryListBinding? = null + private val binding get() = _binding!! + + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.fragment_ktx_gallery_list, container, false) + _binding = FragmentKtxGalleryListBinding.inflate(inflater, container, false) + return binding.root } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) listenAnalyticsForInstrumentTesting() setDataForAutoAnalytics() - radioGroupContentTypeVideo.isChecked = false - switchSound.isChecked = false - switchSound.setOnClickListener { - if (switchSound.isChecked) - pxlPhotoRecyclerView.unmute() + binding.moduleSearchLayout.radioGroupContentTypeVideo.isChecked = false + binding.switchSound.isChecked = false + binding.switchSound.setOnClickListener { + if (binding.switchSound.isChecked) + binding.pxlPhotoRecyclerView.unmute() else - pxlPhotoRecyclerView.mute() + binding.pxlPhotoRecyclerView.mute() } initRecyclerView() addViewModelListeners() initFilterClickListeners() configureViews() - v_body.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { + binding.vBody.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { try { - if (v_body == null) + if (binding.vBody == null) return - val cellHeightInPixel = v_body.measuredHeight * 0.5f + val cellHeightInPixel = binding.vBody.measuredHeight * 0.5f viewModel.cellHeightInPixel = cellHeightInPixel.toInt() loadAlbum() - v_body.viewTreeObserver.removeOnGlobalLayoutListener(this) + binding.vBody.viewTreeObserver.removeOnGlobalLayoutListener(this) } catch (e: Exception) { e.printStackTrace() } @@ -99,14 +105,14 @@ class KtxGalleryListFragment : BaseFragment(), LifecycleObserver { fun listenAnalyticsForInstrumentTesting() { viewLifecycleOwner.lifecycleScope.launch { - AnalyticsObserver.observe("Obsev.GalleryList", tvDebugText) + AnalyticsObserver.observe("Obsev.GalleryList", binding.tvDebugText) } } fun setDataForAutoAnalytics() { // if you want to delegate firing 'VisibleWidget' and 'OpenedWidget' analytics event to PXLPhotoRecyclerView, use this code. // Prerequisite: PXLClient.autoAnalyticsEnabled = true located in in your application that extends Application. please check AppApplication.kt - pxlPhotoRecyclerView.albumForAutoAnalytics = BaseRecyclerView.AlbumForAutoAnalytics(viewModel.pxlKtxAlbum, PXLWidgetType.photowall.type) + binding.pxlPhotoRecyclerView.albumForAutoAnalytics = BaseRecyclerView.AlbumForAutoAnalytics(viewModel.pxlKtxAlbum, PXLWidgetType.photowall.type) // if you want to manually fire the two events, you don't use this and do need to implement our own analytics codes. Please check out KtxAnalyticsFragment.kt to get the sample codes. } @@ -117,19 +123,19 @@ class KtxGalleryListFragment : BaseFragment(), LifecycleObserver { }) viewModel.uploadStatus.observe(viewLifecycleOwner, Observer { - fabUpload.isEnabled = !it + binding.fabUpload.isEnabled = !it }) viewModel.loading.observe(viewLifecycleOwner, Observer { - lottieView.visibility = if (it) View.VISIBLE else View.GONE + binding.lottieView.visibility = if (it) View.VISIBLE else View.GONE }) viewModel.searchResultEvent.observe(viewLifecycleOwner, EventObserver { when (it) { is BaseViewModel.Command.Data -> { if (it.isFirstPage) { - pxlPhotoRecyclerView.replaceList(it.list) - pxlPhotoRecyclerView.playVideoOnResume() + binding.pxlPhotoRecyclerView.replaceList(it.list) + binding.pxlPhotoRecyclerView.playVideoOnResume() if (it.list.isNotEmpty()) { it.list.firstOrNull()?.pxlPhoto?.also { viewModel.getPhotoWithId(it) // add your own region id @@ -139,10 +145,10 @@ class KtxGalleryListFragment : BaseFragment(), LifecycleObserver { // if no result in the first page, open search panel so that the SDK developers will try out different filters if (it.list.isEmpty()) { Toast.makeText(context, "success!! but you got an empty list.\nwhat about trying different searching options here?", Toast.LENGTH_LONG).show() - drawerLayout.openDrawer(GravityCompat.END) + binding.drawerLayout.openDrawer(GravityCompat.END) } } else { - pxlPhotoRecyclerView.addList(it.list) + binding.pxlPhotoRecyclerView.addList(it.list) } } @@ -195,10 +201,10 @@ class KtxGalleryListFragment : BaseFragment(), LifecycleObserver { } // this will play the video on onResume and stop the video on onPause - pxlPhotoRecyclerView.useLifecycleObserver(lifecycle) + binding.pxlPhotoRecyclerView.useLifecycleObserver(lifecycle) // you can customize color, size if you need - pxlPhotoRecyclerView.initiate(infiniteScroll = false, + binding.pxlPhotoRecyclerView.initiate(infiniteScroll = false, showingDebugView = false, onButtonClickedListener = { view, photoWithImageScaleType -> context?.also { ctx -> @@ -217,11 +223,11 @@ class KtxGalleryListFragment : BaseFragment(), LifecycleObserver { fun initFilterClickListeners() { // set filter buttons - fabUpload.setOnClickListener { setupExternalStoragePermission() } - fabFilter.setOnClickListener { drawerLayout.openDrawer(GravityCompat.END) } - btnCloseFilter.setOnClickListener { drawerLayout.closeDrawer(GravityCompat.END) } - btnApply.setOnClickListener { - drawerLayout.closeDrawer(GravityCompat.END) + binding.fabUpload.setOnClickListener { setupExternalStoragePermission() } + binding.fabFilter.setOnClickListener { binding.drawerLayout.openDrawer(GravityCompat.END) } + binding.moduleSearchLayout.btnCloseFilter.setOnClickListener { binding.drawerLayout.closeDrawer(GravityCompat.END) } + binding.moduleSearchLayout.btnApply.setOnClickListener { + binding.drawerLayout.closeDrawer(GravityCompat.END) loadAlbum() } } @@ -254,9 +260,9 @@ class KtxGalleryListFragment : BaseFragment(), LifecycleObserver { context?.also { var searchId: PXLKtxBaseAlbum.SearchId? = null // initiate album - for (i in 0 until radioGroupAlbum.childCount) { - val rb = radioGroupAlbum.getChildAt(i) as MaterialRadioButton - if (radioGroupAlbum.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupAlbum.childCount) { + val rb = binding.moduleSearchLayout.radioGroupAlbum.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupAlbum.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == getString(R.string.radio_album)) { searchId = PXLKtxBaseAlbum.SearchId.Album(BuildConfig.PIXLEE_ALBUM_ID) @@ -289,7 +295,7 @@ class KtxGalleryListFragment : BaseFragment(), LifecycleObserver { } private fun configureViews() { - pxlPhotoRecyclerView.addOnScrollListener(object : + binding.pxlPhotoRecyclerView.addOnScrollListener(object : androidx.recyclerview.widget.RecyclerView.OnScrollListener() { override fun onScrolled( recyclerView: androidx.recyclerview.widget.RecyclerView, @@ -297,7 +303,7 @@ class KtxGalleryListFragment : BaseFragment(), LifecycleObserver { dy: Int ) { super.onScrolled(recyclerView, dx, dy) - pxlPhotoRecyclerView.linearLayoutManager.apply { + binding.pxlPhotoRecyclerView.linearLayoutManager.apply { viewModel.listScrolled(childCount, findLastVisibleItemPosition(), itemCount) } } @@ -306,7 +312,7 @@ class KtxGalleryListFragment : BaseFragment(), LifecycleObserver { fun readPerPage(): Int { // Set textViewPerPage filter if text is not empty - val minTwitterFollowers = textViewPerPage.text.toString() + val minTwitterFollowers = binding.moduleSearchLayout.textViewPerPage.text.toString() return if (!minTwitterFollowers.isEmpty()) { Integer.valueOf(minTwitterFollowers) } else 20 @@ -315,7 +321,7 @@ class KtxGalleryListFragment : BaseFragment(), LifecycleObserver { } fun readRegionIdFromUI(): Int? { - val data = textViewRegionId.text.toString() + val data = binding.moduleSearchLayout.textViewRegionId.text.toString() return if (data.isNotEmpty()) { Integer.valueOf(data) } else null @@ -324,9 +330,9 @@ class KtxGalleryListFragment : BaseFragment(), LifecycleObserver { fun readSortOptionsFromUI(): PXLAlbumSortOptions { val sortOptions = PXLAlbumSortOptions() // Set sortType filter if a radio button is selected - for (i in 0 until radioGroupSortType.childCount) { - val rb = radioGroupSortType.getChildAt(i) as MaterialRadioButton - if (radioGroupSortType.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupSortType.childCount) { + val rb = binding.moduleSearchLayout.radioGroupSortType.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupSortType.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == PXLAlbumSortType.RECENCY.value) sortOptions.sortType = PXLAlbumSortType.RECENCY else if (text == PXLAlbumSortType.APPROVED_TIME.value) sortOptions.sortType = PXLAlbumSortType.APPROVED_TIME @@ -340,8 +346,8 @@ class KtxGalleryListFragment : BaseFragment(), LifecycleObserver { } // Set sorting direction - if (radioGroupSortDirection.checkedRadioButtonId == radioGroupSortDirectionASC.id) sortOptions.descending = false - else if (radioGroupSortDirection.checkedRadioButtonId == radioGroupSortDirectionDESC.id) sortOptions.descending = true + if (binding.moduleSearchLayout.radioGroupSortDirection.checkedRadioButtonId == binding.moduleSearchLayout.radioGroupSortDirectionASC.id) sortOptions.descending = false + else if (binding.moduleSearchLayout.radioGroupSortDirection.checkedRadioButtonId == binding.moduleSearchLayout.radioGroupSortDirectionDESC.id) sortOptions.descending = true return sortOptions } @@ -349,21 +355,21 @@ class KtxGalleryListFragment : BaseFragment(), LifecycleObserver { val filterOptions = PXLAlbumFilterOptions() // Set minTwitterFollowers filter if text is not empty - val minTwitterFollowers = textViewMinTwitterFollowers.text.toString() + val minTwitterFollowers = binding.moduleSearchLayout.textViewMinTwitterFollowers.text.toString() if (!minTwitterFollowers.isEmpty()) { filterOptions.minTwitterFollowers = Integer.valueOf(minTwitterFollowers) } // Set minInstagramFollowers filter if text is not empty - val minInstagramFollowers = textViewMinInstagramFollowers.text.toString() + val minInstagramFollowers = binding.moduleSearchLayout.textViewMinInstagramFollowers.text.toString() if (!minInstagramFollowers.isEmpty()) { filterOptions.minInstagramFollowers = Integer.valueOf(minInstagramFollowers) } // Set hasProduct filter if false or not true is set - for (i in 0 until radioGroupHasPermission.childCount) { - val rb = radioGroupHasPermission.getChildAt(i) as MaterialRadioButton - if (radioGroupHasPermission.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupHasPermission.childCount) { + val rb = binding.moduleSearchLayout.radioGroupHasPermission.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupHasPermission.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == getString(R.string.radio_false)) filterOptions.hasPermission = false else if (text == getString(R.string.radio_true)) filterOptions.hasPermission = true break @@ -371,9 +377,9 @@ class KtxGalleryListFragment : BaseFragment(), LifecycleObserver { } // Set hasProduct filter if false or not true is set - for (i in 0 until radioGroupHasProduct.childCount) { - val rb = radioGroupHasProduct.getChildAt(i) as MaterialRadioButton - if (radioGroupHasProduct.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupHasProduct.childCount) { + val rb = binding.moduleSearchLayout.radioGroupHasProduct.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupHasProduct.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == getString(R.string.radio_false)) filterOptions.hasProduct = false else if (text == getString(R.string.radio_true)) filterOptions.hasProduct = true break @@ -381,9 +387,9 @@ class KtxGalleryListFragment : BaseFragment(), LifecycleObserver { } // Set inStockOnly filter if false or not true is set - for (i in 0 until radioGroupInStockOnly.childCount) { - val rb = radioGroupInStockOnly.getChildAt(i) as MaterialRadioButton - if (radioGroupInStockOnly.checkedRadioButtonId == rb.id) { + for (i in 0 until binding.moduleSearchLayout.radioGroupInStockOnly.childCount) { + val rb = binding.moduleSearchLayout.radioGroupInStockOnly.getChildAt(i) as MaterialRadioButton + if (binding.moduleSearchLayout.radioGroupInStockOnly.checkedRadioButtonId == rb.id) { val text = rb.text.toString() if (text == getString(R.string.radio_false)) filterOptions.inStockOnly = false else if (text == getString(R.string.radio_true)) filterOptions.inStockOnly = true break @@ -392,19 +398,19 @@ class KtxGalleryListFragment : BaseFragment(), LifecycleObserver { // Set contentSource filter if any of its check boxes is selected val contentSource: ArrayList = ArrayList() - if (radioGroupContentSourceInstagramFeed.isChecked) contentSource.add(PXLContentSource.INSTAGRAM_FEED) - if (radioGroupContentSourceInstagramStory.isChecked) contentSource.add(PXLContentSource.INSTAGRAM_STORY) - if (radioGroupContentSourceTwitter.isChecked) contentSource.add(PXLContentSource.TWITTER) - if (radioGroupContentSourceFacebook.isChecked) contentSource.add(PXLContentSource.FACEBOOK) - if (radioGroupContentSourceApi.isChecked) contentSource.add(PXLContentSource.API) - if (radioGroupContentSourceDesktop.isChecked) contentSource.add(PXLContentSource.DESKTOP) - if (radioGroupContentSourceEmail.isChecked) contentSource.add(PXLContentSource.EMAIL) + if (binding.moduleSearchLayout.radioGroupContentSourceInstagramFeed.isChecked) contentSource.add(PXLContentSource.INSTAGRAM_FEED) + if (binding.moduleSearchLayout.radioGroupContentSourceInstagramStory.isChecked) contentSource.add(PXLContentSource.INSTAGRAM_STORY) + if (binding.moduleSearchLayout.radioGroupContentSourceTwitter.isChecked) contentSource.add(PXLContentSource.TWITTER) + if (binding.moduleSearchLayout.radioGroupContentSourceFacebook.isChecked) contentSource.add(PXLContentSource.FACEBOOK) + if (binding.moduleSearchLayout.radioGroupContentSourceApi.isChecked) contentSource.add(PXLContentSource.API) + if (binding.moduleSearchLayout.radioGroupContentSourceDesktop.isChecked) contentSource.add(PXLContentSource.DESKTOP) + if (binding.moduleSearchLayout.radioGroupContentSourceEmail.isChecked) contentSource.add(PXLContentSource.EMAIL) if (contentSource.isNotEmpty()) filterOptions.contentSource = contentSource // Set contentType filter if any of its check boxes is selected val contentType: ArrayList = ArrayList() - if (radioGroupContentTypeImage.isChecked) contentType.add(PXLContentType.IMAGE) - if (radioGroupContentTypeVideo.isChecked) contentType.add(PXLContentType.VIDEO) + if (binding.moduleSearchLayout.radioGroupContentTypeImage.isChecked) contentType.add(PXLContentType.IMAGE) + if (binding.moduleSearchLayout.radioGroupContentTypeVideo.isChecked) contentType.add(PXLContentType.VIDEO) if (contentType.isNotEmpty()) filterOptions.contentType = contentType // Apart from the examples above, there are more filters you can implement in you app. diff --git a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/uioptions/ProductViewFragment.kt b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/uioptions/ProductViewFragment.kt index 2e80da0a..a99ee356 100644 --- a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/uioptions/ProductViewFragment.kt +++ b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/uioptions/ProductViewFragment.kt @@ -10,6 +10,7 @@ import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import com.pixlee.pixleeandroidsdk.R +import com.pixlee.pixleeandroidsdk.databinding.FragmentProductViewBinding import com.pixlee.pixleeandroidsdk.ui.BaseFragment import com.pixlee.pixleeandroidsdk.ui.widgets.ViewerActivity import com.pixlee.pixleesdk.data.PXLProduct @@ -19,7 +20,6 @@ import com.pixlee.pixleesdk.ui.viewholder.PhotoWithVideoInfo import com.pixlee.pixleesdk.ui.viewholder.ProductViewHolder import com.pixlee.pixleesdk.ui.widgets.* import com.pixlee.pixleesdk.util.px -import kotlinx.android.synthetic.main.fragment_product_view.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -41,14 +41,18 @@ class ProductViewFragment : BaseFragment() { return R.string.title_product_view } + private var _binding: FragmentProductViewBinding? = null + private val binding get() = _binding!! + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.fragment_product_view, container, false) + _binding = FragmentProductViewBinding.inflate(inflater, container, false) + return binding.root } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - btnProductView.setOnClickListener { + binding.btnProductView.setOnClickListener { openViwerActivity() } @@ -60,18 +64,18 @@ class ProductViewFragment : BaseFragment() { val result = mockAlbumUtil.album.getFirstPage() val products = result.photos.firstOrNull()?.products ?: emptyList() - rvOption1.adapter = makeProducts(ProductViewHolder.DiscountLayout.CROSS_THROUGH, products) - rvOption2.adapter = makeProducts(ProductViewHolder.DiscountLayout.WAS_OLD_PRICE, products) - rvOption3.adapter = makeProducts(ProductViewHolder.DiscountLayout.WITH_DISCOUNT_LABEL, products) - rvOption4.adapter = makeProducts(null, products) - rvOption1Icon.adapter = makeProducts(ProductViewHolder.DiscountLayout.CROSS_THROUGH, products, showShopIcon = true) - rvOption2Icon.adapter = makeProducts(ProductViewHolder.DiscountLayout.WAS_OLD_PRICE, products, showShopIcon = true) - rvOption3Icon.adapter = makeProducts(ProductViewHolder.DiscountLayout.WITH_DISCOUNT_LABEL, products, showShopIcon = true) - rvOption4Icon.adapter = makeProducts(null, products, showShopIcon = true) - rvOption1All.adapter = makeProducts(ProductViewHolder.DiscountLayout.CROSS_THROUGH, products, showBookmarkIcon = true, showShopIcon = true) - rvOption2All.adapter = makeProducts(ProductViewHolder.DiscountLayout.WAS_OLD_PRICE, products, showBookmarkIcon = true, showShopIcon = true) - rvOption3All.adapter = makeProducts(ProductViewHolder.DiscountLayout.WITH_DISCOUNT_LABEL, products, showBookmarkIcon = true, showShopIcon = true) - rvOption4All.adapter = makeProducts(null, products, showBookmarkIcon = true, showShopIcon = true) + binding.rvOption1.adapter = makeProducts(ProductViewHolder.DiscountLayout.CROSS_THROUGH, products) + binding.rvOption2.adapter = makeProducts(ProductViewHolder.DiscountLayout.WAS_OLD_PRICE, products) + binding.rvOption3.adapter = makeProducts(ProductViewHolder.DiscountLayout.WITH_DISCOUNT_LABEL, products) + binding.rvOption4.adapter = makeProducts(null, products) + binding.rvOption1Icon.adapter = makeProducts(ProductViewHolder.DiscountLayout.CROSS_THROUGH, products, showShopIcon = true) + binding.rvOption2Icon.adapter = makeProducts(ProductViewHolder.DiscountLayout.WAS_OLD_PRICE, products, showShopIcon = true) + binding.rvOption3Icon.adapter = makeProducts(ProductViewHolder.DiscountLayout.WITH_DISCOUNT_LABEL, products, showShopIcon = true) + binding.rvOption4Icon.adapter = makeProducts(null, products, showShopIcon = true) + binding.rvOption1All.adapter = makeProducts(ProductViewHolder.DiscountLayout.CROSS_THROUGH, products, showBookmarkIcon = true, showShopIcon = true) + binding.rvOption2All.adapter = makeProducts(ProductViewHolder.DiscountLayout.WAS_OLD_PRICE, products, showBookmarkIcon = true, showShopIcon = true) + binding.rvOption3All.adapter = makeProducts(ProductViewHolder.DiscountLayout.WITH_DISCOUNT_LABEL, products, showBookmarkIcon = true, showShopIcon = true) + binding.rvOption4All.adapter = makeProducts(null, products, showBookmarkIcon = true, showShopIcon = true) } } diff --git a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/widgets/HotspotsActivity.kt b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/widgets/HotspotsActivity.kt index d21ff6d2..ed9d7d28 100644 --- a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/widgets/HotspotsActivity.kt +++ b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/widgets/HotspotsActivity.kt @@ -11,6 +11,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope import com.pixlee.pixleeandroidsdk.R +import com.pixlee.pixleeandroidsdk.databinding.ActivityViewerBinding import com.pixlee.pixleeandroidsdk.ui.uioptions.MockAlbumUtil import com.pixlee.pixleesdk.data.PXLPhoto import com.pixlee.pixleesdk.enums.PXLPhotoSize @@ -19,7 +20,6 @@ import com.pixlee.pixleesdk.ui.viewholder.ProductViewHolder import com.pixlee.pixleesdk.ui.widgets.* import com.pixlee.pixleesdk.util.PXLViewUtil import com.pixlee.pixleesdk.util.px -import kotlinx.android.synthetic.main.activity_viewer.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -40,17 +40,22 @@ class HotspotsActivity : AppCompatActivity() { override fun onDestroy() { super.onDestroy() mockAlbumUtil.release() + _binding = null } + private var _binding: ActivityViewerBinding? = null + private val binding get() = _binding!! + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_viewer) + _binding = ActivityViewerBinding.inflate(layoutInflater) + setContentView(binding.root) // set a full screen mode PXLViewUtil.expandContentAreaOverStatusBar(this) // give a padding to the top as much as the status bar's height - pxlPhotoProductView.addPaddingToHeader(0, PXLViewUtil.getStatusBarHeight(this), 0, 0) + binding.pxlPhotoProductView.addPaddingToHeader(0, PXLViewUtil.getStatusBarHeight(this), 0, 0) lifecycleScope.launch { withContext(Dispatchers.IO) { @@ -74,7 +79,7 @@ class HotspotsActivity : AppCompatActivity() { fun init(item: PhotoWithVideoInfo) { // set your ui settings - pxlPhotoProductView + binding.pxlPhotoProductView .setContent(photoInfo = item, showHotspots = true, headerConfiguration = PXLPhotoProductView.Configuration().apply { diff --git a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/widgets/PXLPhotoViewFragment.kt b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/widgets/PXLPhotoViewFragment.kt index 9a00ae0b..1d82cda9 100644 --- a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/widgets/PXLPhotoViewFragment.kt +++ b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/widgets/PXLPhotoViewFragment.kt @@ -15,6 +15,9 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleObserver import androidx.lifecycle.OnLifecycleEvent import com.pixlee.pixleeandroidsdk.R +import com.pixlee.pixleeandroidsdk.databinding.FragmentKtxGalleryListBinding +import com.pixlee.pixleeandroidsdk.databinding.FragmentPxlphotoViewBinding +import com.pixlee.pixleeandroidsdk.databinding.ModuleSearchBinding import com.pixlee.pixleeandroidsdk.ui.BaseFragment import com.pixlee.pixleesdk.enums.PXLPhotoSize import com.pixlee.pixleesdk.ui.viewholder.PhotoWithImageScaleType @@ -22,7 +25,6 @@ import com.pixlee.pixleesdk.ui.widgets.ImageScaleType import com.pixlee.pixleesdk.ui.widgets.PXLPhotoView import com.pixlee.pixleesdk.ui.widgets.TextViewStyle import com.pixlee.pixleesdk.util.px -import kotlinx.android.synthetic.main.fragment_pxlphoto_view.* /** * This is to display a photo with texts of PXLPhoto @@ -32,23 +34,32 @@ class PXLPhotoViewFragment : BaseFragment(), LifecycleObserver { return R.string.title_pxlphotoview } + private var _binding: FragmentPxlphotoViewBinding? = null + private val binding get() = _binding!! + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.fragment_pxlphoto_view, container, false) + _binding = FragmentPxlphotoViewBinding.inflate(inflater, container, false) + return binding.root } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - switchSound.setOnClickListener { - pxlPhotoViewFitWrapLandscape.apply { - if(switchSound.isChecked) unmute() else mute() + binding.switchSound.setOnClickListener { + binding.pxlPhotoViewFitWrapLandscape.apply { + if(binding.switchSound.isChecked) unmute() else mute() } - pxlPhotoViewFitPortrait.apply { - if(switchSound.isChecked) unmute() else mute() + binding.pxlPhotoViewFitPortrait.apply { + if(binding.switchSound.isChecked) unmute() else mute() } - pxlPhotoViewCrop.apply { - if(switchSound.isChecked) unmute() else mute() + binding.pxlPhotoViewCrop.apply { + if(binding.switchSound.isChecked) unmute() else mute() } } @@ -98,18 +109,18 @@ class PXLPhotoViewFragment : BaseFragment(), LifecycleObserver { } - initPXLPhotoView(pxlPhotoViewFitWrapLandscape, configuration.copy(), it, ImageScaleType.FIT_CENTER) - initPXLPhotoView(pxlPhotoViewFitPortrait, configuration.copy(), it, ImageScaleType.FIT_CENTER) - initPXLPhotoView(pxlPhotoViewCrop, configuration.copy(), it, ImageScaleType.CENTER_CROP) + initPXLPhotoView(binding.pxlPhotoViewFitWrapLandscape, configuration.copy(), it, ImageScaleType.FIT_CENTER) + initPXLPhotoView(binding.pxlPhotoViewFitPortrait, configuration.copy(), it, ImageScaleType.FIT_CENTER) + initPXLPhotoView(binding.pxlPhotoViewCrop, configuration.copy(), it, ImageScaleType.CENTER_CROP) - scrollView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { + binding.scrollView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { try { - if (scrollView == null) + if (binding.scrollView == null) return startScrollListener() - scrollView.viewTreeObserver.removeOnGlobalLayoutListener(this) + binding.scrollView.viewTreeObserver.removeOnGlobalLayoutListener(this) } catch (e: Exception) { e.printStackTrace() } @@ -127,11 +138,11 @@ class PXLPhotoViewFragment : BaseFragment(), LifecycleObserver { } fun startScrollListener() { - pxlPhotoViewFitWrapLandscape.playVideo() + binding.pxlPhotoViewFitWrapLandscape.playVideo() val scrollBounds = Rect() - scrollView.getHitRect(scrollBounds) - scrollView.setOnScrollChangeListener { v: NestedScrollView?, scrollX: Int, scrollY: Int, oldScrollX: Int, oldScrollY: Int -> + binding.scrollView.getHitRect(scrollBounds) + binding.scrollView.setOnScrollChangeListener { v: NestedScrollView?, scrollX: Int, scrollY: Int, oldScrollX: Int, oldScrollY: Int -> playRelevantVideo(scrollBounds) } } @@ -146,14 +157,14 @@ class PXLPhotoViewFragment : BaseFragment(), LifecycleObserver { } } - if (pxlPhotoViewFitWrapLandscape.getLocalVisibleRect(scrollBounds)) { - stopExistingAndPlayNew(pxlPhotoViewFitWrapLandscape, 1) + if (binding.pxlPhotoViewFitWrapLandscape.getLocalVisibleRect(scrollBounds)) { + stopExistingAndPlayNew(binding.pxlPhotoViewFitWrapLandscape, 1) - } else if (pxlPhotoViewCrop.getLocalVisibleRect(scrollBounds)) { - stopExistingAndPlayNew(pxlPhotoViewCrop, 2) + } else if (binding.pxlPhotoViewCrop.getLocalVisibleRect(scrollBounds)) { + stopExistingAndPlayNew(binding.pxlPhotoViewCrop, 2) - }else if (pxlPhotoViewFitPortrait.getLocalVisibleRect(scrollBounds)) { - stopExistingAndPlayNew(pxlPhotoViewFitPortrait, 3) + }else if (binding.pxlPhotoViewFitPortrait.getLocalVisibleRect(scrollBounds)) { + stopExistingAndPlayNew(binding.pxlPhotoViewFitPortrait, 3) } } @@ -180,14 +191,14 @@ class PXLPhotoViewFragment : BaseFragment(), LifecycleObserver { fun playVideo(){ val scrollBounds = Rect() - scrollView.getHitRect(scrollBounds) + binding.scrollView.getHitRect(scrollBounds) playRelevantVideo(scrollBounds) } fun stopVideo() { - pxlPhotoViewFitWrapLandscape.pauseVideo() - pxlPhotoViewCrop.pauseVideo() - pxlPhotoViewFitPortrait.pauseVideo() + binding.pxlPhotoViewFitWrapLandscape.pauseVideo() + binding.pxlPhotoViewCrop.pauseVideo() + binding.pxlPhotoViewFitPortrait.pauseVideo() } override fun onStop() { diff --git a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/widgets/PXLPhotoViewInRecyclerViewFragment.kt b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/widgets/PXLPhotoViewInRecyclerViewFragment.kt index cfe0087c..c569c1f6 100644 --- a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/widgets/PXLPhotoViewInRecyclerViewFragment.kt +++ b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/widgets/PXLPhotoViewInRecyclerViewFragment.kt @@ -10,6 +10,7 @@ import android.view.ViewTreeObserver import android.widget.Toast import androidx.fragment.app.Fragment import com.pixlee.pixleeandroidsdk.R +import com.pixlee.pixleeandroidsdk.databinding.FragmentPxlphotoviewInRecyclerviewBinding import com.pixlee.pixleeandroidsdk.ui.BaseFragment import com.pixlee.pixleesdk.data.PXLPhoto import com.pixlee.pixleesdk.enums.PXLPhotoSize @@ -18,7 +19,6 @@ import com.pixlee.pixleesdk.ui.widgets.ImageScaleType import com.pixlee.pixleesdk.ui.widgets.PXLPhotoView import com.pixlee.pixleesdk.ui.widgets.TextViewStyle import com.pixlee.pixleesdk.util.px -import kotlinx.android.synthetic.main.fragment_pxlphotoview_in_recyclerview.* /** * This is to display a photo with texts of PXLPhoto in RecyclerView @@ -28,13 +28,17 @@ class PXLPhotoViewInRecyclerViewFragment : BaseFragment() { return R.string.title_pxlphotoview_in_recyclerview } + private var _binding: FragmentPxlphotoviewInRecyclerviewBinding? = null + private val binding get() = _binding!! + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.fragment_pxlphotoview_in_recyclerview, container, false) + _binding = FragmentPxlphotoviewInRecyclerviewBinding.inflate(inflater, container, false) + return binding.root } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - pxlPhotoRecyclerView.initiate(infiniteScroll = false, + binding.pxlPhotoRecyclerView.initiate(infiniteScroll = false, onButtonClickedListener = { view, pxlPhoto -> context?.also { ctx -> Toast.makeText(ctx, "onButtonClickedListener", Toast.LENGTH_SHORT).show() @@ -46,15 +50,15 @@ class PXLPhotoViewInRecyclerViewFragment : BaseFragment() { } }) - pxlPhotoRecyclerView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { + binding.pxlPhotoRecyclerView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { try { - if (pxlPhotoRecyclerView == null) + if (binding.pxlPhotoRecyclerView == null) return - val cellSize = pxlPhotoRecyclerView.measuredHeight / 2 + val cellSize = binding.pxlPhotoRecyclerView.measuredHeight / 2 startList(cellSize) - pxlPhotoRecyclerView.viewTreeObserver.removeOnGlobalLayoutListener(this) + binding.pxlPhotoRecyclerView.viewTreeObserver.removeOnGlobalLayoutListener(this) } catch (e: Exception) { e.printStackTrace() } @@ -126,7 +130,7 @@ class PXLPhotoViewInRecyclerViewFragment : BaseFragment() { list.add(PhotoWithImageScaleType(pxlPhoto, generateConfiguration(ImageScaleType.FIT_CENTER), 600.px.toInt())) } - pxlPhotoRecyclerView.replaceList(list) + binding.pxlPhotoRecyclerView.replaceList(list) } else { val pxlPhotos = arguments?.getParcelableArrayList("pxlPhotos") pxlPhotos?.also { @@ -139,7 +143,7 @@ class PXLPhotoViewInRecyclerViewFragment : BaseFragment() { list.add(PhotoWithImageScaleType(it, generateConfiguration(ImageScaleType.CENTER_CROP), cellSize)) } - pxlPhotoRecyclerView.replaceList(list) + binding.pxlPhotoRecyclerView.replaceList(list) // customize the cell height // pxlPhotoRecyclerView.replaceList(it.toList(), ImageScaleType.FIT_CENTER, 600.px.toInt()) @@ -150,12 +154,12 @@ class PXLPhotoViewInRecyclerViewFragment : BaseFragment() { override fun onResume() { super.onResume() - pxlPhotoRecyclerView.playVideoOnResume() + binding.pxlPhotoRecyclerView.playVideoOnResume() } override fun onStop() { super.onStop() - pxlPhotoRecyclerView.stopVideoOnPause() + binding.pxlPhotoRecyclerView.stopVideoOnPause() } companion object { diff --git a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/widgets/ViewerActivity.kt b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/widgets/ViewerActivity.kt index ba50159f..db3097fa 100644 --- a/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/widgets/ViewerActivity.kt +++ b/app/src/main/java/com/pixlee/pixleeandroidsdk/ui/widgets/ViewerActivity.kt @@ -11,6 +11,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope import com.pixlee.pixleeandroidsdk.R +import com.pixlee.pixleeandroidsdk.databinding.ActivityViewerBinding import com.pixlee.pixleesdk.data.PXLPhoto import com.pixlee.pixleesdk.network.observer.AnalyticsObserver import com.pixlee.pixleesdk.ui.viewholder.PhotoWithVideoInfo @@ -21,7 +22,6 @@ import com.pixlee.pixleesdk.ui.widgets.PXLPhotoProductView import com.pixlee.pixleesdk.ui.widgets.TextStyle import com.pixlee.pixleesdk.util.PXLViewUtil import com.pixlee.pixleesdk.util.px -import kotlinx.android.synthetic.main.activity_viewer.* import kotlinx.coroutines.launch import java.util.* @@ -32,15 +32,23 @@ import java.util.* * This shows how to play the video and its product list */ class ViewerActivity : AppCompatActivity() { + override fun onDestroy() { + super.onDestroy() + _binding = null + } + private var _binding: ActivityViewerBinding? = null + private val binding get() = _binding!! + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_viewer) + _binding = ActivityViewerBinding.inflate(layoutInflater) + setContentView(binding.root) // set a full screen mode PXLViewUtil.expandContentAreaOverStatusBar(this) // give a padding to the top as much as the status bar's height - pxlPhotoProductView.addPaddingToHeader(0, PXLViewUtil.getStatusBarHeight(this), 0, 0) + binding.pxlPhotoProductView.addPaddingToHeader(0, PXLViewUtil.getStatusBarHeight(this), 0, 0) val i = intent if (i == null) { @@ -61,7 +69,7 @@ class ViewerActivity : AppCompatActivity() { fun init(item: PhotoWithVideoInfo) { item.configuration.imageScaleType = ImageScaleType.FIT_CENTER // set your ui settings - pxlPhotoProductView + binding.pxlPhotoProductView .setContent(photoInfo = item, showHotspots = true, headerConfiguration = PXLPhotoProductView.Configuration().apply { @@ -175,7 +183,7 @@ class ViewerActivity : AppCompatActivity() { fun listenAnalyticsForInstrumentTesting() { lifecycleScope.launch { - AnalyticsObserver.observe("Obsev.ViewerActivity", tvDebugTextViewer) + AnalyticsObserver.observe("Obsev.ViewerActivity", binding.tvDebugTextViewer) } } diff --git a/app/src/main/res/layout/fragment_analytics.xml b/app/src/main/res/layout/fragment_analytics.xml index 3d2f5009..71f42819 100644 --- a/app/src/main/res/layout/fragment_analytics.xml +++ b/app/src/main/res/layout/fragment_analytics.xml @@ -257,7 +257,7 @@ android:layout_gravity="end" android:fitsSystemWindows="false"> - + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_gallery.xml b/app/src/main/res/layout/fragment_gallery.xml index 78c7b3ee..f5078793 100644 --- a/app/src/main/res/layout/fragment_gallery.xml +++ b/app/src/main/res/layout/fragment_gallery.xml @@ -80,7 +80,7 @@ android:layout_gravity="end" android:fitsSystemWindows="false"> - + diff --git a/app/src/main/res/layout/fragment_ktx_gallery_grid.xml b/app/src/main/res/layout/fragment_ktx_gallery_grid.xml index 880eb77d..7c17fa5d 100644 --- a/app/src/main/res/layout/fragment_ktx_gallery_grid.xml +++ b/app/src/main/res/layout/fragment_ktx_gallery_grid.xml @@ -72,7 +72,7 @@ android:layout_gravity="end" android:fitsSystemWindows="false"> - + diff --git a/app/src/main/res/layout/fragment_ktx_gallery_list.xml b/app/src/main/res/layout/fragment_ktx_gallery_list.xml index 4201ebdb..54db444c 100644 --- a/app/src/main/res/layout/fragment_ktx_gallery_list.xml +++ b/app/src/main/res/layout/fragment_ktx_gallery_list.xml @@ -91,7 +91,7 @@ android:layout_gravity="end" android:fitsSystemWindows="false"> - + diff --git a/app/src/main/res/layout/module_search.xml b/app/src/main/res/layout/module_search.xml index 7c6f7091..d90b50c7 100644 --- a/app/src/main/res/layout/module_search.xml +++ b/app/src/main/res/layout/module_search.xml @@ -40,8 +40,8 @@ android:layout_width="?attr/actionBarSize" android:layout_height="?attr/actionBarSize" android:background="?attr/selectableItemBackgroundBorderless" - android:tint="@color/red_500" - android:src="@drawable/ic_close" /> + android:src="@drawable/ic_close" + app:tint="@color/red_500" /> diff --git a/build.gradle b/build.gradle index 30856e2f..c60081f0 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ buildscript { ext.kotlin_version = '1.5.20' - ext.coroutines = "1.3.1" + ext.coroutines = "1.5.0" repositories { google() mavenCentral() @@ -8,8 +8,6 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:7.0.4' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files } } @@ -17,6 +15,7 @@ allprojects { repositories { google() mavenCentral() + maven { url "https://jitpack.io" } } } @@ -38,20 +37,20 @@ ext { androidxFragmentVersion = "1.1.0-rc01" coreVersion = "1.3.1-alpha02" - extJUnitVersion = "1.1.2" + extJUnitVersion = "1.1.3" runnerVersion = "1.3.1-alpha02" espressoVersion = "3.4.0-alpha02" robolectricVersion = "4.5-alpha-1" jakeWhartonOkhttpOdlingResource = "1.0.0" - androidxAppcompat = "1.2.0" - androidxConstraint = "2.0.1" - material = "1.2.1" + androidxAppcompat = "1.4.1" + androidxConstraint = "2.1.3" + material = "1.5.0" - lifecycle = "2.2.0" + lifecycle = "2.4.0" retrofit2 = "2.9.0" - okhttp3 = "4.8.0" + okhttp3 = "4.9.2" moshi = "1.9.2" rxJava = "2.2.8" rxAndroid = "2.1.1" @@ -61,8 +60,13 @@ ext { lottie = "3.4.1" androidJZVideo="1.0.8" - checkerframeworkVersion = '3.3.0' + checkerframeworkVersion = '3.13.0' exoPlayer="2.16.1" supportLibraryVersion = '27.0.0' jackson = '2.10.3' + junit = '4.13.2' + androidxRunner = '1.4.0' + androidXrules = '1.4.0' + + recyclerview = '1.2.1' } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index d100ac49..c1278888 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,4 +15,9 @@ android.enableJetifier=true # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true +org.gradle.parallel=true + + +COMPILE_SDK_VERSION=31 +TARGET_SDK_VERSION=30 +MIN_SDK_VERSION=21 \ No newline at end of file diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 00000000..0e082489 --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,6 @@ +# configuration file for building snapshots and releases with jitpack.io +jdk: + - openjdk11 +before_install: + - sdk install java 11.0.10-open + - sdk use java 11.0.10-open \ No newline at end of file diff --git a/pixleesdk/build.gradle b/pixleesdk/build.gradle index 0b9e4942..54393e62 100644 --- a/pixleesdk/build.gradle +++ b/pixleesdk/build.gradle @@ -1,32 +1,35 @@ -apply plugin: 'com.android.library' -apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' -apply plugin: 'kotlin-kapt' - -androidExtensions { - experimental = true +plugins { + id 'com.android.library' + id 'kotlin-android' + id 'kotlin-kapt' + id 'kotlin-parcelize' + id 'maven-publish' } android { - compileSdkVersion 31 + compileSdkVersion COMPILE_SDK_VERSION as int defaultConfig { - minSdkVersion 16 - targetSdkVersion 30 + minSdkVersion MIN_SDK_VERSION as int + targetSdkVersion TARGET_SDK_VERSION as int testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } + buildFeatures { + viewBinding true + } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = JavaVersion.VERSION_1_8.toString() + jvmTarget = JavaVersion.VERSION_11.toString() } testOptions { // unitTests.returnDefaultValues = true @@ -41,6 +44,11 @@ android { } } } + + packagingOptions { + exclude 'META-INF/AL2.0' + exclude 'META-INF/LGPL2.1' + } } dependencies { @@ -49,12 +57,12 @@ dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines" - implementation 'androidx.core:core-ktx:1.3.2' + implementation 'androidx.core:core-ktx:1.7.0' /** * testing */ - testImplementation 'junit:junit:4.12' + testImplementation "junit:junit:$junit" testImplementation 'org.json:json:20200518' androidTestImplementation "com.fasterxml.jackson.core:jackson-databind:$jackson" androidTestImplementation 'androidx.test.ext:junit-ktx:' + rootProject.extJUnitVersion @@ -108,5 +116,16 @@ dependencies { implementation "com.google.android.exoplayer:extension-ima:$exoPlayer" implementation "com.google.android.exoplayer:extension-cronet:$exoPlayer" - implementation 'androidx.annotation:annotation:1.1.0' + implementation 'androidx.annotation:annotation:1.3.0' } + +afterEvaluate { + publishing { + publications { + release(MavenPublication) { + from components.release + + } + } + } +} \ No newline at end of file diff --git a/pixleesdk/src/main/java/com/pixlee/pixleesdk/data/PXLProduct.java b/pixleesdk/src/main/java/com/pixlee/pixleesdk/data/PXLProduct.java index 243c78be..cba52710 100644 --- a/pixleesdk/src/main/java/com/pixlee/pixleesdk/data/PXLProduct.java +++ b/pixleesdk/src/main/java/com/pixlee/pixleesdk/data/PXLProduct.java @@ -2,6 +2,7 @@ import android.os.Parcel; import android.os.Parcelable; +import android.util.Log; import com.pixlee.pixleesdk.network.annotation.FieldBigDecimal; import com.pixlee.pixleesdk.network.annotation.FieldDate; @@ -77,7 +78,6 @@ public boolean hasAvailableSalesPrice() { } else if (salesStartDate != null && salesEndDate != null) { isWithinSalesDateRange = salesStartDate.getTime() <= today.getTime() && salesEndDate.getTime() >= today.getTime(); } - return salesPriceLessThanStandard && isWithinSalesDateRange; } diff --git a/pixleesdk/src/main/java/com/pixlee/pixleesdk/network/annotation/FieldBigDecimal.java b/pixleesdk/src/main/java/com/pixlee/pixleesdk/network/annotation/FieldBigDecimal.java index bbb41465..71c5d5c4 100644 --- a/pixleesdk/src/main/java/com/pixlee/pixleesdk/network/annotation/FieldBigDecimal.java +++ b/pixleesdk/src/main/java/com/pixlee/pixleesdk/network/annotation/FieldBigDecimal.java @@ -9,5 +9,5 @@ @Retention(RetentionPolicy.RUNTIME) @JsonQualifier public @interface FieldBigDecimal { - BigDecimal NONE = new BigDecimal(0); + BigDecimal NONE = null; } \ No newline at end of file diff --git a/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/adapter/PXLPhotoAdapter.kt b/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/adapter/PXLPhotoAdapter.kt index 3fdfc79b..d19c5561 100644 --- a/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/adapter/PXLPhotoAdapter.kt +++ b/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/adapter/PXLPhotoAdapter.kt @@ -10,8 +10,6 @@ import com.pixlee.pixleesdk.ui.viewholder.PhotoWithImageScaleType import com.pixlee.pixleesdk.ui.viewholder.TextHeaderViewHolder import com.pixlee.pixleesdk.ui.widgets.TextViewStyle import com.pixlee.pixleesdk.ui.widgets.list.ListHeader -import kotlinx.android.synthetic.main.item_load_more.* -import kotlinx.android.synthetic.main.item_pxlphoto.* /** * This is to display PhotoWithImageScaleType having PXLPhoto in a RecyclerView. @@ -61,7 +59,7 @@ class PXLPhotoAdapter( } val data = item as Item.Header - holder.bind(data.listHeader) + holder.setData(data.listHeader) holder.itemView.setOnClickListener(null) } is PXLPhotoViewHolder -> { @@ -70,7 +68,7 @@ class PXLPhotoAdapter( } val data = item as Item.Content - holder.bind(data.data, showingDebugView) + holder.setData(data.data, showingDebugView) holder.itemView.setOnClickListener { onPhotoClickedListener?.also { it(holder.itemView, data.data) @@ -78,9 +76,9 @@ class PXLPhotoAdapter( } if (onButtonClickedListener == null) { - holder.pxlPhotoView.setButtonClickListener(null) + holder.binding.pxlPhotoView.setButtonClickListener(null) } else { - holder.pxlPhotoView.setButtonClickListener(View.OnClickListener { + holder.binding.pxlPhotoView.setButtonClickListener(View.OnClickListener { onButtonClickedListener?.also { it(holder.itemView, data.data) } @@ -89,8 +87,8 @@ class PXLPhotoAdapter( } is LoadMoreViewHolder -> { val data = item as Item.LoadMore - holder.bind(data) - holder.tvLoadMore.setOnClickListener { + holder.setData(data) + holder.binding.tvLoadMore.setOnClickListener { onLoadMoreClickedListener?.also { it() } diff --git a/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/adapter/ProductAdapter.kt b/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/adapter/ProductAdapter.kt index f92134dd..32007f0c 100644 --- a/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/adapter/ProductAdapter.kt +++ b/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/adapter/ProductAdapter.kt @@ -5,7 +5,6 @@ import androidx.recyclerview.widget.RecyclerView import com.pixlee.pixleesdk.data.PXLProduct import com.pixlee.pixleesdk.ui.viewholder.ProductViewHolder import com.pixlee.pixleesdk.ui.viewholder.ProductViewHolder.Companion.create -import kotlinx.android.synthetic.main.item_product.* import java.util.* /** @@ -32,18 +31,18 @@ class ProductAdapter( }else{ holder.bind(product, null, configuration) } - holder.bookmark.setOnClickListener { - val productId = list[holder.adapterPosition].id + holder.binding.bookmark.setOnClickListener { + val productId = list[holder.bindingAdapterPosition].id bookmarkMap?.also { val bookmarked = it[productId] ?: false it[productId] = !bookmarked - onBookmarkChanged(list[holder.adapterPosition].id, !bookmarked) + onBookmarkChanged(list[holder.bindingAdapterPosition].id, !bookmarked) holder.changeBookmarkUI(!bookmarked, configuration.bookmarkDrawable) } } holder.itemView.setOnClickListener { - onItemClicked(list[holder.adapterPosition]) + onItemClicked(list[holder.bindingAdapterPosition]) } } diff --git a/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/viewholder/LoadMoreViewHolder.kt b/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/viewholder/LoadMoreViewHolder.kt index dde435fc..c12ee016 100644 --- a/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/viewholder/LoadMoreViewHolder.kt +++ b/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/viewholder/LoadMoreViewHolder.kt @@ -4,39 +4,36 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import com.pixlee.pixleesdk.R +import com.pixlee.pixleesdk.databinding.ItemLoadMoreBinding import com.pixlee.pixleesdk.ui.adapter.PXLPhotoAdapter import com.pixlee.pixleesdk.ui.widgets.setTextViewStyle -import kotlinx.android.extensions.LayoutContainer -import kotlinx.android.synthetic.main.item_load_more.* /** * This is to display Header in the grid list. * You can set the header using either ListHeader.Gif(gif) or ListHeader.SpannableText(text) */ -class LoadMoreViewHolder(override val containerView: View) : - RecyclerView.ViewHolder(containerView), - LayoutContainer { +class LoadMoreViewHolder(val binding: ItemLoadMoreBinding) : + RecyclerView.ViewHolder(binding.root) { - fun bind(loadMore: PXLPhotoAdapter.Item.LoadMore) { - tvLoadMore.setTextViewStyle(loadMore.loadMoreTextViewStyle) + fun setData(loadMore: PXLPhotoAdapter.Item.LoadMore) { + binding.tvLoadMore.setTextViewStyle(loadMore.loadMoreTextViewStyle) when(loadMore.loading){ true -> { - tvLoadMore.visibility = View.INVISIBLE - tvLoadMore.isEnabled = false - lottieView.visibility = View.VISIBLE + binding.tvLoadMore.visibility = View.INVISIBLE + binding.tvLoadMore.isEnabled = false + binding.lottieView.visibility = View.VISIBLE } false -> { - tvLoadMore.visibility = View.VISIBLE - tvLoadMore.isEnabled = true - lottieView.visibility = View.GONE + binding.tvLoadMore.visibility = View.VISIBLE + binding.tvLoadMore.isEnabled = true + binding.lottieView.visibility = View.GONE } } } companion object { fun create(parent: ViewGroup): LoadMoreViewHolder { - return LoadMoreViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_load_more, parent, false)) + return LoadMoreViewHolder(ItemLoadMoreBinding.inflate(LayoutInflater.from(parent.context), parent, false)) } } } \ No newline at end of file diff --git a/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/viewholder/PXLPhotoViewHolder.kt b/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/viewholder/PXLPhotoViewHolder.kt index f58fa736..f3c76cb6 100644 --- a/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/viewholder/PXLPhotoViewHolder.kt +++ b/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/viewholder/PXLPhotoViewHolder.kt @@ -5,40 +5,36 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import com.pixlee.pixleesdk.R import com.pixlee.pixleesdk.data.PXLPhoto -import com.pixlee.pixleesdk.ui.widgets.ImageScaleType +import com.pixlee.pixleesdk.databinding.ItemPxlphotoBinding import com.pixlee.pixleesdk.ui.widgets.PXLPhotoView import com.pixlee.pixleesdk.util.px -import kotlinx.android.extensions.LayoutContainer import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.item_pxlphoto.* /** * This is to display PhotoWithImageScaleType having PXLPhoto as a RecyclerView.ViewHolder. * This shows its content(photo/video). Via PXLPhotoView.Configuration, you can custom TextViews and a Button. */ -class PXLPhotoViewHolder(override val containerView: View) : - RecyclerView.ViewHolder(containerView), - LayoutContainer { +class PXLPhotoViewHolder(val binding: ItemPxlphotoBinding) : + RecyclerView.ViewHolder(binding.root) { - fun bind(data: PhotoWithImageScaleType, showingDebugView: Boolean = false) { - pxlPhotoView.layoutParams.height = data.heightInPixel - pxlPhotoView.setConfiguration(configuration = data.configuration) - pxlPhotoView.setContent(data.pxlPhoto, data.configuration.imageScaleType) - pxlPhotoView.setLooping(data.isLoopingVideo) - pxlPhotoView.changeVolume(if(data.soundMuted) 0f else 1f) + fun setData(data: PhotoWithImageScaleType, showingDebugView: Boolean = false) { + binding.pxlPhotoView.layoutParams.height = data.heightInPixel + binding.pxlPhotoView.setConfiguration(configuration = data.configuration) + binding.pxlPhotoView.setContent(data.pxlPhoto, data.configuration.imageScaleType) + binding.pxlPhotoView.setLooping(data.isLoopingVideo) + binding.pxlPhotoView.changeVolume(if(data.soundMuted) 0f else 1f) - tv.visibility = if (showingDebugView) View.VISIBLE else View.GONE - tvPercent.visibility = if (showingDebugView) View.VISIBLE else View.GONE - tv.text = "ScaleType: ${data.configuration.imageScaleType.name}\nwidth: ${pxlPhotoView.layoutParams.width}, height: ${pxlPhotoView.layoutParams.height}\nid: ${data.pxlPhoto.id}" + binding.tv.visibility = if (showingDebugView) View.VISIBLE else View.GONE + binding.tvPercent.visibility = if (showingDebugView) View.VISIBLE else View.GONE + binding.tv.text = "ScaleType: ${data.configuration.imageScaleType.name}\nwidth: ${binding.pxlPhotoView.layoutParams.width}, height: ${binding.pxlPhotoView.layoutParams.height}\nid: ${data.pxlPhoto.id}" } companion object { fun create(parent: ViewGroup): PXLPhotoViewHolder { - val view = LayoutInflater.from(parent.context).inflate(R.layout.item_pxlphoto, parent, false) - val holder = PXLPhotoViewHolder(view) - view.setTag(holder) + val binding = ItemPxlphotoBinding.inflate(LayoutInflater.from(parent.context), parent, false) + val holder = PXLPhotoViewHolder(binding) + //binding.root.setTag(holder) return holder } } diff --git a/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/viewholder/ProductViewHolder.kt b/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/viewholder/ProductViewHolder.kt index f45ffc1c..3fcede2e 100644 --- a/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/viewholder/ProductViewHolder.kt +++ b/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/viewholder/ProductViewHolder.kt @@ -20,6 +20,8 @@ import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.pixlee.pixleesdk.R import com.pixlee.pixleesdk.data.PXLProduct +import com.pixlee.pixleesdk.databinding.ItemProductBinding +import com.pixlee.pixleesdk.databinding.ItemPxlphotoBinding import com.pixlee.pixleesdk.ui.widgets.CurrencyTextStyle import com.pixlee.pixleesdk.ui.widgets.TextStyle import com.pixlee.pixleesdk.ui.widgets.setTextStyle @@ -27,8 +29,6 @@ import com.pixlee.pixleesdk.util.ExtendedCurrency import com.pixlee.pixleesdk.util.getFractionalPart import com.pixlee.pixleesdk.util.px import com.pixlee.pixleesdk.util.setCompatColorFilter -import kotlinx.android.extensions.LayoutContainer -import kotlinx.android.synthetic.main.item_product.* import java.math.BigDecimal import java.text.DecimalFormat @@ -36,7 +36,7 @@ import java.text.DecimalFormat /** * This is to display PXLProduct as a RecyclerView.ViewHolder */ -class ProductViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView), LayoutContainer { +class ProductViewHolder(val binding: ItemProductBinding) : RecyclerView.ViewHolder(binding.root) { data class Configuration( var mainTextStyle: TextStyle? = null, var subTextStyle: TextStyle? = null, @@ -82,19 +82,19 @@ class ProductViewHolder(override val containerView: View) : RecyclerView.ViewHol var formatter = DecimalFormat("#,##0.##") fun bind(product: PXLProduct, isBookmarked: Boolean?, configuration: Configuration) { // product image UI - Glide.with(imageView.context) + Glide.with(binding.imageView.context) .load(product.imageThumb) .fitCenter() - .into(imageView) + .into(binding.imageView) // main text UI - configuration.mainTextStyle?.also { tvMain.setTextStyle(it) } - tvMain.text = product.title + configuration.mainTextStyle?.also { binding.tvMain.setTextStyle(it) } + binding.tvMain.text = product.title // sub text UI - configuration.subTextStyle?.also { tvMain.setTextStyle(it) } - tvSub.visibility = if (product.description != null && product.description.isNotEmpty()) View.VISIBLE else View.INVISIBLE - tvSub.text = product.description + configuration.subTextStyle?.also { binding.tvMain.setTextStyle(it) } + binding.tvSub.visibility = if (product.description != null && product.description.isNotEmpty()) View.VISIBLE else View.INVISIBLE + binding.tvSub.text = product.description // price UI (product.price ?: 0.toBigDecimal()).let { price -> @@ -133,7 +133,7 @@ class ProductViewHolder(override val containerView: View) : RecyclerView.ViewHol // add was_old_price if needed if (!noSalesPrice && discountLayout != null && discountLayout == DiscountLayout.WAS_OLD_PRICE) { - defaultPrice.integerPrice = tvPrice.context.getString(R.string.was_old_price, defaultPrice.integerPrice) + defaultPrice.integerPrice = binding.tvPrice.context.getString(R.string.was_old_price, defaultPrice.integerPrice) } val defaultPriceString = "${defaultPrice.integerPrice}${defaultPrice.decimalPrice}" @@ -142,7 +142,7 @@ class ProductViewHolder(override val containerView: View) : RecyclerView.ViewHol val total = if (!noSalesPrice && discountLayout != null) { val discountPercentage = product.getDiscountPercentage() offLabel = if (discountLayout == DiscountLayout.WITH_DISCOUNT_LABEL && discountPercentage != null) { - " ${tvSub.context.getString(R.string.percent_off, "$discountPercentage")}" + " ${binding.tvSub.context.getString(R.string.percent_off, "$discountPercentage")}" } else { "" } @@ -152,8 +152,8 @@ class ProductViewHolder(override val containerView: View) : RecyclerView.ViewHol } // set the string to the UI with customized size and color - tvPrice.text = SpannableString(total).apply { - val metrics = tvSub.context.resources.displayMetrics + binding.tvPrice.text = SpannableString(total).apply { + val metrics = binding.tvSub.context.resources.displayMetrics var newIndex = 0 // Draw integer sales price @@ -210,19 +210,19 @@ class ProductViewHolder(override val containerView: View) : RecyclerView.ViewHol } // bookmark UI - bookmark.visibility = if (configuration.bookmarkDrawable != null) View.VISIBLE else View.GONE + binding.bookmark.visibility = if (configuration.bookmarkDrawable != null) View.VISIBLE else View.GONE if (isBookmarked != null && configuration.bookmarkDrawable != null) { changeBookmarkUI(isBookmarked, configuration.bookmarkDrawable) } // shop image UI - iconBox.visibility = if (configuration.circleIcon != null) View.VISIBLE else View.GONE + binding.iconBox.visibility = if (configuration.circleIcon != null) View.VISIBLE else View.GONE configuration.circleIcon?.let { - iconBox.background = getDrawable(it) - iconBox.setPadding(it.padding, it.padding, it.padding, it.padding) - ivIcon.setBackgroundResource(it.icon) - ivIcon.setCompatColorFilter(it.iconColor) + binding.iconBox.background = getDrawable(it) + binding.iconBox.setPadding(it.padding, it.padding, it.padding, it.padding) + binding.ivIcon.setBackgroundResource(it.icon) + binding.ivIcon.setCompatColorFilter(it.iconColor) } } @@ -237,16 +237,16 @@ class ProductViewHolder(override val containerView: View) : RecyclerView.ViewHol fun changeBookmarkUI(isBookmarked: Boolean, bookmarkDrawable: Bookmark?) { bookmarkDrawable?.let { - bookmark.setBackgroundResource(when (isBookmarked) { + binding.bookmark.setBackgroundResource(when (isBookmarked) { false -> it.unselectedIcon true -> it.selectedIcon }) val filter = it.filterColor if (filter == null) { - bookmark.setCompatColorFilter(null) + binding.bookmark.setCompatColorFilter(null) } else { - bookmark.setCompatColorFilter(when (isBookmarked) { + binding.bookmark.setCompatColorFilter(when (isBookmarked) { false -> filter.unselectedColor true -> filter.selectedColor }) @@ -257,7 +257,7 @@ class ProductViewHolder(override val containerView: View) : RecyclerView.ViewHol companion object { fun create(parent: ViewGroup): ProductViewHolder { - return ProductViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_product, parent, false)) + return ProductViewHolder(ItemProductBinding.inflate(LayoutInflater.from(parent.context), parent, false)) } } } diff --git a/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/viewholder/TextHeaderViewHolder.kt b/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/viewholder/TextHeaderViewHolder.kt index 83231d22..6cf3e59c 100644 --- a/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/viewholder/TextHeaderViewHolder.kt +++ b/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/viewholder/TextHeaderViewHolder.kt @@ -1,55 +1,50 @@ package com.pixlee.pixleesdk.ui.viewholder import android.view.LayoutInflater -import android.view.View import android.view.View.GONE import android.view.View.VISIBLE import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide -import com.pixlee.pixleesdk.R +import com.pixlee.pixleesdk.databinding.ItemHeaderBinding import com.pixlee.pixleesdk.ui.widgets.ImageScaleType import com.pixlee.pixleesdk.ui.widgets.list.ListHeader -import kotlinx.android.extensions.LayoutContainer -import kotlinx.android.synthetic.main.item_header.* /** * This is to display Header in the grid list. * You can set the header using either ListHeader.Gif(gif) or ListHeader.SpannableText(text) */ -class TextHeaderViewHolder(override val containerView: View) : - RecyclerView.ViewHolder(containerView), - LayoutContainer { +class TextHeaderViewHolder(val binding: ItemHeaderBinding) : RecyclerView.ViewHolder(binding.root) { - fun bind(listHeader: ListHeader) { + fun setData(listHeader: ListHeader) { when(listHeader){ is ListHeader.Gif -> { - ivHeader.layoutParams.height = listHeader.heightInPixel + binding.ivHeader.layoutParams.height = listHeader.heightInPixel - var builder = Glide.with(ivHeader) + var builder = Glide.with(binding.ivHeader) .load(listHeader.url) builder = when (listHeader.imageScaleType) { ImageScaleType.FIT_CENTER -> builder.fitCenter() ImageScaleType.CENTER_CROP -> builder.centerCrop() } - vHeader.setPadding(0, 0, 0, 0) - builder.into(ivHeader) + binding.vHeader.setPadding(0, 0, 0, 0) + builder.into(binding.ivHeader) } is ListHeader.SpannableText -> { - tvHeader.text = listHeader.spannable + binding.tvHeader.text = listHeader.spannable listHeader.padding.apply { - vHeader.setPadding(left, top, right, bottom) + binding.vHeader.setPadding(left, top, right, bottom) } } } - tvHeader.visibility = if(listHeader is ListHeader.SpannableText) VISIBLE else GONE - ivHeader.visibility = if(listHeader is ListHeader.Gif) VISIBLE else GONE + binding.tvHeader.visibility = if(listHeader is ListHeader.SpannableText) VISIBLE else GONE + binding.ivHeader.visibility = if(listHeader is ListHeader.Gif) VISIBLE else GONE } companion object { fun create(parent: ViewGroup): TextHeaderViewHolder { - return TextHeaderViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_header, parent, false)) + return TextHeaderViewHolder(ItemHeaderBinding.inflate(LayoutInflater.from(parent.context), parent, false)) } } } \ No newline at end of file diff --git a/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/widgets/PXLPhotoProductView.kt b/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/widgets/PXLPhotoProductView.kt index 367e5557..d6f3e408 100644 --- a/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/widgets/PXLPhotoProductView.kt +++ b/pixleesdk/src/main/java/com/pixlee/pixleesdk/ui/widgets/PXLPhotoProductView.kt @@ -33,6 +33,7 @@ import com.pixlee.pixleesdk.R import com.pixlee.pixleesdk.client.PXLAnalytics import com.pixlee.pixleesdk.client.PXLClient import com.pixlee.pixleesdk.data.PXLProduct +import com.pixlee.pixleesdk.databinding.WidgetViewerBinding import com.pixlee.pixleesdk.enums.PXLPhotoSize import com.pixlee.pixleesdk.ui.adapter.ProductAdapter import com.pixlee.pixleesdk.ui.viewholder.PhotoWithVideoInfo @@ -40,7 +41,6 @@ import com.pixlee.pixleesdk.ui.viewholder.ProductViewHolder import com.pixlee.pixleesdk.util.HotspotsReader import com.pixlee.pixleesdk.util.px import com.pixlee.pixleesdk.util.setCompatIconWithColor -import kotlinx.android.synthetic.main.widget_viewer.view.* import kotlinx.coroutines.* import java.util.* @@ -96,10 +96,12 @@ class PXLPhotoProductView : FrameLayout, LifecycleObserver { initView(context) } + lateinit var binding: WidgetViewerBinding private fun initView(context: Context) { val li = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater - val view = li.inflate(R.layout.widget_viewer, this, false) - addView(view) + val binding = WidgetViewerBinding.inflate(li, this, false) + this.binding = binding + addView(binding.root) val lifecycleOwner = context as? LifecycleOwner ?: throw Exception("androidx.lifecycle.LifecycleOwner is required. Please make sure your Activity or Fragment provides androidx.lifecycle.LifecycleOwner") @@ -133,10 +135,10 @@ class PXLPhotoProductView : FrameLayout, LifecycleObserver { initHeader(headerConfiguration) loadProducts(configuration) - pxlPhotoView.setConfiguration(configuration = PXLPhotoView.Configuration(pxlPhotoSize = photoInfo.configuration.pxlPhotoSize)) - pxlPhotoView.setContent(photoInfo.pxlPhoto, photoInfo.configuration.imageScaleType) - pxlPhotoView.setLooping(photoInfo.isLoopingVideo) - pxlPhotoView.changeVolume(if (photoInfo.soundMuted) 0f else 1f) + binding.pxlPhotoView.setConfiguration(configuration = PXLPhotoView.Configuration(pxlPhotoSize = photoInfo.configuration.pxlPhotoSize)) + binding.pxlPhotoView.setContent(photoInfo.pxlPhoto, photoInfo.configuration.imageScaleType) + binding.pxlPhotoView.setLooping(photoInfo.isLoopingVideo) + binding.pxlPhotoView.changeVolume(if (photoInfo.soundMuted) 0f else 1f) addHotspots() @@ -147,20 +149,20 @@ class PXLPhotoProductView : FrameLayout, LifecycleObserver { private var headerConfiguration: Configuration? = null private fun initHeader(headerConfiguration: Configuration) { this.headerConfiguration = headerConfiguration - vBack.visibility = if (headerConfiguration.backButton != null) View.VISIBLE else View.GONE + binding.vBack.visibility = if (headerConfiguration.backButton != null) View.VISIBLE else View.GONE headerConfiguration.backButton?.apply { - vBack.setOnClickListener { onClickListener?.let { it() } } - vBack.background = GradientDrawable().apply { + binding.vBack.setOnClickListener { onClickListener?.let { it() } } + binding.vBack.background = GradientDrawable().apply { shape = android.graphics.drawable.GradientDrawable.OVAL setColor(backgroundColor) } - vBack.setPadding(padding, padding, padding, padding) - ivBack.setCompatIconWithColor(iconColor, icon) + binding.vBack.setPadding(padding, padding, padding, padding) + binding.ivBack.setCompatIconWithColor(iconColor, icon) } - vMute.visibility = if (headerConfiguration.muteCheckBox != null && photoInfo?.pxlPhoto?.isVideo ?: false) View.VISIBLE else View.GONE + binding.vMute.visibility = if (headerConfiguration.muteCheckBox != null && photoInfo?.pxlPhoto?.isVideo ?: false) View.VISIBLE else View.GONE headerConfiguration.muteCheckBox?.apply { - vMute.setOnClickListener { + binding.vMute.setOnClickListener { if (isMutted) { unmute() } else { @@ -168,11 +170,11 @@ class PXLPhotoProductView : FrameLayout, LifecycleObserver { } onCheckedListener?.let { it1 -> it1(isMutted) } } - vMute.background = GradientDrawable().apply { + binding.vMute.background = GradientDrawable().apply { shape = android.graphics.drawable.GradientDrawable.OVAL setColor(backgroundColor) } - vMute.setPadding(padding, padding, padding, padding) + binding.vMute.setPadding(padding, padding, padding, padding) setMuteIcon(isMutted) } } @@ -182,7 +184,7 @@ class PXLPhotoProductView : FrameLayout, LifecycleObserver { * The content will not be affected by this padding because the header area and the content are not related in a ViewGroup. */ fun addPaddingToHeader(left: Int, top: Int, right: Int, bottom: Int) { - headerView.setPadding(left, top, right, bottom) + binding.headerView.setPadding(left, top, right, bottom) } private fun loadProducts(configuration: ProductViewHolder.Configuration) { @@ -203,8 +205,8 @@ class PXLPhotoProductView : FrameLayout, LifecycleObserver { - recyclerView.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) - recyclerView.adapter = adapter + binding.recyclerView.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) + binding.recyclerView.adapter = adapter } } } @@ -223,20 +225,20 @@ class PXLPhotoProductView : FrameLayout, LifecycleObserver { } // since this is run after the delay run on a background thread, v_hotspots could be null. so null check is essential. - if (v_hotspots == null) return@launch + if (binding.vHotspots == null) return@launch - if (v_hotspots.childCount > 0) { + if (binding.vHotspots.childCount > 0) { // remove all child views if this is not the first trial - v_hotspots.removeAllViews() + binding.vHotspots.removeAllViews() } - v_hotspots.setOnClickListener { + binding.vHotspots.setOnClickListener { hiddenHotspots = !hiddenHotspots val visibility = if (hiddenHotspots) GONE else VISIBLE - val childCount = v_hotspots.childCount + val childCount = binding.vHotspots.childCount if (childCount > 0) { for (i in 0 until childCount) { - v_hotspots.getChildAt(i).visibility = visibility + binding.vHotspots.getChildAt(i).visibility = visibility } } } @@ -259,11 +261,11 @@ class PXLPhotoProductView : FrameLayout, LifecycleObserver { .load(originalImageUrl) .into(object : SimpleTarget() { override fun onResourceReady(resource: Bitmap, transition: Transition?) { - if (v_hotspots == null) return + if (binding.vHotspots == null) return photoInfo?.configuration?.imageScaleType?.let { imageScaleType -> val reader = HotspotsReader(imageScaleType, - pxlPhotoView.measuredWidth, pxlPhotoView.measuredHeight, + binding.pxlPhotoView.measuredWidth, binding.pxlPhotoView.measuredHeight, resource.width, resource.height ) @@ -289,12 +291,12 @@ class PXLPhotoProductView : FrameLayout, LifecycleObserver { } } - v_hotspots.addView(imageView) + binding.vHotspots.addView(imageView) // on hotspot clicked imageView.setOnClickListener { - if (recyclerView == null) return@setOnClickListener - recyclerView.smoothScrollToPosition(productPosition) + if (binding.recyclerView == null) return@setOnClickListener + binding.recyclerView.smoothScrollToPosition(productPosition) } } @@ -339,13 +341,13 @@ class PXLPhotoProductView : FrameLayout, LifecycleObserver { private fun changeMute(muted: Boolean) { isMutted = muted - pxlPhotoView.changeVolume(if (muted) 0f else 1f) + binding.pxlPhotoView.changeVolume(if (muted) 0f else 1f) setMuteIcon(muted) } private fun setMuteIcon(muted: Boolean) { headerConfiguration?.muteCheckBox?.apply { - ivMute.setCompatIconWithColor(iconColor, if (muted) mutedIcon else unmutedIcon) + binding.ivMute.setCompatIconWithColor(iconColor, if (muted) mutedIcon else unmutedIcon) } } @@ -357,12 +359,12 @@ class PXLPhotoProductView : FrameLayout, LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun playVideoOnResume() { fireAnalyticsOpenLightbox() - pxlPhotoView.playVideo() + binding.pxlPhotoView.playVideo() } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun stopVideoOnPause() { - pxlPhotoView.pauseVideo() + binding.pxlPhotoView.pauseVideo() } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) diff --git a/pixleesdk/src/main/java/com/pixlee/pixleesdk/util/ImageViewExt.kt b/pixleesdk/src/main/java/com/pixlee/pixleesdk/util/ImageViewExt.kt index 80ee52a7..d1dd9f69 100644 --- a/pixleesdk/src/main/java/com/pixlee/pixleesdk/util/ImageViewExt.kt +++ b/pixleesdk/src/main/java/com/pixlee/pixleesdk/util/ImageViewExt.kt @@ -7,9 +7,6 @@ import android.os.Build import android.widget.ImageView import androidx.annotation.ColorInt import androidx.annotation.DrawableRes -import com.pixlee.pixleesdk.ui.viewholder.ProductViewHolder -import kotlinx.android.synthetic.main.item_product.* - /** * Created by sungjun on 9/18/20. diff --git a/simpleapp/build.gradle b/simpleapp/build.gradle index 6ecb12f8..f2a9edeb 100644 --- a/simpleapp/build.gradle +++ b/simpleapp/build.gradle @@ -1,21 +1,18 @@ plugins { id 'com.android.application' id 'kotlin-android' - id 'kotlin-android-extensions' + id 'kotlin-parcelize' } -androidExtensions { - experimental = true -} android { - compileSdkVersion 31 + compileSdkVersion COMPILE_SDK_VERSION as int defaultConfig { multiDexEnabled true applicationId "com.pixlee.pixleeandroidsdk.simple" - minSdkVersion 21 - targetSdkVersion 30 + minSdkVersion MIN_SDK_VERSION as int + targetSdkVersion TARGET_SDK_VERSION as int versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -32,15 +29,16 @@ android { } } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '11' } - viewBinding { - enabled = true + buildFeatures { + viewBinding true } + buildTypes { release { minifyEnabled false @@ -59,15 +57,20 @@ android { } } } + + packagingOptions { + exclude 'META-INF/AL2.0' + exclude 'META-INF/LGPL2.1' + } } dependencies { /** * libraries for app. you don't need to use these */ - testImplementation 'junit:junit:4.13' - androidTestImplementation 'androidx.test:runner:1.3.0' - androidTestImplementation 'androidx.test.ext:junit:' + rootProject.extJUnitVersion + testImplementation "junit:junit:$junit" + androidTestImplementation "androidx.test:runner:$androidxRunner" + androidTestImplementation "androidx.test.ext:junit:$extJUnitVersion" implementation "androidx.appcompat:appcompat:$androidxAppcompat" implementation "androidx.constraintlayout:constraintlayout:$androidxConstraint" implementation "com.google.android.material:material:$material" diff --git a/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/DynamicDemoActivity.kt b/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/DynamicDemoActivity.kt index 20e2ca58..25fe8821 100644 --- a/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/DynamicDemoActivity.kt +++ b/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/DynamicDemoActivity.kt @@ -14,6 +14,7 @@ import android.view.inputmethod.InputMethodManager import androidx.appcompat.app.AppCompatActivity import androidx.core.view.GravityCompat import androidx.drawerlayout.widget.DrawerLayout +import com.pixlee.pixleeandroidsdk.databinding.ActivityDynamicPhotosBinding import com.pixlee.pixleesdk.client.PXLKtxBaseAlbum import com.pixlee.pixleesdk.data.PXLAlbumFilterOptions import com.pixlee.pixleesdk.data.PXLAlbumSortOptions @@ -25,30 +26,38 @@ import com.pixlee.pixleesdk.ui.widgets.PXLPhotoView import com.pixlee.pixleesdk.ui.widgets.TextPadding import com.pixlee.pixleesdk.ui.widgets.TextViewStyle import com.pixlee.pixleesdk.ui.widgets.list.ListHeader -import com.pixlee.pixleesdk.ui.widgets.list.Space import com.pixlee.pixleesdk.ui.widgets.list.PXLWidgetView +import com.pixlee.pixleesdk.ui.widgets.list.Space import com.pixlee.pixleesdk.util.px -import kotlinx.android.synthetic.main.activity_dynamic_photos.* -import kotlinx.android.synthetic.main.module_search.* /** * Created by sungjun on 3/23/21. */ class DynamicDemoActivity : AppCompatActivity() { + private var _binding: ActivityDynamicPhotosBinding? = null + private val binding get() = _binding!! + + override fun onDestroy() { + super.onDestroy() + _binding = null + } + var cellHeightInPixel = 200.px.toInt() public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_dynamic_photos) + _binding = ActivityDynamicPhotosBinding.inflate(layoutInflater) + setContentView(binding.root) + setFilters() - widget.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { + binding.widget.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { try { - if (widget == null) + if (binding.widget == null) return - cellHeightInPixel = widget.measuredHeight / 2 + cellHeightInPixel = binding.widget.measuredHeight / 2 initiateList() - widget.viewTreeObserver.removeOnGlobalLayoutListener(this) + binding.widget.viewTreeObserver.removeOnGlobalLayoutListener(this) } catch (e: Exception) { e.printStackTrace() } @@ -59,7 +68,7 @@ class DynamicDemoActivity : AppCompatActivity() { private fun initiateList() { // you can customize color, size if you need - widget.initiate( + binding.widget.initiate( widgetTypeForAnalytics = "your_widget_type", // this will be used when this view automatically fires openedWidget, widgetVisible analytics viewType = getViewType(), cellHeightInPixel = cellHeightInPixel, @@ -91,7 +100,7 @@ class DynamicDemoActivity : AppCompatActivity() { } private fun getViewType(): PXLWidgetView.ViewType { - return if (radioGrid.isChecked) { + return if (binding.leftLayout.radioGrid.isChecked) { PXLWidgetView.ViewType.Grid( gridSpan = getGridSpan(), lineSpace = Space(lineWidthInPixel = getLineSpace().px.toInt()), @@ -99,8 +108,8 @@ class DynamicDemoActivity : AppCompatActivity() { ) } else { PXLWidgetView.ViewType.List( - infiniteScroll = radio_infiniteScroll_on.isChecked, - autoPlayVideo = radio_autoPlayVideo_on.isChecked, + infiniteScroll = binding.leftLayout.radioInfiniteScrollOn.isChecked, + autoPlayVideo = binding.leftLayout.radioAutoPlayVideoOn.isChecked, alphaForStoppedVideos = 1f ) } @@ -130,9 +139,9 @@ class DynamicDemoActivity : AppCompatActivity() { } private fun setFilters() { - drawerLayout.setScrimColor(Color.TRANSPARENT) - drawerLayout.drawerElevation = 0f - drawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener { + binding.drawerLayout.setScrimColor(Color.TRANSPARENT) + binding.drawerLayout.drawerElevation = 0f + binding.drawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener { override fun onDrawerSlide(drawerView: View, slideOffset: Float) { } @@ -143,7 +152,7 @@ class DynamicDemoActivity : AppCompatActivity() { override fun onDrawerClosed(drawerView: View) { val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager - imm.hideSoftInputFromWindow(tvLineSpace.windowToken, 0) + imm.hideSoftInputFromWindow(binding.leftLayout.tvLineSpace.windowToken, 0) } override fun onDrawerStateChanged(newState: Int) { @@ -151,53 +160,54 @@ class DynamicDemoActivity : AppCompatActivity() { } }) - fabFilter.setOnClickListener { drawerLayout.openDrawer(GravityCompat.END) } + binding.fabFilter.setOnClickListener { binding.drawerLayout.openDrawer(GravityCompat.END) } + + binding.leftLayout.btnApply.setOnClickListener { binding.drawerLayout.closeDrawer(GravityCompat.END) } + - btnApply.setOnClickListener { drawerLayout.closeDrawer(GravityCompat.END) } - radio_grid.setOnCheckedChangeListener { group, checkedId -> - val viewType = widget.currentViewType + binding.leftLayout.radioGridCount.setOnCheckedChangeListener { group, checkedId -> when (checkedId) { - R.id.radio_grid_2 -> { + binding.leftLayout.radioGridCount2.id -> { changeSpan(2) } - R.id.radio_grid_3 -> { + binding.leftLayout.radioGridCount3.id -> { changeSpan(3) } - R.id.radio_grid_4 -> { + binding.leftLayout.radioGridCount4.id -> { changeSpan(4) } - R.id.radio_grid_5 -> { + binding.leftLayout.radioGridCount5.id -> { changeSpan(5) } } } - radioViewType.setOnCheckedChangeListener { group, checkedId -> - v_grid.visibility = if (R.id.radioGrid == checkedId) View.VISIBLE else View.GONE - v_list.visibility = if (R.id.radioList == checkedId) View.VISIBLE else View.GONE + binding.leftLayout.radioViewType.setOnCheckedChangeListener { group, checkedId -> + binding.leftLayout.vGrid.visibility = if (R.id.radioGrid == checkedId) View.VISIBLE else View.GONE + binding.leftLayout.vList.visibility = if (R.id.radioList == checkedId) View.VISIBLE else View.GONE refreshViewType() changeSpan(getGridSpan()) } - radio_infiniteScroll.setOnCheckedChangeListener { group, checkedId -> + binding.leftLayout.radioInfiniteScroll.setOnCheckedChangeListener { group, checkedId -> changeSpan(getGridSpan()) refreshViewType() - if (radio_infiniteScroll_on.isChecked) { - widget.scrollToPosition(Integer.MAX_VALUE / 2) + if (binding.leftLayout.radioInfiniteScrollOn.isChecked) { + binding.widget.scrollToPosition(Integer.MAX_VALUE / 2) } } - radio_autoPlayVideo.setOnCheckedChangeListener { group, checkedId -> + binding.leftLayout.radioAutoPlayVideo.setOnCheckedChangeListener { group, checkedId -> changeSpan(getGridSpan()) refreshViewType() } - radio_header.setOnCheckedChangeListener { group, checkedId -> + binding.leftLayout.radioHeader.setOnCheckedChangeListener { group, checkedId -> refreshViewType() } - tvLineSpace.addTextChangedListener(object : TextWatcher { + binding.leftLayout.tvLineSpace.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { } @@ -207,8 +217,8 @@ class DynamicDemoActivity : AppCompatActivity() { } override fun afterTextChanged(s: Editable?) { - Log.e("text change", "changed text: ${tvLineSpace.text}") - tvLineSpace.text + Log.e("text change", "changed text: ${binding.leftLayout.tvLineSpace.text}") + binding.leftLayout.tvLineSpace.text refreshViewType() changeSpan(getGridSpan()) } @@ -216,63 +226,63 @@ class DynamicDemoActivity : AppCompatActivity() { } fun changeSpan(span: Int) { - val viewType = widget.currentViewType + val viewType = binding.widget.currentViewType if (viewType is PXLWidgetView.ViewType.Grid) { val allLineSpace = getLineSpace().px.toInt() * (span - 1) - cellHeightInPixel = (widget.measuredWidth - allLineSpace) / span + cellHeightInPixel = (binding.widget.measuredWidth - allLineSpace) / span - widget.currentViewType = viewType.copy().apply { + binding.widget.currentViewType = viewType.copy().apply { gridSpan = span } } else { - cellHeightInPixel = widget.measuredHeight / 2 + cellHeightInPixel = binding.widget.measuredHeight / 2 } - widget.viewModel.cellHeightInPixel = cellHeightInPixel - widget.viewModel.customizedConfiguration.pxlPhotoSize = if (radioList.isChecked) PXLPhotoSize.BIG else PXLPhotoSize.MEDIUM - widget.pxlPhotoAdapter.list.forEach { + binding.widget.viewModel.cellHeightInPixel = cellHeightInPixel + binding.widget.viewModel.customizedConfiguration.pxlPhotoSize = if (binding.leftLayout.radioList.isChecked) PXLPhotoSize.BIG else PXLPhotoSize.MEDIUM + binding.widget.pxlPhotoAdapter.list.forEach { when (it) { is PXLPhotoAdapter.Item.Content -> { - it.data.heightInPixel = widget.viewModel.cellHeightInPixel - it.data.configuration.pxlPhotoSize = widget.viewModel.customizedConfiguration.pxlPhotoSize + it.data.heightInPixel = binding.widget.viewModel.cellHeightInPixel + it.data.configuration.pxlPhotoSize = binding.widget.viewModel.customizedConfiguration.pxlPhotoSize } } } - widget.pxlPhotoAdapter.notifyDataSetChanged() + binding.widget.pxlPhotoAdapter.notifyDataSetChanged() - if (radio_infiniteScroll_on.isChecked) { - var lastItem = widget.pxlPhotoAdapter.list.lastOrNull() + if (binding.leftLayout.radioInfiniteScrollOn.isChecked) { + var lastItem = binding.widget.pxlPhotoAdapter.list.lastOrNull() if (lastItem != null && lastItem is PXLPhotoAdapter.Item.LoadMore) { - val position = widget.pxlPhotoAdapter.list.count() - 1 - widget.pxlPhotoAdapter.list.removeAt(position) - widget.pxlPhotoAdapter.notifyItemRemoved(position) + val position = binding.widget.pxlPhotoAdapter.list.count() - 1 + binding.widget.pxlPhotoAdapter.list.removeAt(position) + binding.widget.pxlPhotoAdapter.notifyItemRemoved(position) } } } fun refreshViewType() { - widget.currentViewType = getViewType() + binding.widget.currentViewType = getViewType() } fun getGridSpan(): Int { - return if (radio_grid_2.isChecked) 2 - else if (radio_grid_3.isChecked) 3 - else if (radio_grid_4.isChecked) 4 - else if (radio_grid_5.isChecked) 5 + return if (binding.leftLayout.radioGridCount2.isChecked) 2 + else if (binding.leftLayout.radioGridCount3.isChecked) 3 + else if (binding.leftLayout.radioGridCount4.isChecked) 4 + else if (binding.leftLayout.radioGridCount5.isChecked) 5 else 2 } fun getLineSpace(): Int { - val text = tvLineSpace.text.toString() + val text = binding.leftLayout.tvLineSpace.text.toString() return if (text.isEmpty()) 0 else text.toInt() } fun getHeader(): ListHeader? { - return if (radio_header_image.isChecked) + return if (binding.leftLayout.radioHeaderImage.isChecked) ListHeader.Gif(url = "https://media.giphy.com/media/dzaUX7CAG0Ihi/giphy.gif", heightInPixel = 200.px.toInt(), imageScaleType = ImageScaleType.CENTER_CROP) - else if (radio_header_text.isChecked) + else if (binding.leftLayout.radioHeaderText.isChecked) getTitleSpannable() else null diff --git a/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/IndexActivity.kt b/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/IndexActivity.kt index ad937506..2d030e4d 100644 --- a/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/IndexActivity.kt +++ b/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/IndexActivity.kt @@ -3,25 +3,33 @@ package com.pixlee.pixleeandroidsdk import android.content.Intent import android.os.Bundle import androidx.appcompat.app.AppCompatActivity -import kotlinx.android.synthetic.main.activity_index.* +import com.pixlee.pixleeandroidsdk.databinding.ActivityIndexBinding /** * Created by sungjun on 3/23/21. */ class IndexActivity : AppCompatActivity() { + private var _binding: ActivityIndexBinding? = null + private val binding get() = _binding!! + + override fun onDestroy() { + super.onDestroy() + _binding = null + } public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_index) + _binding = ActivityIndexBinding.inflate(layoutInflater) + setContentView(binding.root) - grid.setOnClickListener { + binding.grid.setOnClickListener { startActivity(Intent(this, SimpleGridActivity::class.java)) } - list.setOnClickListener { + binding.list.setOnClickListener { startActivity(Intent(this, SimpleListActivity::class.java)) } - dynamic.setOnClickListener { + binding.dynamic.setOnClickListener { startActivity(Intent(this, DynamicDemoActivity::class.java)) } } diff --git a/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/SimpleGridActivity.kt b/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/SimpleGridActivity.kt index 8d7eedc0..87cc2ab1 100644 --- a/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/SimpleGridActivity.kt +++ b/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/SimpleGridActivity.kt @@ -6,6 +6,7 @@ import android.os.Bundle import android.view.ViewTreeObserver import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat +import com.pixlee.pixleeandroidsdk.databinding.ActivitySimpleDemoBinding import com.pixlee.pixleesdk.client.PXLKtxBaseAlbum import com.pixlee.pixleesdk.data.PXLAlbumFilterOptions import com.pixlee.pixleesdk.data.PXLAlbumSortOptions @@ -17,7 +18,6 @@ import com.pixlee.pixleesdk.ui.widgets.TextPadding import com.pixlee.pixleesdk.ui.widgets.TextViewStyle import com.pixlee.pixleesdk.ui.widgets.list.PXLWidgetView import com.pixlee.pixleesdk.util.px -import kotlinx.android.synthetic.main.activity_simple_demo.* /** * Created by sungjun on 3/23/21. @@ -25,24 +25,34 @@ import kotlinx.android.synthetic.main.activity_simple_demo.* class SimpleGridActivity : AppCompatActivity() { val listHeightRatio = 0.5f + private var _binding: ActivitySimpleDemoBinding? = null + private val binding get() = _binding!! + + override fun onDestroy() { + super.onDestroy() + _binding = null + } + public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_simple_demo) - setSupportActionBar(toolbar) - toolbar.navigationIcon?.setColorFilter( + _binding = ActivitySimpleDemoBinding.inflate(layoutInflater) + setContentView(binding.root) + + setSupportActionBar(binding.toolbar) + binding.toolbar.navigationIcon?.setColorFilter( ContextCompat.getColor(this, R.color.grey_60), PorterDuff.Mode.SRC_ATOP ) - widget.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { + binding.widget.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { try { - if (widget == null) + if (binding.widget == null) return - initiateList((widget.measuredHeight * listHeightRatio).toInt()) + initiateList((binding.widget.measuredHeight * listHeightRatio).toInt()) - widget.viewTreeObserver.removeOnGlobalLayoutListener(this) + binding.widget.viewTreeObserver.removeOnGlobalLayoutListener(this) } catch (e: Exception) { e.printStackTrace() } @@ -53,7 +63,7 @@ class SimpleGridActivity : AppCompatActivity() { private fun initiateList(cellHeightInPixel: Int) { // you can customize color, size if you need - widget.initiate( + binding.widget.initiate( widgetTypeForAnalytics = "your_widget_type", // this will be used when this view automatically fires openedWidget, widgetVisible analytics viewType = PXLWidgetView.ViewType.Grid(), cellHeightInPixel = cellHeightInPixel, diff --git a/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/SimpleListActivity.kt b/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/SimpleListActivity.kt index 8bd4ec5d..5eaf9782 100644 --- a/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/SimpleListActivity.kt +++ b/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/SimpleListActivity.kt @@ -7,6 +7,7 @@ import android.view.ViewTreeObserver import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat +import com.pixlee.pixleeandroidsdk.databinding.ActivitySimpleDemoBinding import com.pixlee.pixleesdk.client.PXLKtxBaseAlbum import com.pixlee.pixleesdk.data.PXLAlbumFilterOptions import com.pixlee.pixleesdk.data.PXLAlbumSortOptions @@ -18,7 +19,6 @@ import com.pixlee.pixleesdk.ui.widgets.TextPadding import com.pixlee.pixleesdk.ui.widgets.TextViewStyle import com.pixlee.pixleesdk.ui.widgets.list.PXLWidgetView import com.pixlee.pixleesdk.util.px -import kotlinx.android.synthetic.main.activity_simple_demo.* /** * Created by sungjun on 3/23/21. @@ -26,24 +26,33 @@ import kotlinx.android.synthetic.main.activity_simple_demo.* class SimpleListActivity : AppCompatActivity() { val listHeightRatio = 0.5f + private var _binding: ActivitySimpleDemoBinding? = null + private val binding get() = _binding!! + + override fun onDestroy() { + super.onDestroy() + _binding = null + } + public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_simple_demo) - setSupportActionBar(toolbar) - toolbar.navigationIcon?.setColorFilter( + _binding = ActivitySimpleDemoBinding.inflate(layoutInflater) + setContentView(binding.root) + setSupportActionBar(binding.toolbar) + binding.toolbar.navigationIcon?.setColorFilter( ContextCompat.getColor(this, R.color.grey_60), PorterDuff.Mode.SRC_ATOP ) - widget.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { + binding.widget.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { try { - if (widget == null) + if (binding.widget == null) return - initwidget((widget.measuredHeight * listHeightRatio).toInt()) + initwidget((binding.widget.measuredHeight * listHeightRatio).toInt()) - widget.viewTreeObserver.removeOnGlobalLayoutListener(this) + binding.widget.viewTreeObserver.removeOnGlobalLayoutListener(this) } catch (e: Exception) { e.printStackTrace() } @@ -54,7 +63,7 @@ class SimpleListActivity : AppCompatActivity() { private fun initwidget(cellHeightInPixel: Int) { // you can customize color, size if you need - widget.initiate( + binding.widget.initiate( widgetTypeForAnalytics = "your_widget_type", // this will be used when this view automatically fires openedWidget, widgetVisible analytics viewType = PXLWidgetView.ViewType.List(), cellHeightInPixel = cellHeightInPixel, diff --git a/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/ViewerActivity.kt b/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/ViewerActivity.kt index 42752260..37bbc652 100644 --- a/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/ViewerActivity.kt +++ b/simpleapp/src/main/java/com/pixlee/pixleeandroidsdk/ViewerActivity.kt @@ -8,6 +8,7 @@ import android.os.Bundle import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat +import com.pixlee.pixleeandroidsdk.databinding.ActivityViewerBinding import com.pixlee.pixleesdk.ui.viewholder.PhotoWithVideoInfo import com.pixlee.pixleesdk.ui.viewholder.ProductViewHolder import com.pixlee.pixleesdk.ui.widgets.CurrencyTextStyle @@ -16,7 +17,6 @@ import com.pixlee.pixleesdk.ui.widgets.PXLPhotoProductView import com.pixlee.pixleesdk.ui.widgets.TextStyle import com.pixlee.pixleesdk.util.PXLViewUtil import com.pixlee.pixleesdk.util.px -import kotlinx.android.synthetic.main.activity_viewer.* import java.util.* /** @@ -26,9 +26,18 @@ import java.util.* * This shows how to play the video and its product list */ class ViewerActivity : AppCompatActivity() { + private var _binding: ActivityViewerBinding? = null + private val binding get() = _binding!! + + override fun onDestroy() { + super.onDestroy() + _binding = null + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_viewer) + _binding = ActivityViewerBinding.inflate(layoutInflater) + setContentView(binding.root) // set a full screen mode PXLViewUtil.expandContentAreaOverStatusBar(this) @@ -53,10 +62,10 @@ class ViewerActivity : AppCompatActivity() { item.configuration.imageScaleType = ImageScaleType.FIT_CENTER // give a padding to the top as much as the status bar's height - pxlPhotoProductView.addPaddingToHeader(0, PXLViewUtil.getStatusBarHeight(this), 0, 0) + binding.pxlPhotoProductView.addPaddingToHeader(0, PXLViewUtil.getStatusBarHeight(this), 0, 0) // set your ui settings - pxlPhotoProductView + binding.pxlPhotoProductView .setContent(photoInfo = item, headerConfiguration = PXLPhotoProductView.Configuration().apply { backButton = PXLPhotoProductView.CircleButton().apply { diff --git a/simpleapp/src/main/res/layout/activity_dynamic_photos.xml b/simpleapp/src/main/res/layout/activity_dynamic_photos.xml index f70c6676..0d75eae8 100644 --- a/simpleapp/src/main/res/layout/activity_dynamic_photos.xml +++ b/simpleapp/src/main/res/layout/activity_dynamic_photos.xml @@ -47,7 +47,10 @@ android:fitsSystemWindows="false" android:alpha="0.9"> - + diff --git a/simpleapp/src/main/res/layout/module_search.xml b/simpleapp/src/main/res/layout/module_search.xml index 63bed168..3c6019b9 100644 --- a/simpleapp/src/main/res/layout/module_search.xml +++ b/simpleapp/src/main/res/layout/module_search.xml @@ -80,23 +80,23 @@ android:orientation="vertical"> - +