From a708bac616214a2e3cc77a00e2096ce8ab2a57f4 Mon Sep 17 00:00:00 2001 From: Mihai-Cristian Condrea Date: Tue, 2 Sep 2025 12:21:57 +0300 Subject: [PATCH 1/2] refactor: centralize activity edge-to-edge setup --- .../components/navigation/BaseActivity.java | 34 ++++++++++++++++ .../java/ui/screens/help/HelpActivity.java | 19 +++------ .../java/ui/screens/main/MainActivity.java | 29 +++++++++----- .../java/ui/screens/main/MainViewModel.java | 10 +++++ .../ui/screens/support/SupportActivity.java | 27 ++----------- app/src/main/res/layout/activity_main.xml | 40 +++++++++++++++---- app/src/main/res/values/strings.xml | 3 ++ 7 files changed, 107 insertions(+), 55 deletions(-) create mode 100644 app/src/main/java/com/d4rk/androidtutorials/java/ui/components/navigation/BaseActivity.java diff --git a/app/src/main/java/com/d4rk/androidtutorials/java/ui/components/navigation/BaseActivity.java b/app/src/main/java/com/d4rk/androidtutorials/java/ui/components/navigation/BaseActivity.java new file mode 100644 index 00000000..3c5da3f9 --- /dev/null +++ b/app/src/main/java/com/d4rk/androidtutorials/java/ui/components/navigation/BaseActivity.java @@ -0,0 +1,34 @@ +package com.d4rk.androidtutorials.java.ui.components.navigation; + +import android.os.Bundle; +import android.view.View; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; + +import com.d4rk.androidtutorials.java.R; +import com.d4rk.androidtutorials.java.utils.EdgeToEdgeDelegate; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onPostCreate(@Nullable Bundle savedInstanceState) { + super.onPostCreate(savedInstanceState); + View container = findViewById(R.id.container); + if (container != null) { + EdgeToEdgeDelegate edgeToEdgeDelegate = new EdgeToEdgeDelegate(this); + edgeToEdgeDelegate.applyEdgeToEdge(container); + } + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(true); + } + } + + @Override + public boolean onSupportNavigateUp() { + finish(); + return true; + } +} diff --git a/app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/help/HelpActivity.java b/app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/help/HelpActivity.java index 55ef65f7..f1e0e8db 100644 --- a/app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/help/HelpActivity.java +++ b/app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/help/HelpActivity.java @@ -9,9 +9,8 @@ import android.view.MenuItem; import androidx.annotation.NonNull; -import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AlertDialog; -import com.d4rk.androidtutorials.java.ui.components.navigation.UpNavigationActivity; +import com.d4rk.androidtutorials.java.ui.components.navigation.BaseActivity; import androidx.lifecycle.ViewModelProvider; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; @@ -21,7 +20,6 @@ import com.d4rk.androidtutorials.java.databinding.ActivityHelpBinding; import com.d4rk.androidtutorials.java.databinding.DialogVersionInfoBinding; import com.d4rk.androidtutorials.java.ui.screens.help.repository.HelpRepository; -import com.d4rk.androidtutorials.java.utils.EdgeToEdgeDelegate; import com.d4rk.androidtutorials.java.utils.OpenSourceLicensesUtils; import com.google.android.material.snackbar.Snackbar; import com.google.android.play.core.review.ReviewInfo; @@ -30,7 +28,7 @@ import dagger.hilt.android.AndroidEntryPoint; @AndroidEntryPoint -public class HelpActivity extends UpNavigationActivity { +public class HelpActivity extends BaseActivity { private HelpViewModel helpViewModel; @@ -40,16 +38,8 @@ protected void onCreate(Bundle savedInstanceState) { ActivityHelpBinding binding = ActivityHelpBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); - EdgeToEdgeDelegate edgeToEdgeDelegate = new EdgeToEdgeDelegate(this); - edgeToEdgeDelegate.applyEdgeToEdge(binding.container); - helpViewModel = new ViewModelProvider(this).get(HelpViewModel.class); - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - } - getSupportFragmentManager().beginTransaction() .replace(R.id.frame_layout_faq, new FaqFragment()) .commit(); @@ -73,7 +63,10 @@ public boolean onCreateOptionsMenu(Menu menu) { public boolean onOptionsItemSelected(@NonNull MenuItem item) { int itemId = item.getItemId(); - if (itemId == R.id.view_in_google_play) { + if (itemId == android.R.id.home) { + finish(); + return true; + } else if (itemId == R.id.view_in_google_play) { openGooglePlayListing(); return true; } else if (itemId == R.id.version_info) { diff --git a/app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/main/MainActivity.java b/app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/main/MainActivity.java index 23663acf..0c301794 100644 --- a/app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/main/MainActivity.java +++ b/app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/main/MainActivity.java @@ -8,6 +8,7 @@ import android.util.Log; import android.util.SparseIntArray; import android.view.View; +import android.widget.Toast; import androidx.activity.OnBackPressedCallback; import androidx.activity.result.ActivityResultLauncher; @@ -42,7 +43,6 @@ import com.d4rk.androidtutorials.java.utils.EdgeToEdgeDelegate; import com.google.android.gms.ads.AdRequest; import com.google.android.gms.ads.MobileAds; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.navigation.NavigationBarView; import com.google.android.material.navigationrail.NavigationRailView; import com.google.android.material.snackbar.Snackbar; @@ -80,6 +80,8 @@ public class MainActivity extends AppCompatActivity { private AppUpdateNotificationsManager appUpdateNotificationsManager; private AppUpdateManager appUpdateManager; private InstallStateUpdatedListener installStateUpdatedListener; + private long backPressedTime; + private static final long BACK_PRESS_INTERVAL = 2000; private final DefaultLifecycleObserver lifecycleObserver = new DefaultLifecycleObserver() { @Override public void onResume(@NonNull LifecycleOwner owner) { @@ -88,11 +90,13 @@ public void onResume(@NonNull LifecycleOwner owner) { if (ConsentUtils.canShowAds(MainActivity.this)) { if (mBinding.adView.getVisibility() != View.VISIBLE) { MobileAds.initialize(MainActivity.this); + mBinding.adPlaceholder.setVisibility(View.GONE); mBinding.adView.setVisibility(View.VISIBLE); mBinding.adView.loadAd(new AdRequest.Builder().build()); } } else { mBinding.adView.setVisibility(View.GONE); + mBinding.adPlaceholder.setVisibility(View.VISIBLE); } } } @@ -149,15 +153,15 @@ protected void onCreate(Bundle savedInstanceState) { getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { - new MaterialAlertDialogBuilder(MainActivity.this) - .setTitle(R.string.alert_dialog_close) - .setMessage(R.string.summary_alert_dialog_close) - .setPositiveButton(android.R.string.yes, (dialog, which) -> { - finish(); - moveTaskToBack(true); - }) - .setNegativeButton(android.R.string.no, null) - .show(); } + long currentTime = System.currentTimeMillis(); + if (currentTime - backPressedTime < BACK_PRESS_INTERVAL) { + finish(); + moveTaskToBack(true); + } else { + backPressedTime = currentTime; + Toast.makeText(MainActivity.this, R.string.press_back_again_to_exit, Toast.LENGTH_SHORT).show(); + } + } }); } @@ -214,10 +218,12 @@ private void observeViewModel() { if (mBinding.adView != null) { if (ConsentUtils.canShowAds(this)) { MobileAds.initialize(this); + mBinding.adPlaceholder.setVisibility(View.GONE); mBinding.adView.setVisibility(View.VISIBLE); mBinding.adView.loadAd(new AdRequest.Builder().build()); } else { mBinding.adView.setVisibility(View.GONE); + mBinding.adPlaceholder.setVisibility(View.VISIBLE); } } } @@ -287,6 +293,9 @@ private void observeViewModel() { recreate(); } }); + + mainViewModel.getLoadingState().observe(this, isLoading -> + mBinding.progressBar.setVisibility(Boolean.TRUE.equals(isLoading) ? View.VISIBLE : View.GONE)); } private void setupUpdateNotifications() { diff --git a/app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/main/MainViewModel.java b/app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/main/MainViewModel.java index d7cff5a2..729a13d0 100644 --- a/app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/main/MainViewModel.java +++ b/app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/main/MainViewModel.java @@ -39,6 +39,7 @@ public class MainViewModel extends ViewModel { private final BuildShortcutIntentUseCase buildShortcutIntentUseCase; private final GetAppUpdateManagerUseCase getAppUpdateManagerUseCase; private final MutableLiveData uiState = new MutableLiveData<>(); + private final MutableLiveData isLoading = new MutableLiveData<>(false); @Inject public MainViewModel(ApplyThemeSettingsUseCase applyThemeSettingsUseCase, @@ -80,6 +81,7 @@ public MainViewModel(ApplyThemeSettingsUseCase applyThemeSettingsUseCase, public void applySettings(String[] themeValues, String[] bottomNavBarLabelsValues, String[] defaultTabValues) { + isLoading.setValue(true); boolean changedTheme = applyThemeSettingsUseCase.invoke(themeValues); String labelVisibilityStr = getBottomNavLabelVisibilityUseCase.invoke(); @@ -99,6 +101,7 @@ public void applySettings(String[] themeValues, uiState.setValue(new MainUiState(visibilityMode, startFragmentId, changedTheme)); applyLanguageSettingsUseCase.invoke(); + isLoading.setValue(false); } /** @@ -136,6 +139,13 @@ public LiveData getUiState() { return uiState; } + /** + * Expose loading state to toggle progress indicators. + */ + public LiveData getLoadingState() { + return isLoading; + } + /** * Expose the AppUpdateManager if the Activity wants to directly check for in-app updates. */ diff --git a/app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/support/SupportActivity.java b/app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/support/SupportActivity.java index 7b868013..5ac94d3e 100644 --- a/app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/support/SupportActivity.java +++ b/app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/support/SupportActivity.java @@ -3,17 +3,12 @@ import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import android.view.MenuItem; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.ActionBar; -import androidx.appcompat.app.AppCompatActivity; +import com.d4rk.androidtutorials.java.ui.components.navigation.BaseActivity; import androidx.lifecycle.ViewModelProvider; import com.android.billingclient.api.ProductDetails; import com.d4rk.androidtutorials.java.data.repository.SupportRepository; import com.d4rk.androidtutorials.java.databinding.ActivitySupportBinding; -import com.d4rk.androidtutorials.java.utils.EdgeToEdgeDelegate; import com.google.android.gms.ads.AdRequest; import java.util.List; @@ -21,7 +16,7 @@ import dagger.hilt.android.AndroidEntryPoint; @AndroidEntryPoint -public class SupportActivity extends AppCompatActivity { +public class SupportActivity extends BaseActivity { private ActivitySupportBinding binding; private SupportViewModel supportViewModel; @@ -32,15 +27,6 @@ protected void onCreate(Bundle savedInstanceState) { binding = ActivitySupportBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); - - EdgeToEdgeDelegate edgeToEdgeDelegate = new EdgeToEdgeDelegate(this); - edgeToEdgeDelegate.applyEdgeToEdge(binding.container); - - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - } - supportViewModel = new ViewModelProvider(this).get(SupportViewModel.class); AdRequest adRequest = supportViewModel.initMobileAds(); @@ -81,12 +67,5 @@ private void initiatePurchase(String productId) { } } - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == android.R.id.home) { - finish(); - return true; - } - return super.onOptionsItemSelected(item); - } + // Up navigation handled by BaseActivity } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index e68591af..ba5aa6c0 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -15,6 +15,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" app:navigationIcon="@drawable/ic_menu" + app:navigationContentDescription="@string/menu" app:shapeAppearanceOverlay="@style/ShapeTokens.Clover" app:title="@string/app_name" /> @@ -26,7 +27,7 @@ android:visibility="gone" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/app_bar_layout" - app:layout_constraintBottom_toTopOf="@+id/ad_view" + app:layout_constraintBottom_toTopOf="@+id/ad_container" app:menu="@menu/bottom_nav_menu" /> - + android:layout_height="50dp" + app:layout_constraintBottom_toTopOf="@+id/nav_view"> + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2af6b9a3..a97ae1e5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -6,6 +6,9 @@ It\'s been a while. It\'s been a while—learn something new about Android. + Menu + Press back again to exit + Welcome Read and agree to the Terms of Service and Privacy Policy to continue Agree From 342a96a0448a72c7229afa1ec54ff28385aecf61 Mon Sep 17 00:00:00 2001 From: Mihai-Cristian Condrea Date: Tue, 2 Sep 2025 12:33:46 +0300 Subject: [PATCH 2/2] chore: localize menu and exit prompts --- app/src/main/res/values-ar-rEG/strings.xml | 2 ++ app/src/main/res/values-bg-rBG/strings.xml | 2 ++ app/src/main/res/values-bn-rBD/strings.xml | 2 ++ app/src/main/res/values-de-rDE/strings.xml | 2 ++ app/src/main/res/values-es-rGQ/strings.xml | 2 ++ app/src/main/res/values-es-rMX/strings.xml | 2 ++ app/src/main/res/values-fil-rPH/strings.xml | 2 ++ app/src/main/res/values-fr-rFR/strings.xml | 2 ++ app/src/main/res/values-hi-rIN/strings.xml | 2 ++ app/src/main/res/values-hu-rHU/strings.xml | 2 ++ app/src/main/res/values-in-rID/strings.xml | 2 ++ app/src/main/res/values-it-rIT/strings.xml | 2 ++ app/src/main/res/values-ja-rJP/strings.xml | 2 ++ app/src/main/res/values-ko-rKR/strings.xml | 2 ++ app/src/main/res/values-pl-rPL/strings.xml | 2 ++ app/src/main/res/values-pt-rBR/strings.xml | 2 ++ app/src/main/res/values-ro-rRO/strings.xml | 2 ++ app/src/main/res/values-ru-rRU/strings.xml | 2 ++ app/src/main/res/values-sv-rSE/strings.xml | 2 ++ app/src/main/res/values-th-rTH/strings.xml | 2 ++ app/src/main/res/values-tr-rTR/strings.xml | 2 ++ app/src/main/res/values-uk-rUA/strings.xml | 2 ++ app/src/main/res/values-ur-rPK/strings.xml | 2 ++ app/src/main/res/values-vi-rVN/strings.xml | 2 ++ app/src/main/res/values-zh-rTW/strings.xml | 2 ++ 25 files changed, 50 insertions(+) diff --git a/app/src/main/res/values-ar-rEG/strings.xml b/app/src/main/res/values-ar-rEG/strings.xml index 03e0cee5..cd068e43 100644 --- a/app/src/main/res/values-ar-rEG/strings.xml +++ b/app/src/main/res/values-ar-rEG/strings.xml @@ -5,6 +5,8 @@ إصدار جديد من التطبيق متاح. اضغط للتحديث. بقالك فترة مدخلتش. It\'s been a while—learn something new about Android. + القائمة + اضغط مرة أخرى للخروج أهلاً بك Read and agree to the Terms of Service and Privacy Policy to continue موافق diff --git a/app/src/main/res/values-bg-rBG/strings.xml b/app/src/main/res/values-bg-rBG/strings.xml index 993670dd..fc09f031 100644 --- a/app/src/main/res/values-bg-rBG/strings.xml +++ b/app/src/main/res/values-bg-rBG/strings.xml @@ -5,6 +5,8 @@ Налична е нова версия на приложението. Кликнете, за да актуализирате. Отдавна не сме се виждали. It\'s been a while—learn something new about Android. + Меню + Натиснете отново назад, за да излезете Добре дошли Read and agree to the Terms of Service and Privacy Policy to continue Съгласен съм diff --git a/app/src/main/res/values-bn-rBD/strings.xml b/app/src/main/res/values-bn-rBD/strings.xml index 44e5146f..6c168194 100644 --- a/app/src/main/res/values-bn-rBD/strings.xml +++ b/app/src/main/res/values-bn-rBD/strings.xml @@ -5,6 +5,8 @@ অ্যাপটির একটি নতুন সংস্করণ উপলব্ধ। আপডেট করতে ক্লিক করুন. অনেক দিন হয়ে গেছে. It\'s been a while—learn something new about Android. + মেনু + প্রস্থান করতে আবার ফিরে টিপুন স্বাগতম Read and agree to the Terms of Service and Privacy Policy to continue সম্মত diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml index 60ff4ceb..fcfd8a6d 100644 --- a/app/src/main/res/values-de-rDE/strings.xml +++ b/app/src/main/res/values-de-rDE/strings.xml @@ -5,6 +5,8 @@ Eine neue Version der App ist verfügbar. Zum Aktualisieren klicken. Schon eine Weile her. It\'s been a while—learn something new about Android. + Menü + Drücken Sie erneut zurück, um zu verlassen Willkommen Read and agree to the Terms of Service and Privacy Policy to continue Zustimmen diff --git a/app/src/main/res/values-es-rGQ/strings.xml b/app/src/main/res/values-es-rGQ/strings.xml index 434a2427..4a50eb0f 100644 --- a/app/src/main/res/values-es-rGQ/strings.xml +++ b/app/src/main/res/values-es-rGQ/strings.xml @@ -5,6 +5,8 @@ Hay una nueva versión de la aplicación disponible. Haz clic para actualizar. Ha pasado un tiempo. It\'s been a while—learn something new about Android. + Menú + Presione de nuevo para salir Bienvenido Read and agree to the Terms of Service and Privacy Policy to continue Aceptar diff --git a/app/src/main/res/values-es-rMX/strings.xml b/app/src/main/res/values-es-rMX/strings.xml index ded5bb99..757d7254 100644 --- a/app/src/main/res/values-es-rMX/strings.xml +++ b/app/src/main/res/values-es-rMX/strings.xml @@ -5,6 +5,8 @@ Hay una nueva versión de la app disponible. Haz clic para actualizar. Ha pasado un tiempo. It\'s been a while—learn something new about Android. + Menú + Presione de nuevo para salir Bienvenido Read and agree to the Terms of Service and Privacy Policy to continue Acepto diff --git a/app/src/main/res/values-fil-rPH/strings.xml b/app/src/main/res/values-fil-rPH/strings.xml index 5132c730..437e0a91 100644 --- a/app/src/main/res/values-fil-rPH/strings.xml +++ b/app/src/main/res/values-fil-rPH/strings.xml @@ -5,6 +5,8 @@ May bagong bersyon ng app. I-click para mag-update. Matagal ka nang hindi bumibisita. It\'s been a while—learn something new about Android. + Menu + Pindutin muli upang lumabas Maligayang pagdating Read and agree to the Terms of Service and Privacy Policy to continue Sumang-ayon diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml index d2189439..e407d6bb 100644 --- a/app/src/main/res/values-fr-rFR/strings.xml +++ b/app/src/main/res/values-fr-rFR/strings.xml @@ -5,6 +5,8 @@ Une nouvelle version de l\'application est disponible. Cliquez pour mettre à jour . Cela fait un moment . It\'s been a while—learn something new about Android. + Menu + Appuyez à nouveau pour quitter Bienvenue Read and agree to the Terms of Service and Privacy Policy to continue Accepter diff --git a/app/src/main/res/values-hi-rIN/strings.xml b/app/src/main/res/values-hi-rIN/strings.xml index c52a3627..bd3b1855 100644 --- a/app/src/main/res/values-hi-rIN/strings.xml +++ b/app/src/main/res/values-hi-rIN/strings.xml @@ -367,6 +367,8 @@ उदाहरण के लिए, यदि आपके ऐप को कुछ डाउनलोड करने की आवश्यकता है, तो उसे इंटरनेट अनुमति की आवश्यकता होगी।\n\nसभी अनुमतियों और आधिकारिक दस्तावेज़ों के संदर्भ के लिए Android डेवलपर्स वेबसाइट पर एक नज़र डालें.\n\nAndroid ऐप्स को डिवाइस पर कुछ सुविधाओं या डेटा तक पहुंचने के लिए अनुमति का अनुरोध करना होगा। इन अनुमतियों का उपयोग उपयोगकर्ता और डिवाइस की गोपनीयता की रक्षा के लिए किया जाता है। जब कोई ऐप इंस्टॉल किया जाता है, तो उपयोगकर्ता को ऐप द्वारा अनुरोधित अनुमतियों को देने या अस्वीकार करने के लिए प्रेरित किया जाता है। ऐप को केवल उन सुविधाओं या डेटा तक पहुंच होगी जिनके लिए उसने अनुमति का अनुरोध किया था।\n\nदो प्रकार की अनुमतियाँ हैं: सामान्य और खतरनाक। सामान्य अनुमतियाँ उपयोगकर्ता की गोपनीयता के लिए कोई जोखिम नहीं पैदा करती हैं। उनमें इंटरनेट एक्सेस और वाइब्रेट जैसी चीजें शामिल हैं। खतरनाक अनुमतियाँ, दूसरी ओर, संवेदनशील जानकारी या कार्यों तक संभावित रूप से पहुंच सकती हैं और इसलिए अधिक प्रतिबंधित हैं। इनमें उपयोगकर्ता के स्थान, कैमरा और संपर्कों तक पहुंच जैसी अनुमतियाँ शामिल हैं।\n\nऐप डेवलपर्स के लिए केवल उन अनुमतियों का अनुरोध करना महत्वपूर्ण है जो उनके ऐप को ठीक से काम करने के लिए बिल्कुल आवश्यक हैं। यह उपयोगकर्ता की गोपनीयता की रक्षा करने में मदद करता है और ऐप को अधिक उपयोगकर्ता के अनुकूल भी बनाता है। इमेज बटन ऐसे बटन होते हैं जिनमें टेक्स्ट के बजाय एक छवि होती है। उनका उपयोग Android में अधिक दृश्य रूप से आकर्षक और इंटरैक्टिव उपयोगकर्ता इंटरफ़ेस प्रदान करने के लिए किया जा सकता है। इमेज बटन का उपयोग कार्यों को ट्रिगर करने, विभिन्न स्क्रीन पर नेविगेट करने या अतिरिक्त जानकारी प्रदर्शित करने के लिए किया जा सकता है। उपयोगकर्ता को बटन के उद्देश्य के बारे में स्पष्ट संचार प्रदान करने के लिए उन्हें अक्सर टेक्स्ट लेबल के संयोजन में उपयोग किया जाता है। It\'s been a while—learn something new about Android. + मेनू + बाहर निकलने के लिए फिर से दबाएं ऐप का एक नया संस्करण उपलब्ध है। अपडेट करने के लिए क्लिक करें. AndroidX AppCompatImageView ImageView का एक सबक्लास है जिसे ActionBar और Material Design की विभिन्न सुविधाओं का समर्थन करने के लिए डिज़ाइन किया गया है। यह AndroidX लाइब्रेरी का हिस्सा है, जो समर्थन लाइब्रेरीज़ का एक सेट है जो Android फ्रेमवर्क API के पिछड़े-संगत संस्करणों के साथ-साथ ऐसी सुविधाएँ प्रदान करता है जो केवल लाइब्रेरी API के माध्यम से उपलब्ध हैं।\n\nAppCompatImageView को ImageView के लिए एक ड्रॉप-इन प्रतिस्थापन के रूप में उपयोग करने का इरादा है, जिससे डेवलपर्स को Android के विभिन्न संस्करणों में समान कोड और UI तत्वों का उपयोग करने की अनुमति मिलती है। इसमें टेंटिंग, वेक्टर ड्रॉएबल्स लोड करने और इमेज स्केलिंग को संभालने जैसी विभिन्न सुविधाओं के लिए समर्थन शामिल है।\n\nAppCompatImageView में Material Design सुविधाओं के लिए भी समर्थन शामिल है जैसे कि एलिवेशन, जो इमेज व्यू को छाया डालने और लेआउट की सतह से ऊपर उठाए हुए दिखने की अनुमति देता है। इसमें Material Design रिपल प्रभाव के लिए भी समर्थन शामिल है, जो एक दृश्य प्रभाव है जो इमेज व्यू को स्पर्श करने पर लागू होता है।\n\nसंक्षेप में, AndroidX AppCompatImageView ImageView का एक बहुमुखी और सुविधा-संपन्न सबक्लास है जिसे Android ऐप्स में सुविधाओं और डिज़ाइन तत्वों की एक विस्तृत श्रृंखला का समर्थन करने के लिए डिज़ाइन किया गया है। लीनियर लेआउट कॉम्पैट Android सपोर्ट लाइब्रेरी ऐपकॉम्पैट v7 में एक क्लास है। इसे नए API स्तरों में पुरानी (जैसे डिवाइडर) में जोड़े गए तरीकों का समर्थन करने के लिए जोड़ा गया था। यदि आप LinearLayout और LinearLayoutCompat में विधियों की तुलना करते हैं, तो आप देख सकते हैं कि कॉम्पैट लेआउट में बिना किसी API स्तर की सीमा के लीनियर लेआउट के सभी तरीके हैं। उदाहरण के लिए, setShowDividers विधि API स्तर 11 पर पेश की गई थी। इसलिए, इस मामले में, यदि आप API स्तर 11 से नीचे के प्लेटफ़ॉर्म को लक्षित कर रहे हैं तो setShowDividers (और इसके पैरामीटर) को LinearLayout के बजाय Linear Layout Compat का उपयोग करके लागू किया जाना चाहिए। diff --git a/app/src/main/res/values-hu-rHU/strings.xml b/app/src/main/res/values-hu-rHU/strings.xml index f07a9d9d..0f111f82 100644 --- a/app/src/main/res/values-hu-rHU/strings.xml +++ b/app/src/main/res/values-hu-rHU/strings.xml @@ -1,6 +1,8 @@ Szerezd meg a Google Playen + Menü + Nyomja meg újra a Back gombot a kilépéshez Tudj meg többet Play Áruház Oktatóanyagok keresése diff --git a/app/src/main/res/values-in-rID/strings.xml b/app/src/main/res/values-in-rID/strings.xml index 49c4804d..a9e3908a 100644 --- a/app/src/main/res/values-in-rID/strings.xml +++ b/app/src/main/res/values-in-rID/strings.xml @@ -367,6 +367,8 @@ Misalnya, jika aplikasi Anda perlu mengunduh sesuatu, aplikasi tersebut akan memerlukan izin Internet.\n\nLihatlah situs web Pengembang Android untuk semua izin dan referensi ke dokumentasi resmi.\n\nAplikasi Android harus meminta izin untuk mengakses fitur atau data tertentu di perangkat. Izin ini digunakan untuk melindungi privasi pengguna dan perangkat. Ketika aplikasi diinstal, pengguna diminta untuk memberikan atau menolak izin yang diminta aplikasi. Aplikasi hanya akan memiliki akses ke fitur atau data yang dimintanya izin.\n\nAda dua jenis izin: normal dan berbahaya. Izin normal tidak menimbulkan risiko terhadap privasi pengguna. Ini termasuk hal-hal seperti akses internet dan getaran. Izin berbahaya, di sisi lain, berpotensi mengakses informasi atau tindakan sensitif dan karenanya lebih dibatasi. Ini termasuk izin seperti akses ke lokasi pengguna, kamera, dan kontak.\n\nPenting bagi pengembang aplikasi untuk hanya meminta izin yang mutlak diperlukan agar aplikasi mereka berfungsi dengan benar. Ini membantu melindungi privasi pengguna dan juga membuat aplikasi lebih ramah pengguna. Tombol gambar adalah tombol yang berisi gambar alih-alih teks. Mereka dapat digunakan di Android untuk menyediakan antarmuka pengguna yang lebih menarik secara visual dan interaktif. Tombol gambar dapat digunakan untuk memicu tindakan, menavigasi ke layar yang berbeda, atau menampilkan informasi tambahan. Mereka sering digunakan dalam kombinasi dengan label teks untuk memberikan komunikasi yang jelas kepada pengguna tentang tujuan tombol. It\'s been a while—learn something new about Android. + Menu + Tekan kembali lagi untuk keluar Versi baru aplikasi tersedia. Klik untuk memperbarui. AndroidX AppCompatImageView adalah subkelas dari ImageView yang dirancang untuk mendukung berbagai fitur ActionBar dan Material Design. Ini adalah bagian dari pustaka AndroidX, yang merupakan seperangkat pustaka dukungan yang menawarkan versi API kerangka kerja Android yang kompatibel ke belakang serta fitur yang hanya tersedia melalui API pustaka.\n\nAppCompatImageView dimaksudkan untuk digunakan sebagai pengganti drop-in untuk ImageView, memungkinkan pengembang untuk menggunakan kode dan elemen UI yang sama di berbagai versi Android. Ini termasuk dukungan untuk berbagai fitur seperti pewarnaan, pemuatan drawable vektor, dan penanganan penskalaan gambar.\n\nAppCompatImageView juga menyertakan dukungan untuk fitur Material Design seperti elevasi, yang memungkinkan tampilan gambar untuk menghasilkan bayangan dan tampak terangkat di atas permukaan tata letak. Ini juga menyertakan dukungan untuk efek riak Material Design, yang merupakan efek visual yang diterapkan saat tampilan gambar disentuh.\n\nSingkatnya, AndroidX AppCompatImageView adalah subkelas ImageView yang serbaguna dan kaya fitur yang dirancang untuk mendukung berbagai fitur dan elemen desain dalam aplikasi Android. Linear Layout Compat adalah kelas dalam pustaka dukungan Android appCompat v7. Ini ditambahkan untuk mendukung metode yang ditambahkan di level API yang lebih baru pada yang lama (seperti pembagi). Jika Anda membandingkan metode di LinearLayout dan LinearLayoutCompat, Anda dapat melihat bahwa tata letak Compat memiliki semua metode dari Tata Letak Linear tanpa batasan level API. Misalnya, metode setShowDividers diperkenalkan pada level API 11. Jadi, dalam kasus ini, setShowDividers (dan parameternya) harus dipanggil menggunakan Linear Layout Compat alih-alih LinearLayout jika Anda menargetkan platform dengan level API di bawah 11. diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml index f0ed25f6..c12b7fd1 100644 --- a/app/src/main/res/values-it-rIT/strings.xml +++ b/app/src/main/res/values-it-rIT/strings.xml @@ -1,6 +1,8 @@ Scaricalo su Google Play + Menu + Premi di nuovo per uscire Scopri di più Play Store Cerca tutorial diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index c8263975..874cb7c4 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -1,6 +1,8 @@ Google Play で入手しよう + メニュー + もう一度押して終了します 詳しく見る Play ストア チュートリアルを検索 diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index 9d146618..f415941a 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -5,6 +5,8 @@ 새로운 버전의 앱이 출시되었습니다. 클릭하여 업데이트하세요. 오랜만이에요. It\'s been a while—learn something new about Android. + 메뉴 + 뒤로가기를 한 번 더 누르면 종료됩니다 환영합니다 Read and agree to the Terms of Service and Privacy Policy to continue 동의 diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 0ada89e5..1978cd10 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -1,6 +1,8 @@ Pobierz z Google Play + Menu + Wciśnij ponownie, aby wyjść Dowiedz się więcej Sklep Play Wyszukaj samouczki diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 8494af4d..9073cdae 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -5,6 +5,8 @@ Uma nova versão do aplicativo está disponível. Clique para atualizar. Faz um tempo. It\'s been a while—learn something new about Android. + Menu + Pressione novamente para sair Bem-vindo Read and agree to the Terms of Service and Privacy Policy to continue Concordo diff --git a/app/src/main/res/values-ro-rRO/strings.xml b/app/src/main/res/values-ro-rRO/strings.xml index 9f74de50..71997d9a 100644 --- a/app/src/main/res/values-ro-rRO/strings.xml +++ b/app/src/main/res/values-ro-rRO/strings.xml @@ -367,6 +367,8 @@ De exemplu, dacă aplicația dvs. trebuie să descarce ceva, va necesita permisiunea Internet.\n\nAruncați o privire pe site-ul web Android Developers pentru toate permisiunile și o referință la documentația oficială.\n\nAplicațiile Android trebuie să solicite permisiunea de a accesa anumite funcționalități sau date pe un dispozitiv. Aceste permisiuni sunt utilizate pentru a proteja confidențialitatea utilizatorului și a dispozitivului. Când o aplicație este instalată, utilizatorului i se solicită să acorde sau să refuze permisiunile pe care le solicită aplicația. Aplicația va avea acces doar la funcționalitățile sau datele pentru care a solicitat permisiunea.\n\nExistă două tipuri de permisiuni: normale și periculoase. Permisiunile normale nu prezintă un risc pentru confidențialitatea utilizatorului. Acestea includ lucruri precum accesul la internet și vibrarea. Permisiunile periculoase, pe de altă parte, pot accesa potențial informații sau acțiuni sensibile și sunt, prin urmare, mai restricționate. Acestea includ permisiuni precum accesul la locația utilizatorului, camera și contactele.\n\nEste important ca dezvoltatorii de aplicații să solicite doar permisiunile care sunt absolut necesare pentru ca aplicația lor să funcționeze corect. Acest lucru ajută la protejarea confidențialității utilizatorului și, de asemenea, face aplicația mai ușor de utilizat. Butoanele imagine sunt butoane care conțin o imagine în loc de text. Ele pot fi utilizate în Android pentru a oferi o interfață de utilizator mai atractivă vizual și interactivă. Butoanele imagine pot fi utilizate pentru a declanșa acțiuni, a naviga la diferite ecrane sau a afișa informații suplimentare. Ele sunt adesea utilizate în combinație cu etichete text pentru a oferi o comunicare clară utilizatorului despre scopul butonului. It\'s been a while—learn something new about Android. + Meniu + Apăsați din nou pentru a ieși Este disponibilă o nouă versiune a aplicației. Apasă pentru a actualiza. AndroidX AppCompatImageView este o subclasă a ImageView care este proiectată să suporte diverse funcționalități ale ActionBar și Material Design. Face parte din biblioteca AndroidX, care este un set de biblioteci de suport ce oferă versiuni compatibile înapoi ale API-urilor framework-ului Android, precum și funcționalități disponibile doar prin API-urile bibliotecii.\n\nAppCompatImageView este conceput pentru a fi utilizat ca înlocuitor direct pentru ImageView, permițând dezvoltatorilor să utilizeze același cod și elemente UI în diferite versiuni de Android. Acesta include suport pentru diverse funcționalități, cum ar fi colorarea (tinting), încărcarea resurselor vectoriale (vector drawables) și gestionarea scalării imaginii.\n\nAppCompatImageView include, de asemenea, suport pentru funcționalități Material Design, cum ar fi elevația, care permite vizualizării imaginii să proiecteze o umbră și să pară ridicată deasupra suprafeței aspectului. Include, de asemenea, suport pentru efectul Material Design ripple, care este un efect vizual aplicat atunci când vizualizarea imaginii este atinsă.\n\nPe scurt, AndroidX AppCompatImageView este o subclasă versatilă și bogată în funcționalități a ImageView, concepută pentru a suporta o gamă largă de funcționalități și elemente de design în aplicațiile Android. Linear Layout Compat este o clasă din biblioteca de suport Android appCompat v7. A fost adăugată pentru a suporta metodele care au fost adăugate în niveluri API mai noi pe cele vechi (cum ar fi divizoarele). Dacă comparați metodele din LinearLayout și LinearLayoutCompat, puteți vedea că aspectul Compat are toate metodele LinearLayout fără nicio limitare a nivelului API. De exemplu, metoda setShowDividers a fost introdusă la nivelul API 11. Prin urmare, în acest caz, setShowDividers (și parametrii săi) ar trebui să fie invocate utilizând Linear Layout Compat în loc de LinearLayout dacă vizați o platformă cu nivel API sub 11. diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index cbff4ac8..43e64838 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -367,6 +367,8 @@ Например, если вашему приложению нужно что-то скачать, ему потребуется разрешение на доступ в Интернет.\n\nПосмотрите сайт Android Developers, чтобы узнать обо всех разрешениях и найти ссылки на официальную документацию.\n\nПриложения Android должны запрашивать разрешение на доступ к определенным функциям или данным на устройстве. Эти разрешения используются для защиты конфиденциальности пользователя и устройства. При установке приложения пользователю предлагается предоставить или отклонить запрошенные приложением разрешения. Приложение будет иметь доступ только к тем функциям или данным, для которых оно запросило разрешение.\n\nСуществует два типа разрешений: обычные и опасные. Обычные разрешения не представляют риска для конфиденциальности пользователя. К ним относятся такие вещи, как доступ в Интернет и вибрация. Опасные разрешения, с другой стороны, потенциально могут получить доступ к конфиденциальной информации или действиям и поэтому более ограничены. К ним относятся такие разрешения, как доступ к местоположению пользователя, камере и контактам.\n\nВажно, чтобы разработчики приложений запрашивали только те разрешения, которые абсолютно необходимы для правильного функционирования их приложения. Это помогает защитить конфиденциальность пользователя, а также делает приложение более удобным для пользователя. Кнопки-изображения — это кнопки, которые содержат изображение вместо текста. Их можно использовать в Android для создания более визуально привлекательного и интерактивного пользовательского интерфейса. Кнопки-изображения могут использоваться для запуска действий, навигации по различным экранам или отображения дополнительной информации. Часто они используются в сочетании с текстовыми метками для обеспечения четкой связи с пользователем о назначении кнопки. It\'s been a while—learn something new about Android. + Меню + Нажмите снова, чтобы выйти Доступна новая версия приложения. Нажмите, чтобы обновить. AndroidX AppCompatImageView — это подкласс ImageView, разработанный для поддержки различных функций ActionBar и Material Design. Он является частью библиотеки AndroidX, которая представляет собой набор вспомогательных библиотек, предлагающих обратно совместимые версии API фреймворка Android, а также функции, доступные только через API библиотеки.\n\nAppCompatImageView предназначен для использования в качестве прямой замены ImageView, что позволяет разработчикам использовать один и тот же код и элементы пользовательского интерфейса в разных версиях Android. Он включает поддержку различных функций, таких как тонирование, загрузка векторных ресурсов и обработка масштабирования изображений.\n\nAppCompatImageView также включает поддержку функций Material Design, таких как возвышение, которое позволяет представлению изображения отбрасывать тень и выглядеть приподнятым над поверхностью макета. Он также включает поддержку эффекта Material Design ripple, который представляет собой визуальный эффект, применяемый при касании представления изображения.\n\nВ заключение, AndroidX AppCompatImageView — это универсальный и многофункциональный подкласс ImageView, разработанный для поддержки широкого спектра функций и элементов дизайна в приложениях Android. Linear Layout Compat — это класс в библиотеке поддержки Android appCompat v7. Он был добавлен для поддержки методов, которые были добавлены в более новые уровни API для старых (например, разделителей). Если вы сравните методы в LinearLayout и LinearLayoutCompat, вы увидите, что макет Compat имеет все методы LinearLayout без каких-либо ограничений по уровню API. Например, метод setShowDividers был введен на уровне API 11. Таким образом, в этом случае setShowDividers (и его параметры) следует вызывать с использованием Linear Layout Compat вместо LinearLayout, если вы ориентируетесь на платформу с уровнем API ниже 11. diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index 32ad478b..7311c540 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -5,6 +5,8 @@ En ny version av appen finns tillgänglig. Klicka för att uppdatera. Det var ett tag sen. It\'s been a while—learn something new about Android. + Meny + Tryck tillbaka igen för att avsluta Välkommen Read and agree to the Terms of Service and Privacy Policy to continue Godkänn diff --git a/app/src/main/res/values-th-rTH/strings.xml b/app/src/main/res/values-th-rTH/strings.xml index a0562d09..f1cadd35 100644 --- a/app/src/main/res/values-th-rTH/strings.xml +++ b/app/src/main/res/values-th-rTH/strings.xml @@ -5,6 +5,8 @@ แอปเวอร์ชันใหม่พร้อมใช้งานแล้ว คลิกเพื่ออัปเดต. ไม่ได้เจอกันนานเลย. It\'s been a while—learn something new about Android. + เมนู + กดกลับอีกครั้งเพื่อออก ยินดีต้อนรับ Read and agree to the Terms of Service and Privacy Policy to continue ยอมรับ diff --git a/app/src/main/res/values-tr-rTR/strings.xml b/app/src/main/res/values-tr-rTR/strings.xml index 072faf5b..ee0f38d5 100644 --- a/app/src/main/res/values-tr-rTR/strings.xml +++ b/app/src/main/res/values-tr-rTR/strings.xml @@ -5,6 +5,8 @@ Uygulamanın yeni bir sürümü mevcut. Güncellemek için tıklayın. Görüşmeyeli uzun zaman oldu. It\'s been a while—learn something new about Android. + Menü + Çıkmak için tekrar basın Hoş geldiniz Read and agree to the Terms of Service and Privacy Policy to continue Kabul Et diff --git a/app/src/main/res/values-uk-rUA/strings.xml b/app/src/main/res/values-uk-rUA/strings.xml index 73726608..5169eaa1 100644 --- a/app/src/main/res/values-uk-rUA/strings.xml +++ b/app/src/main/res/values-uk-rUA/strings.xml @@ -5,6 +5,8 @@ Доступна нова версія програми. Натисніть, щоб оновити. Давно не бачились. It\'s been a while—learn something new about Android. + Меню + Натисніть ще раз, щоб вийти Ласкаво просимо Read and agree to the Terms of Service and Privacy Policy to continue Погоджуюсь diff --git a/app/src/main/res/values-ur-rPK/strings.xml b/app/src/main/res/values-ur-rPK/strings.xml index a5a846b2..82eb66ec 100644 --- a/app/src/main/res/values-ur-rPK/strings.xml +++ b/app/src/main/res/values-ur-rPK/strings.xml @@ -5,6 +5,8 @@ ایپ کا نیا ورژن دستیاب ہے۔ اپڈیٹ کرنے کے لیے کلک کریں. کافی وقت ہو گیا ہے. It\'s been a while—learn something new about Android. + مینو + باہر نکلنے کے لئے دوبارہ دبائیں خوش آمدید Read and agree to the Terms of Service and Privacy Policy to continue اتفاق کریں diff --git a/app/src/main/res/values-vi-rVN/strings.xml b/app/src/main/res/values-vi-rVN/strings.xml index ac2f5a03..6dbbfd74 100644 --- a/app/src/main/res/values-vi-rVN/strings.xml +++ b/app/src/main/res/values-vi-rVN/strings.xml @@ -5,6 +5,8 @@ Đã có phiên bản mới của ứng dụng. Nhấp để cập nhật. Đã lâu không gặp. It\'s been a while—learn something new about Android. + Menu + Nhấn lại một lần nữa để thoát Chào mừng Read and agree to the Terms of Service and Privacy Policy to continue Đồng ý diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 084dc71b..6e4cae87 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -5,6 +5,8 @@ 應用程式有新版本可用。點擊更新! 好久不見! It\'s been a while—learn something new about Android. + 選單 + 再按一次返回鍵退出 歡迎 Read and agree to the Terms of Service and Privacy Policy to continue 同意