9

I have been trying my hands on ConstraintLayout and so far I have liked it a lot except now I have run into a peculiar problem. The same layout, if I design using a RelativeLayout displays the color of the contained TextViews as the default text color(greyish) but with ConstraintLayout, it shows white.

This happens on both a real device as well as an emulator with Android 5.0 but not on emulator(7.0). Does anyone know, why might this be happening?

Also, the obvious solution seems to be manually styling the color of the TextView in the layout to what it should be but that seems like a hack than a solution. I would be interested in knowing, why this is happening in the first place and if this hack is the only solution? (I prefer not fixing it by forcing a color on TextView as the behavior is correct on Android 7.0)

EDIT: Forgot to mention that the Layout Editor shows them both as black/greyish so that is also a cue that the actual color should not be white.


For your reference, here are the 2 layouts that are more or less same(there is a Button in one of them and TextView instead of Button in the other) in which one is faulty.

The layout that shows it white(issue in focus):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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="wrap_content"
    android:layout_marginTop="4dp"
    android:layout_marginBottom="4dp"
    android:layout_marginLeft="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginRight="8dp"
    android:layout_marginEnd="8dp"
    android:background="@color/lightGrey">


    <android.support.constraint.ConstraintLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:paddingBottom="10dp"
        android:elevation="2dp"
        android:id="@+id/constraintLayout">


        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintTop_toTopOf="parent"
            android:layout_marginLeft="16dp"
            android:layout_marginStart="16dp"
            android:layout_marginTop="16dp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toLeftOf="@+id/guideline"
            android:layout_marginRight="8dp"
            android:layout_marginEnd="8dp"
            app:layout_constraintHorizontal_bias="0.0"
            android:id="@+id/linearLayout"
            tools:layout_editor_absoluteY="16dp">

            <TextView
                android:text="@string/tutor_name"
                android:textStyle="bold"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/tutor_name"/>

            <TextView
                android:text="@string/tutor_skill_set"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="12dp"
                android:id="@+id/skill_set"/>

            <TextView
                android:text="@string/tutor_types"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="12dp"
                android:id="@+id/tutor_types" />

            <TextView
                android:text="@string/tutor_location"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/location"
                android:layout_marginTop="12dp" />

        </LinearLayout>


        <ImageView
            android:id="@+id/display_pic"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_marginEnd="16dp"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="16dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="16dp"
            android:adjustViewBounds="false"
            android:scaleType="centerCrop"
            app:layout_constraintHorizontal_bias="1.0"
            app:layout_constraintLeft_toLeftOf="@+id/guideline"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@android:color/holo_red_light" />

        <com.iarcuschin.simpleratingbar.SimpleRatingBar
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/tutor_rating"
            android:layout_below="@+id/display_pic"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            app:srb_starSize="13dp"
            app:srb_numberOfStars="5"
            app:srb_borderColor="@color/colorAccent"
            app:srb_fillColor="@color/colorPrimary"
            app:srb_starBorderWidth="1"
            app:srb_isIndicator="true"
            app:layout_constraintRight_toRightOf="@+id/display_pic"
            android:layout_marginTop="8dp"
            app:layout_constraintTop_toBottomOf="@+id/display_pic"
            android:layout_marginLeft="8dp"
            android:layout_marginStart="8dp"
            app:layout_constraintLeft_toLeftOf="@+id/guideline"
            app:layout_constraintHorizontal_bias="1.0" />

        <android.support.constraint.Guideline
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/guideline"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.6796875" />


    </android.support.constraint.ConstraintLayout>


    <TextView
        android:id="@+id/tutor_requested_time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="32dp"
        android:text="Requested time"
        android:textStyle="italic"
        android:layout_marginStart="32dp"
        android:layout_marginBottom="8dp"
        android:layout_below="@+id/constraintLayout" />


</RelativeLayout>

