mirror of
https://github.com/openlibrecommunity/olcng.git
synced 2026-07-03 14:05:17 +02:00
Refactor progress bar handling to BaseActivity
This commit is contained in:
@@ -246,7 +246,7 @@ class BackupActivity : BaseActivity() {
|
||||
return
|
||||
}
|
||||
|
||||
binding.pbWaiting.show()
|
||||
showLoading()
|
||||
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
var tempFile: File? = null
|
||||
@@ -283,7 +283,7 @@ class BackupActivity : BaseActivity() {
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
binding.pbWaiting.hide()
|
||||
hideLoading()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -296,7 +296,7 @@ class BackupActivity : BaseActivity() {
|
||||
return
|
||||
}
|
||||
|
||||
binding.pbWaiting.show()
|
||||
showLoading()
|
||||
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
var target: File? = null
|
||||
@@ -328,7 +328,7 @@ class BackupActivity : BaseActivity() {
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
binding.pbWaiting.hide()
|
||||
hideLoading()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import androidx.core.view.WindowCompat
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.handler.SettingsManager
|
||||
import com.v2ray.ang.helper.CustomDividerItemDecoration
|
||||
@@ -21,7 +22,21 @@ import com.v2ray.ang.util.MyContextWrapper
|
||||
import com.v2ray.ang.util.Utils
|
||||
|
||||
|
||||
/**
|
||||
* BaseActivity provides common helpers and UI wiring used across the app's activities.
|
||||
*
|
||||
* Responsibilities:
|
||||
* - Inflate a shared base layout that contains a toolbar and a content container.
|
||||
* - Provide convenient overloads of `setContentViewWithToolbar` to attach child layouts or
|
||||
* view-binding roots into the base container and initialize the toolbar.
|
||||
* - Expose a global in-layout `ProgressBar` (cached) with `showLoading()` / `hideLoading()` helpers.
|
||||
* - Provide a helper to add a custom divider to RecyclerViews.
|
||||
* - Wrap base context according to user locale settings.
|
||||
*/
|
||||
abstract class BaseActivity : AppCompatActivity() {
|
||||
// Progress indicator that sits at the bottom of the toolbar
|
||||
private var progressBar: LinearProgressIndicator? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
@@ -32,6 +47,15 @@ abstract class BaseActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle action bar item selections.
|
||||
*
|
||||
* Currently this handles the home/up button by delegating to the activity's
|
||||
* onBackPressedDispatcher to provide consistent back navigation behavior.
|
||||
*
|
||||
* @param item the selected menu item
|
||||
* @return true if the event was handled, otherwise delegates to the superclass
|
||||
*/
|
||||
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
|
||||
android.R.id.home -> {
|
||||
// Handles the home button press by delegating to the onBackPressedDispatcher.
|
||||
@@ -43,17 +67,29 @@ abstract class BaseActivity : AppCompatActivity() {
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the base context with the user's locale settings.
|
||||
*
|
||||
* This ensures resources are loaded using the configured locale.
|
||||
*
|
||||
* @param newBase the original base context to wrap
|
||||
*/
|
||||
override fun attachBaseContext(newBase: Context?) {
|
||||
super.attachBaseContext(MyContextWrapper.wrap(newBase ?: return, SettingsManager.getLocale()))
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom divider to a RecyclerView.
|
||||
* Adds a custom divider drawable to the provided RecyclerView.
|
||||
*
|
||||
* @param recyclerView The target RecyclerView to which the divider will be added.
|
||||
* @param context The context used to access resources.
|
||||
* @param drawableResId The resource ID of the drawable to be used as the divider.
|
||||
* @param orientation The orientation of the divider (DividerItemDecoration.VERTICAL or DividerItemDecoration.HORIZONTAL).
|
||||
* This is a convenience helper that constructs a [CustomDividerItemDecoration]
|
||||
* using the given drawable resource id and adds it to the RecyclerView.
|
||||
*
|
||||
* @param recyclerView the target RecyclerView
|
||||
* @param context the context used to resolve resources (may be activity or application context)
|
||||
* @param drawableResId the drawable resource id to use as the divider
|
||||
* @param orientation one of [DividerItemDecoration.VERTICAL] or [DividerItemDecoration.HORIZONTAL]
|
||||
*
|
||||
* @throws IllegalArgumentException if the drawable resource cannot be found
|
||||
*/
|
||||
protected fun addCustomDividerToRecyclerView(recyclerView: RecyclerView, context: Context?, drawableResId: Int, orientation: Int = DividerItemDecoration.VERTICAL) {
|
||||
// Get the drawable from resources
|
||||
@@ -67,6 +103,17 @@ abstract class BaseActivity : AppCompatActivity() {
|
||||
recyclerView.addItemDecoration(dividerItemDecoration)
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the toolbar instance using the default toolbar id if null is passed.
|
||||
*
|
||||
* This helper will set the toolbar as the action bar and configure the up button
|
||||
* visibility plus optional title.
|
||||
*
|
||||
* @param toolbar the toolbar instance to configure (may be null, in which case the view
|
||||
* with id R.id.toolbar in the activity content will be used)
|
||||
* @param showHomeAsUp whether the home/up affordance should be shown (default true)
|
||||
* @param title optional title to set on the activity
|
||||
*/
|
||||
protected fun setupToolbar(toolbar: Toolbar?, showHomeAsUp: Boolean = true, title: CharSequence? = null) {
|
||||
val tb = toolbar ?: findViewById<Toolbar?>(R.id.toolbar)
|
||||
tb?.let {
|
||||
@@ -74,24 +121,56 @@ abstract class BaseActivity : AppCompatActivity() {
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(showHomeAsUp)
|
||||
title?.let { t -> this.title = t }
|
||||
}
|
||||
progressBar = findViewById(R.id.progress_bar)
|
||||
}
|
||||
|
||||
/**
|
||||
* Inflate the shared base layout, attach the child layout resource into the base
|
||||
* content container, cache the in-layout ProgressBar and configure the toolbar.
|
||||
*
|
||||
* Typical usage in subclasses:
|
||||
* setContentViewWithToolbar(R.layout.activity_settings, showHomeAsUp = true, title = "Settings")
|
||||
*
|
||||
* @param layoutResId child layout resource to inflate into the base content container
|
||||
* @param showHomeAsUp whether to show the up/home affordance on the toolbar (default true)
|
||||
* @param title optional activity title to set on the toolbar
|
||||
*/
|
||||
protected fun setContentViewWithToolbar(layoutResId: Int, showHomeAsUp: Boolean = true, title: CharSequence? = null) {
|
||||
val base = LayoutInflater.from(this).inflate(R.layout.activity_base, null)
|
||||
val container = base.findViewById<FrameLayout>(R.id.content_container)
|
||||
LayoutInflater.from(this).inflate(layoutResId, container, true)
|
||||
progressBar = base.findViewById(R.id.progress_bar)
|
||||
super.setContentView(base)
|
||||
setupToolbar(base, showHomeAsUp, title)
|
||||
}
|
||||
|
||||
/**
|
||||
* Inflate the shared base layout, attach the provided child view (commonly a view-binding root)
|
||||
* into the base content container, cache the in-layout ProgressBar and configure the toolbar.
|
||||
*
|
||||
* Typical usage with view binding:
|
||||
* setContentViewWithToolbar(binding.root, showHomeAsUp = true, title = "...")
|
||||
*
|
||||
* @param childView the already-inflated child view to add to the base content container
|
||||
* @param showHomeAsUp whether to show the up/home affordance on the toolbar (default true)
|
||||
* @param title optional activity title to set on the toolbar
|
||||
*/
|
||||
protected fun setContentViewWithToolbar(childView: View, showHomeAsUp: Boolean = true, title: CharSequence? = null) {
|
||||
val base = LayoutInflater.from(this).inflate(R.layout.activity_base, null)
|
||||
val container = base.findViewById<FrameLayout>(R.id.content_container)
|
||||
container.addView(childView, ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
|
||||
progressBar = base.findViewById(R.id.progress_bar)
|
||||
super.setContentView(base)
|
||||
setupToolbar(base, showHomeAsUp, title)
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal helper that configures the MaterialToolbar found in the inflated base root.
|
||||
*
|
||||
* @param baseRoot the root view of the inflated base layout
|
||||
* @param showHomeAsUp whether to show the up/home affordance
|
||||
* @param title optional title to set on the support action bar
|
||||
*/
|
||||
private fun setupToolbar(baseRoot: View, showHomeAsUp: Boolean, title: CharSequence?) {
|
||||
val toolbar = baseRoot.findViewById<MaterialToolbar>(R.id.toolbar)
|
||||
toolbar?.let {
|
||||
@@ -101,4 +180,37 @@ abstract class BaseActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the base layout's ProgressBar.
|
||||
*
|
||||
* This method is safe to call from background threads; the visibility change will
|
||||
* be posted to the UI thread via [runOnUiThread]. If the base layout was not set yet
|
||||
* (progressBar == null) the call is a no-op.
|
||||
*/
|
||||
protected fun showLoading() {
|
||||
runOnUiThread {
|
||||
progressBar?.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the base layout's ProgressBar.
|
||||
*
|
||||
* Safe to call from background threads. No-op if the progress bar hasn't been cached.
|
||||
*/
|
||||
protected fun hideLoading() {
|
||||
runOnUiThread {
|
||||
progressBar?.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true when the base ProgressBar is currently visible.
|
||||
*
|
||||
* @return true if the progress bar exists and its visibility is VISIBLE
|
||||
*/
|
||||
protected fun isLoadingVisible(): Boolean {
|
||||
return progressBar?.visibility == View.VISIBLE
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ class CheckUpdateActivity : BaseActivity() {
|
||||
|
||||
private fun checkForUpdates(includePreRelease: Boolean) {
|
||||
toast(R.string.update_checking_for_update)
|
||||
showLoading()
|
||||
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
@@ -58,6 +59,9 @@ class CheckUpdateActivity : BaseActivity() {
|
||||
Log.e(AppConfig.TAG, "Failed to check for updates: ${e.message}")
|
||||
toastError(e.message ?: getString(R.string.toast_failure))
|
||||
}
|
||||
finally {
|
||||
hideLoading()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -422,7 +422,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
}
|
||||
|
||||
private fun importBatchConfig(server: String?) {
|
||||
binding.pbWaiting.show()
|
||||
showLoading()
|
||||
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
@@ -438,12 +438,12 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
countSub > 0 -> setupGroupTab()
|
||||
else -> toastError(R.string.toast_failure)
|
||||
}
|
||||
binding.pbWaiting.hide()
|
||||
hideLoading()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
withContext(Dispatchers.Main) {
|
||||
toastError(R.string.toast_failure)
|
||||
binding.pbWaiting.hide()
|
||||
hideLoading()
|
||||
}
|
||||
Log.e(AppConfig.TAG, "Failed to import batch config", e)
|
||||
}
|
||||
@@ -468,7 +468,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
* import config from sub
|
||||
*/
|
||||
private fun importConfigViaSub(): Boolean {
|
||||
binding.pbWaiting.show()
|
||||
showLoading()
|
||||
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val count = mainViewModel.updateConfigViaSubAll()
|
||||
@@ -480,14 +480,14 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
} else {
|
||||
toastError(R.string.toast_failure)
|
||||
}
|
||||
binding.pbWaiting.hide()
|
||||
hideLoading()
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun exportAll() {
|
||||
binding.pbWaiting.show()
|
||||
showLoading()
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val ret = mainViewModel.exportAllServer()
|
||||
launch(Dispatchers.Main) {
|
||||
@@ -495,7 +495,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
toast(getString(R.string.title_export_config_count, ret))
|
||||
else
|
||||
toastError(R.string.toast_failure)
|
||||
binding.pbWaiting.hide()
|
||||
hideLoading()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -503,13 +503,13 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
private fun delAllConfig() {
|
||||
AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
binding.pbWaiting.show()
|
||||
showLoading()
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val ret = mainViewModel.removeAllServer()
|
||||
launch(Dispatchers.Main) {
|
||||
mainViewModel.reloadServerList()
|
||||
toast(getString(R.string.title_del_config_count, ret))
|
||||
binding.pbWaiting.hide()
|
||||
hideLoading()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -522,13 +522,13 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
private fun delDuplicateConfig() {
|
||||
AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
binding.pbWaiting.show()
|
||||
showLoading()
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val ret = mainViewModel.removeDuplicateServer()
|
||||
launch(Dispatchers.Main) {
|
||||
mainViewModel.reloadServerList()
|
||||
toast(getString(R.string.title_del_duplicate_config_count, ret))
|
||||
binding.pbWaiting.hide()
|
||||
hideLoading()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -541,13 +541,13 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
private fun delInvalidConfig() {
|
||||
AlertDialog.Builder(this).setMessage(R.string.del_invalid_config_comfirm)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
binding.pbWaiting.show()
|
||||
showLoading()
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val ret = mainViewModel.removeInvalidServer()
|
||||
launch(Dispatchers.Main) {
|
||||
mainViewModel.reloadServerList()
|
||||
toast(getString(R.string.title_del_config_count, ret))
|
||||
binding.pbWaiting.hide()
|
||||
hideLoading()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -558,12 +558,12 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
}
|
||||
|
||||
private fun sortByTestResults() {
|
||||
binding.pbWaiting.show()
|
||||
showLoading()
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
mainViewModel.sortByTestResults()
|
||||
launch(Dispatchers.Main) {
|
||||
mainViewModel.reloadServerList()
|
||||
binding.pbWaiting.hide()
|
||||
hideLoading()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ class PerAppProxyActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
private fun initList() {
|
||||
binding.pbWaiting.show()
|
||||
showLoading()
|
||||
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
@@ -98,7 +98,7 @@ class PerAppProxyActivity : BaseActivity() {
|
||||
} catch (e: Exception) {
|
||||
Log.e(ANG_PACKAGE, "Error loading apps", e)
|
||||
} finally {
|
||||
binding.pbWaiting.hide()
|
||||
hideLoading()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -179,7 +179,7 @@ class PerAppProxyActivity : BaseActivity() {
|
||||
|
||||
private fun selectProxyAppAuto() {
|
||||
toast(R.string.msg_downloading_content)
|
||||
binding.pbWaiting.show()
|
||||
showLoading()
|
||||
|
||||
val url = AppConfig.ANDROID_PACKAGE_NAME_LIST_URL
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
@@ -192,7 +192,7 @@ class PerAppProxyActivity : BaseActivity() {
|
||||
//Log.i(AppConfig.TAG, content)
|
||||
selectProxyApp(content, true)
|
||||
toastSuccess(R.string.toast_success)
|
||||
binding.pbWaiting.hide()
|
||||
hideLoading()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ class SubSettingActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
R.id.sub_update -> {
|
||||
binding.pbWaiting.show()
|
||||
showLoading()
|
||||
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val count = AngConfigManager.updateConfigViaSubAll()
|
||||
@@ -70,7 +70,7 @@ class SubSettingActivity : BaseActivity() {
|
||||
} else {
|
||||
toastError(R.string.toast_failure)
|
||||
}
|
||||
binding.pbWaiting.hide()
|
||||
hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ class UserAssetActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
private fun downloadGeoFiles() {
|
||||
binding.pbWaiting.show()
|
||||
showLoading()
|
||||
toast(R.string.msg_downloading_content)
|
||||
|
||||
val httpPort = SettingsManager.getHttpPort()
|
||||
@@ -247,7 +247,7 @@ class UserAssetActivity : BaseActivity() {
|
||||
} else {
|
||||
toast(getString(R.string.toast_failure))
|
||||
}
|
||||
binding.pbWaiting.hide()
|
||||
hideLoading()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,14 +9,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/pb_waiting"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
android:visibility="invisible"
|
||||
app:indicatorColor="@color/color_fab_active" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -14,6 +14,15 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:titleTextAppearance="@style/TextAppearance.AppCompat.Title" />
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/progress_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@id/toolbar"
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone"
|
||||
app:indicatorColor="@color/color_fab_active" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/content_container"
|
||||
android:layout_width="0dp"
|
||||
@@ -21,6 +30,8 @@
|
||||
app:layout_constraintTop_toBottomOf="@id/toolbar"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -8,14 +8,6 @@
|
||||
android:orientation="vertical"
|
||||
tools:context=".ui.PerAppProxyActivity">
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/pb_waiting"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
android:visibility="invisible"
|
||||
app:indicatorColor="@color/color_fab_active" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/header_view"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/pb_waiting"
|
||||
android:id="@+id/progress_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
|
||||
@@ -7,14 +7,6 @@
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.SubSettingActivity">
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/pb_waiting"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
android:visibility="invisible"
|
||||
app:indicatorColor="@color/color_fab_active" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -7,14 +7,6 @@
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.UserAssetActivity">
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/pb_waiting"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
android:visibility="invisible"
|
||||
app:indicatorColor="@color/color_fab_active" />
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/main_content"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
Reference in New Issue
Block a user