Categories
discuss

Testing fragment: I keep getting java.lang.RuntimeException: android.view.InflateException

I was following this codelab about Material Components and after finishing it I thought I should practice writing some instrumentation tests. The app works fine. But I keep getting this error when I run any of the tests:

    java.lang.RuntimeException: android.view.InflateException: Binary XML file line #37: Binary 
    XML file line #37: Error inflating class 
    com.google.android.material.textfield.TextInputLayout
    at androidx.test.runner.MonitoringInstrumentation.runOnMainSync(MonitoringInstrumentation.java:450)
    at androidx.test.core.app.ActivityScenario.onActivity(ActivityScenario.java:564)
    at androidx.fragment.app.testing.FragmentScenario.internalLaunch(FragmentScenario.java:300)
    at androidx.fragment.app.testing.FragmentScenario.launchInContainer(FragmentScenario.java:282)
    at com.google.codelabs.mdc.kotlin.shrine.LoginFragmentTest.username_and_password_editTexts_visible(LoginFragmentTest.kt:64)
    at java.lang.reflect.Method.invoke(Native Method)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
    at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
    at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:395)
    at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1941)
    Caused by: android.view.InflateException: Binary XML file line #37: Binary XML file line #37: Error inflating class com.google.android.material.textfield.TextInputLayout
    Caused by: android.view.InflateException: Binary XML file line #37: Error inflating class com.google.android.material.textfield.TextInputLayout
    Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Constructor.newInstance0(Native Method)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
    at android.view.LayoutInflater.createView(LayoutInflater.java:645)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:787)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:858)
    at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:861)
    at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
    at com.google.codelabs.mdc.kotlin.shrine.LoginFragment.onCreateView(LoginFragment.kt:19)
    at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698)
    at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:320)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
    at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
    at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447)
    at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2169)
    at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1992)
    at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1947)
    at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1818)
    at androidx.fragment.app.BackStackRecord.commitNow(BackStackRecord.java:297)
    at androidx.fragment.app.testing.FragmentScenario$1.perform(FragmentScenario.java:317)
    at androidx.fragment.app.testing.FragmentScenario$1.perform(FragmentScenario.java:301)
    at androidx.test.core.app.ActivityScenario.lambda$onActivity$2$ActivityScenario(ActivityScenario.java:551)
    at androidx.test.core.app.ActivityScenario$$Lambda$4.run(Unknown Source)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at android.app.Instrumentation$SyncRunnable.run(Instrumentation.java:1959)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6236)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)
    Caused by: java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.MaterialComponents (or a descendant).
    at com.google.android.material.internal.ThemeEnforcement.checkTheme(ThemeEnforcement.java:248)
    at com.google.android.material.internal.ThemeEnforcement.checkMaterialTheme(ThemeEnforcement.java:222)
    at com.google.android.material.internal.ThemeEnforcement.checkCompatibleTheme(ThemeEnforcement.java:150)
    at com.google.android.material.internal.ThemeEnforcement.obtainTintedStyledAttributes(ThemeEnforcement.java:120)
    at com.google.android.material.textfield.TextInputLayout.<init>(TextInputLayout.java:424)
    at com.google.android.material.textfield.TextInputLayout.<init>(TextInputLayout.java:396)
    ... 38 more

    Test running failed: Instrumentation run failed due to 'Process crashed.'

My gradle dependencies:

dependencies {
    implementation 'com.google.android.material:material:1.1.0'
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'com.android.volley:volley:1.1.1'
    implementation 'com.google.code.gson:gson:2.8.6'
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    testImplementation 'junit:junit:4.13'
    androidTestImplementation 'androidx.test:core:1.2.0'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test:runner:1.3.0-alpha04'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0-alpha04'
    debugImplementation ('androidx.fragment:fragment-testing:1.2.2'){
        exclude group: 'androidx.test', module : 'core'
    }
}

I tried changing the Material dependency’s version but with no luck.

My styles file:

    <style name="AppTheme.NoActionBar" parent="Theme.MaterialComponents.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

Fragment layout file:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/loginPageBackgroundColor"
    tools:context=".LoginFragment">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clipChildren="false"
        android:clipToPadding="false"
        android:orientation="vertical"
        android:padding="24dp"
        android:paddingTop="16dp">

        <ImageView
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="48dp"
            android:layout_marginBottom="16dp"
            app:srcCompat="@drawable/shr_logo"
            android:contentDescription="@string/shr_logo_content_description"  />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginBottom="132dp"
            android:text="@string/shr_app_name"
            android:textAllCaps="true"
            android:textSize="16sp" />

        <com.google.android.material.textfield.TextInputLayout
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:layout_margin="4dp"
            android:hint="@string/shr_hint_username"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
            >
            <com.google.android.material.textfield.TextInputEditText
                android:id="@+id/username_edit_text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/password_text_input"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="4dp"
            android:hint="@string/shr_hint_password"
            app:errorEnabled="true"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
            android:inputType="textPassword"
            >
            <com.google.android.material.textfield.TextInputEditText
                android:id="@+id/password_edit_text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </com.google.android.material.textfield.TextInputLayout>
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <com.google.android.material.button.MaterialButton
                android:id="@+id/next_button"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_alignParentRight="true"
                android:text = "@string/shr_button_next"
                />
            <com.google.android.material.button.MaterialButton
                android:id="@+id/cancel_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="12dp"
                android:layout_marginRight="12dp"
                android:layout_toStartOf="@id/next_button"
                android:layout_toLeftOf="@id/next_button"
                android:text="@string/shr_button_cancel"
                style="@style/Widget.MaterialComponents.Button.TextButton"
                />
        </RelativeLayout>

        <!-- Snippet from "Add buttons" section goes here. -->

    </LinearLayout>
</ScrollView>

The code on line 37 is the first TextInputLayout

The fragment implementation:

import android.os.Bundle
import android.text.Editable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.shr_login_fragment.*
import kotlinx.android.synthetic.main.shr_login_fragment.view.*


class LoginFragment : Fragment() {

    override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.shr_login_fragment, container, false)
        view.next_button.setOnClickListener {
            if(isPasswordValid(password_edit_text.text)){
                view.password_text_input.error = null
                // the false so as to not return back to the login screen again
                (activity as NavigationHost).navigateTo(ProductGridFragment(),false)
            }else{
                view.password_text_input.error = getString(R.string.shr_error_password)
            }
        }
        view.password_edit_text.setOnKeyListener { _, _, _ ->
            if(isPasswordValid(password_edit_text.text)){
                view.password_text_input.error = null
            }
            false
        }
        view.cancel_button.setOnClickListener {
            view.password_edit_text.setText("")
            view.username_edit_text.setText("")
        }
        return view
    }
    private fun isPasswordValid(text: Editable?): Boolean{
        return text!=null && text.length >= 8
    }
}

Answer

This was the problem :

Caused by: java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.MaterialComponents (or a descendant).

We need to supply the correct style to the fragment test class. In your layout files, there is material component view (TextInputLayout), so we need to use the MaterialComponents theme.

When creating the FragmentTest class, use style arguments:

@RunWith(AndroidJUnit4::class)
class DummyFragmentTest {

    @Test
    fun testing() {
        launchFragmentInContainer<DummyFragment>(factory = object : FragmentFactory() {
            override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
                return DummyFragment()
            }
        }, themeResId = R.style.AppTheme.NoActionBar) // this is your style
    }
}
Categories
discuss

Android SDK Tools option is missing from SDK Manager in Android Studio 3.6.1

On a freshly installed macOS Catalina, I installed Android Studio 3.6.1.

I’ve got the following error when I ran flutter doctor in the course of setting up flutter SDK on my Mac.

[!] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
    ✗ Android license status unknown.
        Try re-installing or updating your Android SDK Manager.
        See https://developer.android.com/studio/#downloads or visit
        https://flutter.dev/setup/#android-setup for detailed instructions.

I re-installed Android Studio and follow the instructions in the second link in the error message, but these links do not seem to help resolving the issue. I also tried the following:

$ flutter doctor  --android-licenses

Which gives the following error:

Android sdkmanager tool not found
(/Users/username/Library/Android/sdk/tools/bin/sdkmanager).
Try re-installing or updating your Android SDK,
visit https://flutter.dev/setup/#android-setup for detailed instructions.

I checked my installation and found out that tools directory is missing under ~/Library/Android/sdk/.

