Search code examples
androidandroid-layoutandroid-edittextandroid-stylesandroid-textinputlayout

EditText and TextInputLayout added programmatically not picking style and not displaying soft keyboard


I'm developing a library module in which I wanna allow clients to pass a style resource for EditText and TextInputLayout UI components. In order to use the passed layout I need to inflate both component at runtime and add them in the parent layout. When I do this, a weird behavior happens:

  1. InputTextLayout doesn't pick the passed style;
  2. When clicking on the EditText, soft keyboard is not triggered;

Parent Layout

<android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<android.support.v7.widget.Toolbar
    android:id="@+id/search_toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorPrimary"
    android:minHeight="?attr/actionBarSize"
    app:layout_scrollFlags="scroll|enterAlways">

    <LinearLayout
        android:id="@+id/toolbar_inner_container"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        android:padding="3dip"
        android:weightSum="7">

        <ImageView
            android:id="@+id/back"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:src="@drawable/ic_arrow_left_white_24dp" />


    </LinearLayout>
</android.support.v7.widget.Toolbar>

<br.com.edsilfer.kotlin_support.presenter.layout.LineProgressBar
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:colorLine="@color/clr_theme_light_text" />

Sample Preset Styles:

 <!-- THEME LIGHT -->
<!-- search bar input text -->
<style name="TextInputThemeDark">
    <item name="android:colorAccent">@color/clr_theme_dark_text_input_hint</item>
    <item name="android:textColorHint">@color/clr_theme_dark_text_input_hint</item>
    <item name="android:textColor">@color/clr_theme_dark_text_input</item>
    <item name="android:colorControlNormal">@color/clr_theme_dark_text_input</item>
    <item name="android:colorControlActivated">@color/clr_theme_dark_text_input</item>
    <item name="android:textSize">@dimen/dim_presets_commons_text_input_size</item>
</style>



 <style name="SearchText">
    <item name="android:textColorHint">#000</item>
    <item name="android:colorAccent">#000</item>
    <item name="android:textColor">#000</item>
</style>

Add views programmatically

TextInputLayout iw = new TextInputLayout(mActivity, null, R.style.SearchText);
iw.layoutParams = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 5f);
mInput = EditText(mActivity, null, R.style.TextInputThemeDark);
mInput.layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
mClear = new ImageView(mActivity);
mClear.layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f);
mClear.setImageResource(R.drawable.ic_close_black_24dp);

iw.addView(mInput);
iw.setHint("Type something...");

((LinearLayout) mActivity.findViewById(R.id.toolbar_inner_container)).addView(iw)
((LinearLayout) mActivity.findViewById(R.id.toolbar_inner_container)).addView(mClear)

Full project can be found here: https://github.com/edsilfer/android-search-interface


Solution

  • The problem was the way I was instantiating the UI component. Instead to call the constructor right the way, I needed to do that through the use of ContextThemeWrapper. My end code, in Kotlin, came out this way:

     val container = LinearLayout(mActivity)
            val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
            container.layoutParams = params
            container.weightSum = 7f
            container.gravity = Gravity.CENTER_VERTICAL
            container.orientation = LinearLayout.HORIZONTAL
    
            mBack.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)
            mBack.image = mActivity.getDrawable(mPreset.iconBack)
            mBack.background = mActivity.getDrawable(R.drawable.rsc_rounded_corners)
    
            val iw = TextInputLayout(ContextThemeWrapper(mActivity, mPreset.textInputLayoutStyle))
            iw.layoutParams = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 5f)
    
            mInput.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT, 5f)
            mInput.background = null
    
            iw.addView(mInput)
            iw.hint = mActivity.getString(mPreset.hintText)
    
            mClear.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)
            mClear.image = mActivity.getDrawable(mPreset.iconClear)
            mClear.background = mActivity.getDrawable(R.drawable.rsc_rounded_corners)
    
            val toolbar = mActivity.findViewById(R.id.search_toolbar) as Toolbar
            toolbar.setBackgroundColor(mActivity.resources.getColor(mPreset.colorPrimary))
    
            container.addView(mBack)
            container.addView(iw)
            container.addView(mClear)
    
            (mActivity.findViewById(R.id.search_toolbar) as Toolbar).addView(container)
    
            mInput.requestFocus()