The layout that shows it black/greyish(default as it should be)

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="10dp"
    android:layout_marginStart="10dp"
    android:layout_marginRight="10dp"
    android:layout_marginEnd="10dp"
    android:background="@color/lightGrey"
    android:layout_marginBottom="10dp"
    android:layout_marginTop="10dp"
    android:elevation="2dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:paddingBottom="10dp"
        android:paddingEnd="10dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:paddingStart="10dp"
        android:paddingTop="10dp">

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:weightSum="1"
            android:layout_toLeftOf="@+id/display_pic"
            android:layout_toStartOf="@+id/display_pic"
            android:layout_marginEnd="10dp"
            android:layout_marginRight="10dp"
            android:id="@+id/linearLayout2">

            <TextView
                android:text="@string/tutor_name"
                android:textStyle="bold"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/tutor_name"/>

            <TextView
                android:text="@string/tutor_skill_set"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="12dp"
                android:id="@+id/skill_set"/>

            <TextView
                android:text="@string/tutor_types"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="12dp"
                android:id="@+id/tutor_types" />

            <TextView
                android:text="@string/tutor_location"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/location"
                android:layout_marginTop="12dp" />

        </LinearLayout>


        <ImageView
            android:id="@+id/display_pic"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:adjustViewBounds="false"
            android:scaleType="centerCrop"
            app:srcCompat="@android:color/holo_red_light" />

        <com.iarcuschin.simpleratingbar.SimpleRatingBar
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/tutor_rating"
            android:layout_below="@+id/display_pic"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            app:srb_starSize="13dp"
            app:srb_numberOfStars="5"
            app:srb_borderColor="@color/colorAccent"
            app:srb_fillColor="@color/colorPrimary"
            app:srb_starBorderWidth="1"
            app:srb_isIndicator="true"
            android:layout_marginTop="2dp" />

        <Button
            android:id="@+id/request_tutor"
            style="@android:style/Widget.Button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_below="@+id/linearLayout2"
            android:layout_marginTop="14dp"
            android:background="@color/lighterGrey"
            android:minHeight="25dp"
            android:minWidth="80dp"
            android:text="Request"
            android:textAppearance="@style/TextAppearance.AppCompat" />

    </RelativeLayout>

</FrameLayout>

(Note: Although I tried using a Barrier below, it is in ConstraintLayout 1.1.0 beta and I would strictly refrain from using a beta version for production in this case)

EDIT 2: Following @rami-jemli 's advice, here is the ConstraintLayout with a barrier with the problem still persisting.

<?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:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="4dp"
    android:layout_marginBottom="4dp"
    android:layout_marginLeft="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginRight="8dp"
    android:layout_marginEnd="8dp"
    android:background="@color/lightGrey"
    android:id="@+id/constraintLayout">


    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginLeft="16dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/guideline"
        android:layout_marginRight="8dp"
        android:layout_marginEnd="8dp"
        app:layout_constraintHorizontal_bias="0.0"
        android:id="@+id/linearLayout">

        <TextView
            android:text="@string/tutor_name"
            android:textStyle="bold"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/tutor_name"/>

        <TextView
            android:text="@string/tutor_skill_set"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            android:id="@+id/skill_set"/>

        <TextView
            android:text="@string/tutor_types"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            android:id="@+id/tutor_types" />

        <TextView
            android:text="@string/tutor_location"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/location"
            android:layout_marginTop="12dp" />

    </LinearLayout>


    <ImageView
        android:id="@+id/display_pic"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_marginEnd="16dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="16dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="16dp"
        android:adjustViewBounds="false"
        android:scaleType="centerCrop"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintLeft_toLeftOf="@+id/guideline"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@android:color/holo_red_light" />

    <com.iarcuschin.simpleratingbar.SimpleRatingBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tutor_rating"
        android:layout_below="@+id/display_pic"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        app:srb_starSize="13dp"
        app:srb_numberOfStars="5"
        app:srb_borderColor="@color/colorAccent"
        app:srb_fillColor="@color/colorPrimary"
        app:srb_starBorderWidth="1"
        app:srb_isIndicator="true"
        app:layout_constraintRight_toRightOf="@+id/display_pic"
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toBottomOf="@+id/display_pic"
        android:layout_marginLeft="8dp"
        android:layout_marginStart="8dp"
        app:layout_constraintLeft_toLeftOf="@+id/guideline"
        app:layout_constraintHorizontal_bias="1.0" />

    <android.support.constraint.Guideline
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/guideline"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.6796875"
        tools:layout_editor_absoluteY="0dp"
        tools:layout_editor_absoluteX="250dp" />

    <TextView
        android:id="@+id/tutor_requested_time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Requested time"
        android:textStyle="italic"
        android:layout_below="@+id/constraintLayout"
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toTopOf="@+id/barrier"
        app:layout_constraintStart_toStartOf="@+id/linearLayout"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="8dp" />

    <android.support.constraint.Barrier
        android:id="@+id/barrier"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="bottom"
        app:constraint_referenced_ids="tutor_rating,linearLayout"
        tools:layout_editor_absoluteY="126dp" />


</android.support.constraint.ConstraintLayout>