Also, I found out Android SDK Tools option is missing from SDK Tools tab in SDK Manager of the Android Studio as shown in this screenshot. (Android SDK Tools option was present on my previous installation of Android Studio 3.5.3.)

Has anyone had the similar problem? I am not sure what I’m doing wrong. If anyone can show me how I can fix this issue, I’d appreciate it! (This is my first question on Stack Overflow. Please excuse me for lengthy post.)

Answer

I’m using Linux but I guess the problem might be the same.

Launch Android Studio and go to “SDK Manager” – you can launch it after creating a blank project and going “Tools -> SDK Manager” under the “AVD Manager” option. In the new window open “System Settings -> Android SDK”. From there pick “SDK Tools”. Now you need to uncheck the “Hide Obsolete Packages” option in the bottom of the window. Now there should appear a new option: “Android SDK Tools (Obsolete)” – check that, hit “Apply” – it will download the files and “Tools” folder will appear in the Android folder. Then simply run “flutter doctor” in the terminal and you should be asked to accept some licenses – simply run:

$ flutter doctor --android-licenses

It helped me. I don’t know why this option went obsolete when Flutter requires it anyway. Check the settings printscreen.

enter image description here

Categories
discuss

How can I make an Android splash screen with text & background color that changes if my phone is in light or dark mode?

I have been working on this for some time and unfortunately I’ve not been able to achieve the desired effect without using an image. I have researched on Stack Overflow and almost everywhere and still found no solution that does exactly this.

What I am still trying to do is this:

  • Phone is in light mode > Splash screen has a white background with the word ABC in black in the center

  • Phone is in dark mode > Splash screen has a black background with the word ABC in white in the center

Here is what I have so far:

SplashActivity.cs

namespace Japanese.Droid
{
    [Activity(Label = "Anki+", Theme = "@style/LaunchTheme", MainLauncher = true, NoHistory = true)]
    public class SplashActivity : Activity
    {

styles.xaml

<style name="LaunchTheme" parent="Theme.AppCompat">
    <item name="android:windowBackground">@drawable/splash_screen</item>
    <item name="android:navigationBarColor">#ffffff</item>
</style>

splash_screen.xaml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/white"/>
    <item>
        <bitmap android:src="@drawable/splash_logo"
                android:tileMode="disabled"
                android:gravity="center"
                android:layout_gravity="center"/>
    </item>
</layer-list>

splash_screen_night.xaml

<?xml version="1.0" encoding="UTF-8" ?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/black"/>
    <item>
        <bitmap android:src="@drawable/splash_logo"
                android:tileMode="disabled"
                android:gravity="center"
                android:layout_gravity="center"/>
    </item>
</layer-list>

splash_activity

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Support.V7.App;
using Android.Views;

namespace Test.Droid
{
    [Activity(Label = "Test+", Theme = "@style/LaunchTheme", MainLauncher = true, NoHistory = true)]
    public class SplashActivity : Activity
    {

        public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
        {
            base.OnCreate(savedInstanceState, persistentState);

            //==================================== Code to hide the bottom 3 buttons on Android.
            int uiOptions = (int)Window.DecorView.SystemUiVisibility;
            uiOptions |= (int)SystemUiFlags.LowProfile;
            uiOptions |= (int)SystemUiFlags.Fullscreen;
            uiOptions |= (int)SystemUiFlags.HideNavigation;
            uiOptions |= (int)SystemUiFlags.ImmersiveSticky;
            Window.DecorView.SystemUiVisibility = (StatusBarVisibility)uiOptions;
            //===================================

            base.SetTheme(Resource.Style.MainTheme);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        }

        // Launches the startup task
        protected override void OnResume()
        {
            base.OnResume();

            //==================================== Code to hide the bottom 3 buttons on Android.
            int uiOptions = (int)Window.DecorView.SystemUiVisibility;
            uiOptions |= (int)SystemUiFlags.LowProfile;
            uiOptions |= (int)SystemUiFlags.Fullscreen;
            uiOptions |= (int)SystemUiFlags.HideNavigation;
            uiOptions |= (int)SystemUiFlags.ImmersiveSticky;
            Window.DecorView.SystemUiVisibility = (StatusBarVisibility)uiOptions;
            //===================================

            System.Threading.Tasks.Task startupWork = new System.Threading.Tasks.Task(() => { SimulateStartup(); });
            startupWork.Start();
        }


        // Simulates background work that happens behind the splash screen
        async void SimulateStartup()
        {
            await System.Threading.Tasks.Task.Delay(1000); // Simulate a bit of startup work.
            StartActivity(new Intent(Application.Context, typeof(MainActivity)));
        }

        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }

        public override void OnBackPressed() { }
    }
}

This uses an image but I would like to do it with text.

Does anyone know of a way to do it. I’ve researched this as much as possible, asked for help from two Android devs but still nobody can come up with a simple solution to do this without using an image.

Is it possible to do this with text only and not an image for my Xamarin Android application?

Answer

To echieve this you need to make a SplashScreen.xml in the Layout folder in Android Project. Also you need to make the styles in two folders, values and values-night.

Also you need a separate SplashActivity.cs. I am attaching the code herewith.

  1. SplashScreen.xml

      <?xml version="1.0" encoding="utf-8"?>
      <RelativeLayout 
       xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:gravity="center_vertical" 
       android:background="#fff"
       android:id="@+id/splashview">
       <TextView
            android:id="@+id/txtAppVersion"
            android:text="Anki+"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_marginLeft="30dp"
            android:layout_marginBottom="30dp"
            android:textColor="#000"
            android:textSize="24sp"
            android:gravity="center_vertical" 
            android:layout_centerHorizontal="true"/>
        </RelativeLayout>
    
  2. Styles.xml in values folder.

    <style name="MainTheme" parent="MainTheme.Base">
        <item name="android:textAllCaps">false</item>
    </style>
    
    <style name="MainTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="windowNoTitle">true</item>
        <item name="windowActionBar">false</item>
        <item name="windowActionModeOverlay">true</item>
        <item name="elevation">0dp</item>
    </style>
    
    <style name="LaunchTheme" parent="Theme.AppCompat">
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowActionBar">false</item>
        <item name="android:windowFullscreen">true</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowDisablePreview">true</item>
    </style>
    

  3. Styles.xml in values-night folder.

    <style name="MainTheme" parent="MainTheme.Base">
        <item name="android:textAllCaps">false</item>
    </style>
    
    <style name="MainTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="windowNoTitle">true</item>
        <item name="windowActionBar">false</item>
        <item name="windowActionModeOverlay">true</item>
        <item name="elevation">0dp</item>
    </style>
    
    <style name="LaunchTheme" parent="Theme.AppCompat">
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowActionBar">false</item>
        <item name="android:windowFullscreen">true</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowDisablePreview">true</item>
    </style>
    

  4. SplashActivity.cs

    using System;
    using Android.App;
    using Android.Content;
    using Android.Content.Res;
    using Android.OS;
    using Android.Runtime;
    using Android.Views;
    using Android.Widget;
    using Plugin.CurrentActivity;
    
    namespace MyProject.Droid
    {
        [Activity(Label = "MyProject+", Theme = "@style/LaunchTheme", 
    MainLauncher = true, NoHistory = true)]
    public class SplashActivity : Activity
    {
    
        public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
        {
            base.OnCreate(savedInstanceState, persistentState);
    
            //==================================== Code to hide the bottom 3 buttons on Android.
            int uiOptions = (int)Window.DecorView.SystemUiVisibility;
            uiOptions |= (int)SystemUiFlags.LowProfile;
            uiOptions |= (int)SystemUiFlags.Fullscreen;
            uiOptions |= (int)SystemUiFlags.HideNavigation;
            uiOptions |= (int)SystemUiFlags.ImmersiveSticky;
            Window.DecorView.SystemUiVisibility = (StatusBarVisibility)uiOptions;
            //===================================
    
            base.SetTheme(Resource.Style.MainTheme);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        }
    
