Search code examples
androidandroid-layouttimeoutdelaypadding

Adding views after timeout causes padding on other views to go awry - Android


I'm having an issue that when I add views after a delay this changes the padding on my alphabet buttons when I click on them.

MainActivity:

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            LinearLayout linearLayout = findViewById(R.id.lettersToGuess);

            LayoutInflater layoutInflater = (LayoutInflater)getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            TextView asdfsdfanotherTV = (TextView) layoutInflater.inflate(R.layout.guessing_letter_text_view, linearLayout, false);

            linearLayout.addView(asdfsdfanotherTV);
        }
    }, 1000);
}


}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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/white"
    tools:context=".MainActivity"
    android:id="@+id/constraintLayout">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/lettersToGuess"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:layout_marginBottom="32dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:gravity="center_horizontal"
        android:orientation="horizontal"
        app:layout_constraintBottom_toTopOf="@+id/theTableLayout"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"

        tools:context=".ui.mainActivity.MainActivity">
        <TextView
            android:id="@+id/product_name"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:padding="5dip"
            android:text=""
            android:textSize="16dip"
            android:textStyle="bold"
            android:gravity="center"
            android:layout_marginLeft="5dp"
            android:background="@drawable/textlines"
            android:backgroundTint="@color/colorPrimary"
            xmlns:android="http://schemas.android.com/apk/res/android"
            />
    </LinearLayout>

    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="32dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:id="@+id/theTableLayout">

        <TableRow
            android:layout_height="match_parent"
            android:layout_width="match_parent"
            android:weightSum="7">

            <Button xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/buttonA"
                style="@style/Widget.AppCompat.Button.Borderless"
                android:layout_width="0dp"
                android:layout_height="wrap_content"



                android:text="A"
                android:theme="@style/AlphabetButton"
                android:soundEffectsEnabled="false"
                android:layout_weight="1"/>

            <Button xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/buttonB"
                style="@style/Widget.AppCompat.Button.Borderless"
                android:layout_width="0dp"
                android:layout_height="wrap_content"

                android:text="B"
                android:theme="@style/AlphabetButton"
                android:soundEffectsEnabled="false"
                android:layout_weight="1"/>


            <Button xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/buttonC"
                style="@style/Widget.AppCompat.Button.Borderless"
                android:layout_width="0dp"
                android:layout_height="wrap_content"

                android:text="C"
                android:theme="@style/AlphabetButton"
                android:soundEffectsEnabled="false"
                android:layout_weight="1"/>

            <Button xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/buttonD"
                style="@style/Widget.AppCompat.Button.Borderless"
                android:layout_width="0dp"
                android:layout_height="wrap_content"

                android:text="D"
                android:theme="@style/AlphabetButton"
                android:soundEffectsEnabled="false"
                android:layout_weight="1"/>


            <Button xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/buttonE"
                style="@style/Widget.AppCompat.Button.Borderless"
                android:layout_width="0dp"
                android:layout_height="wrap_content"

                android:text="E"
                android:theme="@style/AlphabetButton"
                android:soundEffectsEnabled="false"
                android:layout_weight="1"/>

            <Button xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/buttonF"
                style="@style/Widget.AppCompat.Button.Borderless"
                android:layout_width="0dp"
                android:layout_height="wrap_content"

                android:text="F"
                android:theme="@style/AlphabetButton"
                android:soundEffectsEnabled="false"
                android:layout_weight="1"/>


            <Button xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/buttonG"
                style="@style/Widget.AppCompat.Button.Borderless"
                android:layout_width="0dp"
                android:layout_height="wrap_content"

                android:text="G"
                android:theme="@style/AlphabetButton"
                android:soundEffectsEnabled="false"
                android:layout_weight="1"/>

        </TableRow>

    </TableLayout>
</android.support.constraint.ConstraintLayout>

textlines.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item>
        <shape android:shape="rectangle" >
            <solid android:color="#000000" />
        </shape>
    </item>
    <item android:bottom="3dp" >
        <shape android:shape="rectangle" >
            <solid android:color="#ffffff"/>
        </shape>
    </item>

</layer-list>

styles.xml

    <resources>

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

    <style name="AlphabetButton" parent="Theme.AppCompat.Light">
        <item name="colorControlHighlight">@color/colorAccent</item>
    </style>

</resources>

guessing_letter_text_view.xml

<TextView
android:id="@+id/product_name"
android:layout_width="30dp"
android:layout_height="30dp"
android:padding="5dip"
android:text=""
android:textSize="16dip"
android:textStyle="bold"
android:gravity="center"
android:layout_marginLeft="5dp"
android:background="@drawable/textlines"
xmlns:android="http://schemas.android.com/apk/res/android" />

As you can see, the 'D' button has been clicked and the padding has been adjusted which is not what I want to happen. What makes it even more weird is that if I have the view added without a timeout, my problem disappears. Does anyone know a way to add views after a timeout but not have them mess up padding of other views?

Thanks


Solution

  • For some unknown reason when you add the view programmatically with a delay, the constraint layout get messed up.

    So you have to "reapply" it after the delay.

    Check it out:

    public class MainActivity extends AppCompatActivity {
    
       @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            final ConstraintLayout layout = (ConstraintLayout)findViewById(R.id.constraintLayout);
            final ConstraintSet set = new ConstraintSet();
            set.clone(layout); //clone the layout first
    
    
            final Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    LinearLayout linearLayout = findViewById(R.id.lettersToGuess);
    
                    LayoutInflater layoutInflater = (LayoutInflater)getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    TextView asdfsdfanotherTV = (TextView) layoutInflater.inflate(R.layout.guessing_letter_text_view, linearLayout, false);
    
                    linearLayout.addView(asdfsdfanotherTV);
    
    
                   set.applyTo(layout); //reapply the cloned layout
                }
            }, 1000);
        }
    }
    

    I've tested on my device and it works. See if it works for you too.

    Hope this helps.