Output:(Dummy data)

enter image description here

Manish Kumar Sharma
  • 12,982
  • 9
  • 58
  • 105

2 Answers2

8

I cannot believe this! I found the answer.

From the question, it is not possible to pinpoint what could be wrong because problem is not with the layout, RecyclerView, AppCompat or ConstraintLayout. The problem is with something called the Themed Context. I have been passing around application context in almost all cases but it turns out where the layout is concerned, it is recommended to pass in Activity instance itself(which is a Themed context because it extends ContextThemeWrapper --more on this a bit later).

So, for example, when we are instantiating a LayoutManager for a RecyclerView, we would pass in Activity instance. When we are inflating a layout item for a RecyclerView, we would again use the Activity.

Talking in this context, ContextThemeWrapper takes conceptual precedence as stated here and Activity subclasses it.

Also mentioned is,

ContextThemeWrapper will apply your application theme

The snippet of code I've shared above does not make this immediately clear, however, you can write your own tests to verify this. The best way I can think of doing this is to create a simple app with a ListView that uses android.R.layout.simple_list_item_1 to display items. Make your apps theme Light by default and then initialize your ArrayAdapter using getApplicationContext(). You’ll notice that the text is either not visible or barely visible because it will be white by default whereas your theme should call for default text to be black. Change the code, so that your code initializes the array adapter with “this” (i.e the Activity) or simply getContext() and you’ll see the text turns black.

And,

Do not use getApplicationContext() with LayoutInflater, unless you really do want to ignore your theme.


Hats off to @sockeqwe for his answer on SwitchCompat that gave me this idea.

Note: Previously, I had mentioned that this might be a bug in ConstraintLayout. I take that back and apologies to the folks working on ConstraintLayout(which I have found totally awesome!)

Lastly, thanks to all the folks who gave their precious time reading my question and churning their brainpower for answer.

Manish Kumar Sharma
  • 12,982
  • 9
  • 58
  • 105
3

The way you are using ConstraintLayout now is wrong. You are not getting its performance benefits. There is no need for all the other ViewGroups (RelativeLayout, etc.) and the nested layouts.
In your case, you need to use only one ConstraintLayout as a parent layout with no nested level.
Use Chains instead of LinearLayout.
Try to achieve this and update your question with the new code.
Let's see what you get.

Rami Jemli
  • 2,550
  • 18
  • 31
  • Well, that's what I had planned originally but while doing so, I encountered a problem with ConstraintLayout. You see, there is only 1 vertical constraint per view edge( for top and bottoms edges) I can have but I wanted my view to lie below the bottom edges of 2 other views. This is something I couldn't do with a flat ConstraintLayout. To give you an idea, see: http://imgur.com/a/sw5bx . The *requested time* TextView has to be aligned below the LinearLayout's bottom as well as the rating bar on the right. Do you have a solution for this? – Manish Kumar Sharma Jul 02 '17 at 04:20
  • To keep a view below the edge of two other views, you can use Barriers. They are part of the 1.1.0-beta1 release of ConstraintLayout. You can still get a flat layout. Give it a try. – Rami Jemli Jul 02 '17 at 08:46
  • I kind of explained Barriers here (https://stackoverflow.com/questions/44487758/align-constraintlayout-item-to-be-at-the-end-of-two-items/44489567#44489567) – Rami Jemli Jul 02 '17 at 08:47
  • Yeah...I saw a walkthrough for Barriers after you mentioned. Turns out, a simple Constraint Layout update to 1.1.0 beta won't visually facilitate the use of Barriers so I am now downloading AS 3.0 Canary-5 Preview to use it. But a big thanks for pointing me in this direction. +1 – Manish Kumar Sharma Jul 02 '17 at 11:21
  • I was able to put a barrier in place successfully but the white color bug still remains...;( – Manish Kumar Sharma Jul 02 '17 at 14:23
  • Great. Please update your question with the new layout code and point out which view exactly is showing the color problem – Rami Jemli Jul 02 '17 at 14:45
  • I have put the new info. within EDIT 2. The problem as you can see persists in all the TextViews(Note that above layout is for each item that has been displayed in the list). Side note: Android Studio 3.0 sucks! Couldn't find anywhere the Screen Capture functionality. Also, it is unable to connect to active process on the device unless opened in debug mode - such a turn off really... – Manish Kumar Sharma Jul 02 '17 at 16:20
  • Although helpful this does not provide answer to the question. – Eugen Pechanec Jul 24 '17 at 07:39