        // Launches the startup task
        protected override void OnResume()
        {
            base.OnResume();
            SetContentView(Resource.Layout.SplashScreen);
            bool isDarkTheme;
    
            //var isDarkTheme = Preferences.Get("isDarkTheme", false);
            if (Build.VERSION.SdkInt >= BuildVersionCodes.Froyo)
            {
                var uiModeFlags = CrossCurrentActivity.Current.AppContext.Resources.Configuration.UiMode & UiMode.NightMask;
                if (uiModeFlags == UiMode.NightYes)
                    isDarkTheme = true;
                else isDarkTheme = false;
            }
            else
                isDarkTheme = false;
    
            if (isDarkTheme)
            {
                FindViewById<RelativeLayout>(Resource.Id.splashview).SetBackgroundColor(Android.Graphics.Color.ParseColor("#000000"));
                FindViewById<TextView>(Resource.Id.txtAppVersion).SetTextColor(Android.Graphics.Color.ParseColor("#FFFFFF"));
            }
            else
            {
                FindViewById<RelativeLayout>(Resource.Id.splashview).SetBackgroundColor(Android.Graphics.Color.ParseColor("#FFFFFF"));
                FindViewById<TextView>(Resource.Id.txtAppVersion).SetTextColor(Android.Graphics.Color.ParseColor("#000000"));
            }
    
            // FindViewById<TextView>(Resource.Id.txtAppVersion).Text = $"Version {PackageManager.GetPackageInfo(PackageName, 0).VersionName}";
    
            //==================================== Code to hide the bottom 3 buttons on Android.
            int uiOptions = (int)Window.DecorView.SystemUiVisibility;
            uiOptions |= (int)SystemUiFlags.LowProfile;
            uiOptions |= (int)SystemUiFlags.Fullscreen;
            uiOptions |= (int)SystemUiFlags.HideNavigation;
            uiOptions |= (int)SystemUiFlags.ImmersiveSticky;
            Window.DecorView.SystemUiVisibility = (StatusBarVisibility)uiOptions;
            //===================================
    
            System.Threading.Tasks.Task startupWork = new System.Threading.Tasks.Task(() => { SimulateStartup(); });
            startupWork.Start();
        }
    
        // Simulates background work that happens behind the splash screen
        async void SimulateStartup()
        {
            await System.Threading.Tasks.Task.Delay(1000); // Simulate a bit of startup work.
            StartActivity(new Intent(Application.Context, typeof(MainActivity)));
        }
    
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    
        public override void OnBackPressed() { }
    }
    }
    
Categories
discuss

View Bindings not generating

I’m currently trying out the new ViewBindings but i’m not getting them to work. I’m on Android Studio 3.6.1. I just created a new project and added viewBinding.enabled = true to my modules build.gradle. But when I try to access the MainActivityBinding class, it says it cannot resolve the symbol. Autocomplete doesn’t find anything resembling a binding class. I also tried with a different project using Kotlin but no success there. AS4.0 doesn’t help either. What do I need to do to generate the ViewBinding classes?

My build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"
    viewBinding {
        enabled = true
    }

    defaultConfig {
        applicationId "com.example.myapplication"
        minSdkVersion 29
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

Answer

I couldn’t find my ViewBinding files until it dawned on me that the bindings were being named after the XML files (“fragment_home.xml”) and not after the class (“HomeFragment.kt”). So I couldn’t find them at HomeFragmentBinding but I found them at FragmentHomeBinding.

I found it helpful to think of each ViewBinding as a helper singleton that has been created as that XML file’s delegate.

(Edited to removed obsolete Gradle stuff)

Categories
discuss

Why to use separate CSS files for components in React.js

I am new to Web Development and currently learning React.js. I learned about how to create Components in React and giving styles to them.

Is it like that if I create separate CSS files for React Components, the app will load faster because the browser has to load small sized CSS files instead of single big file?

I want to ask about how React loads the CSS files in the browser and whether I should use separate CSS files for React Components.

Answer

Yes, you want separate files. No, the reason why you do it isn’t for performance (although it certainly can have an impact on performance).

You’re missing that components should be re-usable.

If I create an AwesomeWidget component and I want to drop it straight into another project I’m working on then I should be able to do that with as little friction as possible. And you can’t do that if its styles are mixed in with application-specific stuff. Your components should be, insofar as is possible, independent of what’s around them.

Keep the component-specific files separate and let Webpack do the work of wiring it all up for you. If you find yourself reusing a component enough then move it into its own repo (don’t forget you can npm install from a git url if you don’t want to publish it to the public package registry).

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..