Skip to content

Instantly share code, notes, and snippets.

@ademar111190
Last active March 16, 2023 10:44
Show Gist options
  • Save ademar111190/7d31dab71502e6a85b8a to your computer and use it in GitHub Desktop.
Save ademar111190/7d31dab71502e6a85b8a to your computer and use it in GitHub Desktop.
An easy way to format SearchView's
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ImageSpan;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SearchView;
import android.widget.TextView;
public class SearchViewFormatter {
protected int mSearchBackGroundResource = 0;
protected int mSearchIconResource = 0;
protected boolean mSearchIconInside = false;
protected boolean mSearchIconOutside = false;
protected int mSearchVoiceIconResource = 0;
protected int mSearchTextColorResource = 0;
protected int mSearchHintColorResource = 0;
protected String mSearchHintText = "";
protected int mSearchHintTextResource = 0;
protected int mInputType = Integer.MIN_VALUE;
protected int mSearchCloseIconResource = 0;
protected TextView.OnEditorActionListener mEditorActionListener;
protected Resources mResources;
public SearchViewFormatter setSearchBackGroundResource(int searchBackGroundResource) {
mSearchBackGroundResource = searchBackGroundResource;
return this;
}
public SearchViewFormatter setSearchIconResource(int searchIconResource, boolean inside, boolean outside) {
mSearchIconResource = searchIconResource;
mSearchIconInside = inside;
mSearchIconOutside = outside;
return this;
}
public SearchViewFormatter setSearchVoiceIconResource(int searchVoiceIconResource) {
mSearchVoiceIconResource = searchVoiceIconResource;
return this;
}
public SearchViewFormatter setSearchTextColorResource(int searchTextColorResource) {
mSearchTextColorResource = searchTextColorResource;
return this;
}
public SearchViewFormatter setSearchHintColorResource(int searchHintColorResource) {
mSearchHintColorResource = searchHintColorResource;
return this;
}
public SearchViewFormatter setSearchHintText(String searchHintText) {
mSearchHintText = searchHintText;
return this;
}
public SearchViewFormatter setSearchHintTextResource(int searchHintText) {
mSearchHintTextResource = searchHintText;
return this;
}
public SearchViewFormatter setInputType(int inputType) {
mInputType = inputType;
return this;
}
public SearchViewFormatter setSearchCloseIconResource(int searchCloseIconResource) {
mSearchCloseIconResource = searchCloseIconResource;
return this;
}
public SearchViewFormatter setEditorActionListener(TextView.OnEditorActionListener editorActionListener) {
mEditorActionListener = editorActionListener;
return this;
}
public void format(SearchView searchView) {
if (searchView == null) {
return;
}
mResources = searchView.getContext().getResources();
int id;
if (mSearchBackGroundResource != 0) {
id = getIdentifier("search_plate");
View view = searchView.findViewById(id);
view.setBackgroundResource(mSearchBackGroundResource);
id = getIdentifier("submit_area");
view = searchView.findViewById(id);
view.setBackgroundResource(mSearchBackGroundResource);
}
if (mSearchVoiceIconResource != 0) {
id = getIdentifier("search_voice_btn");
ImageView view = (ImageView) searchView.findViewById(id);
view.setImageResource(mSearchVoiceIconResource);
}
if (mSearchCloseIconResource != 0) {
id = getIdentifier("search_close_btn");
ImageView view = (ImageView) searchView.findViewById(id);
view.setImageResource(mSearchCloseIconResource);
}
id = getIdentifier("search_src_text");
TextView view = (TextView) searchView.findViewById(id);
if (mSearchTextColorResource != 0) {
view.setTextColor(mResources.getColor(mSearchTextColorResource));
}
if (mSearchHintColorResource != 0) {
view.setHintTextColor(mResources.getColor(mSearchHintColorResource));
}
if (mInputType > Integer.MIN_VALUE) {
view.setInputType(mInputType);
}
if (mSearchIconResource != 0) {
ImageView imageView = (ImageView) searchView.findViewById(getIdentifier("search_mag_icon"));
if (mSearchIconInside) {
Drawable searchIconDrawable = mResources.getDrawable(mSearchIconResource);
int size = (int) (view.getTextSize() * 1.25f);
searchIconDrawable.setBounds(0, 0, size, size);
if (mSearchHintTextResource != 0) {
mSearchHintText = mResources.getString(mSearchHintTextResource);
}
SpannableStringBuilder hintBuilder = new SpannableStringBuilder(" ");
hintBuilder.append(mSearchHintText);
hintBuilder.setSpan(
new ImageSpan(searchIconDrawable),
1,
2,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
view.setHint(hintBuilder);
imageView.setLayoutParams(new LinearLayout.LayoutParams(0, 0));
}
if (mSearchIconOutside) {
int searchImgId = getIdentifier("search_button");
imageView = (ImageView) searchView.findViewById(searchImgId);
imageView.setImageResource(mSearchIconResource);
}
}
if (mEditorActionListener != null) {
view.setOnEditorActionListener(mEditorActionListener);
}
}
protected int getIdentifier(String literalId) {
return mResources.getIdentifier(
String.format("android:id/%s", literalId),
null,
null
);
}
}
@kenyee
Copy link

kenyee commented Jun 5, 2014

had a few modifications to get the search icons inside/outside to work right:

import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ImageSpan;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SearchView;
import android.widget.TextView;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class SearchViewFormatter {

protected int mSearchBackGroundResource = 0;
protected int mSearchIconResource = 0;
protected boolean mSearchIconInside = false;
protected boolean mSearchIconOutside = false;
protected int mSearchVoiceIconResource = 0;
protected int mSearchTextColorResource = 0;
protected int mSearchHintColorResource = 0;
protected String mSearchHintText = "";
protected int mInputType = Integer.MIN_VALUE;
protected int mSearchCloseIconResource = 0;
protected TextView.OnEditorActionListener mEditorActionListener;
protected Resources mResources;

public SearchViewFormatter setSearchBackGroundResource(int searchBackGroundResource) {
    mSearchBackGroundResource = searchBackGroundResource;
    return this;
}

public SearchViewFormatter setSearchIconResource(int searchIconResource, boolean inside, boolean outside) {
    mSearchIconResource = searchIconResource;
    mSearchIconInside = inside;
    mSearchIconOutside = outside;
    return this;
}

public SearchViewFormatter setSearchVoiceIconResource(int searchVoiceIconResource) {
    mSearchVoiceIconResource = searchVoiceIconResource;
    return this;
}

public SearchViewFormatter setSearchTextColorResource(int searchTextColorResource) {
    mSearchTextColorResource = searchTextColorResource;
    return this;
}

public SearchViewFormatter setSearchHintColorResource(int searchHintColorResource) {
    mSearchHintColorResource = searchHintColorResource;
    return this;
}

public SearchViewFormatter setSearchHintText(String searchHintText) {
    mSearchHintText = searchHintText;
    return this;
}

public SearchViewFormatter setInputType(int inputType) {
    mInputType = inputType;
    return this;
}

public SearchViewFormatter setSearchCloseIconResource(int searchCloseIconResource) {
    mSearchCloseIconResource = searchCloseIconResource;
    return this;
}

public SearchViewFormatter setEditorActionListener(TextView.OnEditorActionListener editorActionListener) {
    mEditorActionListener = editorActionListener;
    return this;
}

public void format(SearchView searchView) {
    if (searchView == null) {
        return;
    }

    mResources = searchView.getContext().getResources();
    int id;

    if (mSearchBackGroundResource != 0) {
        id = getIdentifier("search_plate");
        View view = searchView.findViewById(id);
        view.setBackgroundResource(mSearchBackGroundResource);

        id = getIdentifier("submit_area");
        view = searchView.findViewById(id);
        view.setBackgroundResource(mSearchBackGroundResource);
    }

    if (mSearchVoiceIconResource != 0) {
        id = getIdentifier("search_voice_btn");
        ImageView view = (ImageView) searchView.findViewById(id);
        view.setImageResource(mSearchVoiceIconResource);
    }

    if (mSearchCloseIconResource != 0) {
        id = getIdentifier("search_close_btn");
        ImageView view = (ImageView) searchView.findViewById(id);
        view.setImageResource(mSearchCloseIconResource);
    }

    id = getIdentifier("search_src_text");
    TextView view = (TextView) searchView.findViewById(id);
    if (mSearchTextColorResource != 0) {
        view.setTextColor(mResources.getColor(mSearchTextColorResource));
    }
    if (mSearchHintColorResource != 0) {
        view.setHintTextColor(mResources.getColor(mSearchHintColorResource));
    }
    if (mInputType > Integer.MIN_VALUE) {
        view.setInputType(mInputType);
    }
    if (mSearchIconResource != 0) {
        ImageView imageView = (ImageView) searchView.findViewById(getIdentifier("search_mag_icon"));

        if (mSearchIconInside) {
            Drawable searchIconDrawable = mResources.getDrawable(mSearchIconResource);
            int size = (int) (view.getTextSize() * 1.25f);
            searchIconDrawable.setBounds(0, 0, size, size);

            SpannableStringBuilder hintBuilder = new SpannableStringBuilder("   ");
            hintBuilder.append(mSearchHintText);  // we can't append view.getHint() because that includes the old icon
            hintBuilder.setSpan(
                    new ImageSpan(searchIconDrawable),
                    1,
                    2,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            );

            view.setHint(hintBuilder);
            imageView.setLayoutParams(new LinearLayout.LayoutParams(0, 0));
        }
        if (mSearchIconOutside) {
            int searchImgId = getIdentifier("search_button");
            imageView = (ImageView) searchView.findViewById(searchImgId);

            imageView.setImageResource(mSearchIconResource);
        }
    }

    if (mEditorActionListener != null) {
        view.setOnEditorActionListener(mEditorActionListener);
    }
}

protected int getIdentifier(String literalId) {
    return mResources.getIdentifier(
            String.format("android:id/%s", literalId),
            null,
            null
    );
}

}

@ademar111190
Copy link
Author

Thanks @kenyee I updated the gist with your contribution 👍

@diegoflassa
Copy link

Updated some deprecated methods

`import android.content.Context
import android.content.res.Resources
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.style.ImageSpan
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.SearchView
import android.widget.TextView
import android.widget.TextView.OnEditorActionListener
import androidx.core.content.ContextCompat

@Suppress("unused")
class SearchViewFormatter(private val context : Context) {
var mSearchBackGroundResource = 0
var mSearchIconResource = 0
var mSearchIconInside = false
private var mSearchIconOutside = false
var mSearchVoiceIconResource = 0
var mSearchTextColorResource = 0
var mSearchHintColorResource = 0
var mSearchHintText = ""
var mSearchHintTextResource = 0
var mInputType = Int.MIN_VALUE
private var mSearchCloseIconResource = 0
var mEditorActionListener: OnEditorActionListener? = null
var mResources: Resources? = null
fun setSearchBackGroundResource(searchBackGroundResource: Int): SearchViewFormatter {
mSearchBackGroundResource = searchBackGroundResource
return this
}

fun setSearchIconResource(
    searchIconResource: Int,
    inside: Boolean,
    outside: Boolean
): SearchViewFormatter {
    mSearchIconResource = searchIconResource
    mSearchIconInside = inside
    mSearchIconOutside = outside
    return this
}


fun setSearchVoiceIconResource(searchVoiceIconResource: Int): SearchViewFormatter {
    mSearchVoiceIconResource = searchVoiceIconResource
    return this
}

fun setSearchTextColorResource(searchTextColorResource: Int): SearchViewFormatter {
    mSearchTextColorResource = searchTextColorResource
    return this
}

fun setSearchHintColorResource(searchHintColorResource: Int): SearchViewFormatter {
    mSearchHintColorResource = searchHintColorResource
    return this
}

fun setSearchHintText(searchHintText: String): SearchViewFormatter {
    mSearchHintText = searchHintText
    return this
}

fun setSearchHintTextResource(searchHintText: Int): SearchViewFormatter {
    mSearchHintTextResource = searchHintText
    return this
}

fun setInputType(inputType: Int): SearchViewFormatter {
    mInputType = inputType
    return this
}

fun setSearchCloseIconResource(searchCloseIconResource: Int): SearchViewFormatter {
    mSearchCloseIconResource = searchCloseIconResource
    return this
}

fun setEditorActionListener(editorActionListener: OnEditorActionListener?): SearchViewFormatter {
    mEditorActionListener = editorActionListener
    return this
}

fun format(searchView: SearchView?) {
    if (searchView == null) {
        return
    }
    mResources = searchView.context.resources
    var id: Int
    if (mSearchBackGroundResource != 0) {
        id = getIdentifier("search_plate")
        var view = searchView.findViewById<View>(id)
        view.setBackgroundResource(mSearchBackGroundResource)
        id = getIdentifier("submit_area")
        view = searchView.findViewById(id)
        view.setBackgroundResource(mSearchBackGroundResource)
    }
    if (mSearchVoiceIconResource != 0) {
        id = getIdentifier("search_voice_btn")
        val view = searchView.findViewById<View>(id) as ImageView
        view.setImageResource(mSearchVoiceIconResource)
    }
    if (mSearchCloseIconResource != 0) {
        id = getIdentifier("search_close_btn")
        val view = searchView.findViewById<View>(id) as ImageView
        view.setImageResource(mSearchCloseIconResource)
    }
    id = getIdentifier("search_src_text")
    val view = searchView.findViewById<View>(id) as TextView
    if (mSearchTextColorResource != 0) {
        view.setTextColor(ContextCompat.getColor(context, mSearchTextColorResource))
    }
    if (mSearchHintColorResource != 0) {
        view.setHintTextColor(ContextCompat.getColor(context, mSearchHintColorResource))
    }
    if (mInputType > Int.MIN_VALUE) {
        view.inputType = mInputType
    }
    if (mSearchIconResource != 0) {
        var imageView =
            searchView.findViewById<View>(getIdentifier("search_mag_icon")) as ImageView
        if (mSearchIconInside) {
            val searchIconDrawable = ContextCompat.getDrawable(context, mSearchIconResource)
            val size = (view.textSize * 1.25f).toInt()
            searchIconDrawable?.setBounds(0, 0, size, size)
            if (mSearchHintTextResource != 0) {
                mSearchHintText = mResources!!.getString(mSearchHintTextResource)
            }
            val hintBuilder = SpannableStringBuilder("   ")
            hintBuilder.append(mSearchHintText)
            hintBuilder.setSpan(
                ImageSpan(searchIconDrawable!!),
                1,
                2,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            view.hint = hintBuilder
            imageView.layoutParams = LinearLayout.LayoutParams(0, 0)
        }
        if (mSearchIconOutside) {
            val searchImgId = getIdentifier("search_button")
            imageView = searchView.findViewById<View>(searchImgId) as ImageView
            imageView.setImageResource(mSearchIconResource)
        }
    }

    if (mEditorActionListener != null) {
        view.setOnEditorActionListener(mEditorActionListener)
    }
}

private fun getIdentifier(literalId: String?): Int {
    return mResources!!.getIdentifier(
        String.format("android:id/%s", literalId),
        null,
        null
    )
}

}`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment