Skip to content

Commit 93ac388

Browse files
authored
chore: refactor base fragment activity in java sample (#506)
1 parent 54ed0f1 commit 93ac388

File tree

11 files changed

+328
-293
lines changed

11 files changed

+328
-293
lines changed

samples/java_layout/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
plugins {
22
id 'com.android.application'
3+
id 'org.jetbrains.kotlin.android'
4+
id 'org.jetbrains.kotlin.kapt'
35
id 'com.google.gms.google-services' // Google services Gradle plugin
46
}
57

samples/java_layout/src/main/AndroidManifest.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,9 @@
120120
</intent-filter>
121121
</activity>
122122
<activity
123-
android:name=".ui.common.SimpleFragmentActivity"
123+
android:name=".ui.tracking.TrackingFragmentActivity"
124124
android:exported="false"
125-
android:label="@string/label_simple_fragment_activity" />
125+
android:label="@string/label_tracking_fragment_activity" />
126126
<activity
127127
android:name=".ui.settings.InternalSettingsActivity"
128128
android:exported="false"

samples/java_layout/src/main/java/io/customer/android/sample/java_layout/ui/common/SimpleFragmentActivity.java

Lines changed: 0 additions & 111 deletions
This file was deleted.

samples/java_layout/src/main/java/io/customer/android/sample/java_layout/ui/core/BaseActivity.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,15 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
2626
binding = inflateViewBinding();
2727
setContentView(binding.getRoot());
2828
viewModelProvider = new ViewModelProvider(this, applicationGraph.getViewModelFactory());
29+
readExtras();
2930
injectDependencies();
3031
setupContent();
3132
}
3233

34+
@EmptySuper
35+
protected void readExtras() {
36+
}
37+
3338
@EmptySuper
3439
protected void injectDependencies() {
3540
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package io.customer.android.sample.java_layout.ui.core
2+
3+
import android.content.Intent
4+
import android.os.Bundle
5+
import android.view.View
6+
import androidx.appcompat.widget.Toolbar
7+
import androidx.fragment.app.Fragment
8+
import androidx.viewbinding.ViewBinding
9+
import com.google.android.material.progressindicator.BaseProgressIndicator
10+
import io.customer.android.sample.java_layout.ui.dashboard.DashboardActivity
11+
import io.customer.android.sample.java_layout.ui.login.LoginActivity
12+
import io.customer.android.sample.java_layout.ui.user.AuthViewModel
13+
import io.customer.android.sample.java_layout.utils.ViewUtils
14+
15+
abstract class BaseFragmentContainerActivity<VB : ViewBinding> : BaseActivity<VB>() {
16+
protected abstract val fragmentContainer: View
17+
protected abstract fun findFragmentByName(fragmentName: String): Fragment?
18+
19+
protected open val progressIndicator: BaseProgressIndicator<*>? = null
20+
protected open fun getFragmentTitle(): String? = null
21+
22+
protected lateinit var fragmentName: String
23+
24+
override fun onBackPressed() {
25+
finish()
26+
}
27+
28+
private fun navigateUp() {
29+
// For better user experience, navigate to launcher activity on navigate up button
30+
if (isTaskRoot) {
31+
startActivity(Intent(this, DashboardActivity::class.java))
32+
}
33+
onBackPressed()
34+
}
35+
36+
override fun readExtras() {
37+
fragmentName = intent?.extras?.getString(ARG_FRAGMENT_NAME)?.takeIf {
38+
it.isNotBlank()
39+
} ?: throw IllegalArgumentException("Fragment name cannot be null")
40+
}
41+
42+
protected fun setupToolbar(toolbar: Toolbar, useAsSupportActionBar: Boolean = false) {
43+
ViewUtils.prepareForAutomatedTests(toolbar)
44+
if (useAsSupportActionBar) {
45+
setSupportActionBar(toolbar)
46+
}
47+
toolbar.setNavigationOnClickListener { _ -> navigateUp() }
48+
}
49+
50+
protected fun setupWithAuthViewModel(authViewModel: AuthViewModel) {
51+
authViewModel.userLoggedInStateObservable.observe(this) { isLoggedIn: Boolean ->
52+
if (isLoggedIn) {
53+
replaceFragmentInView()
54+
} else {
55+
if (isTaskRoot) {
56+
startActivity(Intent(this, LoginActivity::class.java))
57+
}
58+
finish()
59+
}
60+
}
61+
}
62+
63+
private fun replaceFragmentInView() {
64+
val fragment = findFragmentByName(fragmentName) ?: throw IllegalArgumentException("Invalid fragment name provided")
65+
val fragmentManager = supportFragmentManager
66+
val fragmentTransaction = fragmentManager.beginTransaction()
67+
fragmentTransaction.replace(fragmentContainer.id, fragment)
68+
fragmentTransaction.commit()
69+
getFragmentTitle()?.let(::setTitle)
70+
progressIndicator?.hide()
71+
}
72+
73+
companion object {
74+
protected const val ARG_FRAGMENT_NAME = "fragment_name"
75+
76+
@JvmStatic
77+
protected fun getExtras(fragmentName: String?): Bundle {
78+
val extras = Bundle()
79+
extras.putString(ARG_FRAGMENT_NAME, fragmentName)
80+
return extras
81+
}
82+
}
83+
}

samples/java_layout/src/main/java/io/customer/android/sample/java_layout/ui/dashboard/DashboardActivity.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@
3131
import io.customer.android.sample.java_layout.R;
3232
import io.customer.android.sample.java_layout.databinding.ActivityDashboardBinding;
3333
import io.customer.android.sample.java_layout.sdk.CustomerIORepository;
34-
import io.customer.android.sample.java_layout.ui.common.SimpleFragmentActivity;
3534
import io.customer.android.sample.java_layout.ui.core.BaseActivity;
3635
import io.customer.android.sample.java_layout.ui.login.LoginActivity;
3736
import io.customer.android.sample.java_layout.ui.settings.InternalSettingsActivity;
3837
import io.customer.android.sample.java_layout.ui.settings.SettingsActivity;
38+
import io.customer.android.sample.java_layout.ui.tracking.TrackingFragmentActivity;
3939
import io.customer.android.sample.java_layout.ui.user.AuthViewModel;
4040
import io.customer.android.sample.java_layout.utils.Randoms;
4141
import io.customer.android.sample.java_layout.utils.ViewUtils;
@@ -137,13 +137,13 @@ private void setupViews() {
137137
sendRandomEvent();
138138
});
139139
binding.sendCustomEventButton.setOnClickListener(view -> {
140-
startSimpleFragmentActivity(SimpleFragmentActivity.FRAGMENT_CUSTOM_TRACKING_EVENT);
140+
startTrackingFragmentActivity(TrackingFragmentActivity.FRAGMENT_CUSTOM_TRACKING_EVENT);
141141
});
142142
binding.setDeviceAttributesButton.setOnClickListener(view -> {
143-
startSimpleFragmentActivity(SimpleFragmentActivity.FRAGMENT_DEVICE_ATTRIBUTES);
143+
startTrackingFragmentActivity(TrackingFragmentActivity.FRAGMENT_DEVICE_ATTRIBUTES);
144144
});
145145
binding.setProfileAttributesButton.setOnClickListener(view -> {
146-
startSimpleFragmentActivity(SimpleFragmentActivity.FRAGMENT_PROFILE_ATTRIBUTES);
146+
startTrackingFragmentActivity(TrackingFragmentActivity.FRAGMENT_PROFILE_ATTRIBUTES);
147147
});
148148
binding.showPushPromptButton.setOnClickListener(view -> {
149149
requestNotificationPermission();
@@ -189,9 +189,9 @@ private void sendRandomEvent() {
189189
Snackbar.LENGTH_SHORT).show();
190190
}
191191

192-
private void startSimpleFragmentActivity(String fragmentName) {
193-
Intent intent = new Intent(DashboardActivity.this, SimpleFragmentActivity.class);
194-
Bundle extras = SimpleFragmentActivity.getExtras(fragmentName);
192+
private void startTrackingFragmentActivity(String fragmentName) {
193+
Intent intent = new Intent(DashboardActivity.this, TrackingFragmentActivity.class);
194+
Bundle extras = TrackingFragmentActivity.getExtras(fragmentName);
195195
intent.putExtras(extras);
196196
startActivity(intent);
197197
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package io.customer.android.sample.java_layout.ui.tracking
2+
3+
import android.os.Bundle
4+
import android.view.View
5+
import androidx.fragment.app.Fragment
6+
import com.google.android.material.progressindicator.LinearProgressIndicator
7+
import io.customer.android.sample.java_layout.databinding.ActivitySimpleFragmentBinding
8+
import io.customer.android.sample.java_layout.ui.core.BaseFragmentContainerActivity
9+
import io.customer.android.sample.java_layout.ui.user.AuthViewModel
10+
11+
class TrackingFragmentActivity : BaseFragmentContainerActivity<ActivitySimpleFragmentBinding>() {
12+
private lateinit var authViewModel: AuthViewModel
13+
14+
override val fragmentContainer: View get() = binding.container
15+
override val progressIndicator: LinearProgressIndicator get() = binding.progressIndicator
16+
17+
override fun inflateViewBinding(): ActivitySimpleFragmentBinding {
18+
return ActivitySimpleFragmentBinding.inflate(layoutInflater)
19+
}
20+
21+
override fun injectDependencies() {
22+
authViewModel = viewModelProvider[AuthViewModel::class.java]
23+
}
24+
25+
override fun setupContent() {
26+
setupToolbar(binding.topAppBar)
27+
setupWithAuthViewModel(authViewModel)
28+
}
29+
30+
override fun findFragmentByName(fragmentName: String): Fragment? = when (fragmentName) {
31+
FRAGMENT_CUSTOM_TRACKING_EVENT -> CustomEventTrackingFragment.newInstance()
32+
FRAGMENT_DEVICE_ATTRIBUTES -> AttributesTrackingFragment.newInstance(AttributesTrackingFragment.ATTRIBUTE_TYPE_DEVICE)
33+
FRAGMENT_PROFILE_ATTRIBUTES -> AttributesTrackingFragment.newInstance(AttributesTrackingFragment.ATTRIBUTE_TYPE_PROFILE)
34+
else -> null
35+
}
36+
37+
companion object {
38+
const val FRAGMENT_CUSTOM_TRACKING_EVENT: String = "FRAGMENT_CUSTOM_TRACKING_EVENT"
39+
const val FRAGMENT_DEVICE_ATTRIBUTES: String = "FRAGMENT_DEVICE_ATTRIBUTES"
40+
const val FRAGMENT_PROFILE_ATTRIBUTES: String = "FRAGMENT_PROFILE_ATTRIBUTES"
41+
42+
@JvmStatic
43+
fun getExtras(fragmentName: String?): Bundle {
44+
return BaseFragmentContainerActivity.getExtras(fragmentName)
45+
}
46+
}
47+
}

samples/java_layout/src/main/res/layout/activity_simple_fragment.xml

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
xmlns:tools="http://schemas.android.com/tools"
55
android:layout_width="match_parent"
66
android:layout_height="match_parent"
7-
tools:context=".ui.tracking.CustomEventTrackingFragment">
7+
tools:context=".ui.core.BaseFragmentContainerActivity">
88

99
<com.google.android.material.appbar.AppBarLayout
1010
android:layout_width="match_parent"
@@ -28,18 +28,9 @@
2828
tools:visibility="visible" />
2929
</com.google.android.material.appbar.AppBarLayout>
3030

31-
<androidx.core.widget.NestedScrollView
32-
android:id="@+id/content"
31+
<androidx.fragment.app.FragmentContainerView
32+
android:id="@+id/container"
3333
android:layout_width="match_parent"
3434
android:layout_height="match_parent"
35-
android:fadeScrollbars="false"
36-
android:fillViewport="true"
37-
android:scrollbars="vertical"
38-
app:layout_behavior="@string/appbar_scrolling_view_behavior">
39-
40-
<androidx.fragment.app.FragmentContainerView
41-
android:id="@+id/container"
42-
android:layout_width="match_parent"
43-
android:layout_height="wrap_content" />
44-
</androidx.core.widget.NestedScrollView>
35+
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
4536
</androidx.coordinatorlayout.widget.CoordinatorLayout>

0 commit comments

Comments
 (0)