I am trying to create a simple Custom Switch Widget that listens to changes in value of a certain key in SharedPreferences. Below is my code:
public class CustomSwitch extends SwitchCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = CustomSwitch.class.getSimpleName();
private boolean isSwitchTintColorPrimary;
public CustomSwitch(Context context) {
this(context, null);
}
public CustomSwitch(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomSwitch(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initializeView(context, attrs);
}
private void initializeView(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomSwitch, 0, 0);
try {
isSwitchTintColorPrimary = ta.getBoolean(R.styleable.CustomSwitch_tintColorPrimary, false);
} finally {
ta.recycle();
}
applyTheme();
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
registerThemeChangeListener();
}
private void registerThemeChangeListener() {
if (getContext() != null)
ColoriyoPreference.getSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
unRegisterThemeChangeListener();
}
private void unRegisterThemeChangeListener() {
if (getContext() != null)
ColoriyoPreference.getSharedPreferences(getContext()).unregisterOnSharedPreferenceChangeListener(this);
}
private void applyTheme() {
ColorStateList thumbStates = new ColorStateList(
new int[][]{
{android.R.attr.state_checked, android.R.attr.state_enabled},
{-android.R.attr.state_checked, android.R.attr.state_enabled},
{}
},
new int[]{
isSwitchTintColorPrimary ? ColoriyoPreference.getColor(getContext()) : ContextCompat.getColor(getContext(), R.color.colorPrimary),
ContextCompat.getColor(getContext(), R.color.grey_50),
ContextCompat.getColor(getContext(), R.color.grey_50)
}
);
setThumbTintList(thumbStates);
ColorStateList trackStates = new ColorStateList(
new int[][]{
new int[]{-android.R.attr.state_enabled},
new int[]{}
},
new int[]{
Color.GRAY,
Color.LTGRAY
}
);
setTrackTintList(trackStates);
setTrackTintMode(PorterDuff.Mode.OVERLAY);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(PREFERENCE_KEY_COLOR)) {
applyTheme();
}
}
}
And in layout:
<?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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.chintansoni.android.themedemo.MainActivity"
tools:showIn="#layout/activity_main">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.chintansoni.android.themedemo.customview.themeview.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView textColor"
app:textColorPrimary="true" />
<com.chintansoni.android.themedemo.customview.themeview.CustomButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button Background"
app:backgroundColorPrimary="true" />
<com.chintansoni.android.themedemo.customview.themeview.CustomSwitch
android:id="#+id/switch_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOff="Off"
android:textOn="On"
app:tintColorPrimary="true" />
</LinearLayout>
<uz.shift.colorpicker.LineColorPicker
android:id="#+id/picker"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_margin="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:orientation="horizontal" />
</android.support.constraint.ConstraintLayout>
But my view is not getting rendered in UI. Also, I wonder if this code will listen to color change in preference and reflect the color change in runtime?
Any suggestion?
The only thing I was missing:
public CustomSwitch(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.switchStyle); // <--- passing default Style Attribute
}
My improved class is as below:
public class CustomSwitch extends SwitchCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
private boolean isSwitchTintColorPrimary;
public CustomSwitch(Context context) {
this(context, null);
}
public CustomSwitch(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.switchStyle);
}
public CustomSwitch(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initializeView(context, attrs);
}
private void initializeView(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomSwitch, 0, 0);
try {
isSwitchTintColorPrimary = ta.getBoolean(R.styleable.CustomSwitch_tintColorPrimary, false);
} finally {
ta.recycle();
}
applyTheme();
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
registerThemeChangeListener();
}
private void registerThemeChangeListener() {
if (getContext() != null)
ColoriyoPreference.getSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
unRegisterThemeChangeListener();
}
private void unRegisterThemeChangeListener() {
if (getContext() != null)
ColoriyoPreference.getSharedPreferences(getContext()).unregisterOnSharedPreferenceChangeListener(this);
}
private void applyTheme() {
ColorStateList thumbStates = new ColorStateList(
new int[][]{
{android.R.attr.state_checked, android.R.attr.state_enabled},
{-android.R.attr.state_checked, android.R.attr.state_enabled},
{}
},
new int[]{
isSwitchTintColorPrimary ? ColoriyoPreference.getColor(getContext()) : ContextCompat.getColor(getContext(), R.color.colorPrimary),
ContextCompat.getColor(getContext(), R.color.grey_50),
ContextCompat.getColor(getContext(), R.color.grey_50)
}
);
setThumbTintList(thumbStates);
ColorStateList trackStates = new ColorStateList(
new int[][]{
new int[]{android.R.attr.state_enabled},
new int[]{-android.R.attr.state_enabled}
},
new int[]{
Color.LTGRAY,
Color.GRAY,
Color.LTGRAY
}
);
setTrackTintList(trackStates);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(ColoriyoPreference.PREFERENCE_KEY_COLOR)) {
applyTheme();
}
}
}
Related
I have a CustomView extend from RelativeLayout.
I Use this CustomView in layout file but Android Studio in design mode not showing the CustomView. what is problem?
koala_appbar.xml:
<RelativeLayout 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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_gravity="top"
tools:context=".activity.basic.BaseActivity">
<ImageView
android:id="#+id/appbar_imgLogo"
android:layout_width="#dimen/appBar_iconWidth"
android:layout_height="#dimen/appBar_iconHeight"
android:src="#drawable/logo"
android:layout_marginTop="#dimen/appBar_iconTopMargin"
android:layout_marginLeft="#dimen/appBar_iconLeftMargin"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="#dimen/appbar_height"
android:orientation="horizontal"
android:layoutDirection="ltr"
>
<koala.android.customer.views.widget.CustomTextView
android:id="#+id/appBar_txtTitle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center|right"
android:text="#string/app_name_persian"
android:textColor="#color/colorPrimary"
android:textSize="#dimen/TextSize_large"
app:tvCustomFont="#string/baseFont"
/>
<koala.android.customer.views.widget.CustomImageView
android:id="#+id/appBar_imgBack"
android:layout_width="#dimen/appbar_height"
android:layout_height="match_parent"
app:srcCompat="#drawable/ic_arrow_right"
app:ivDrawableTint="#color/colorPrimary"
android:padding="#dimen/appBar_backPadding"
/>
</LinearLayout>
</RelativeLayout>
KoalaAppBar.java:
public class KoalaAppBar extends RelativeLayout {
private static final String DEFAULT_TITLE = "default";
private static final int DEFAULT_TITLE_COLOR = ResourcesCompat.getColor(AppController.getContext().getResources(), R.color.colorPrimary , null);
private static final float DEFAULT_TITLE_FONT_SIZE = AppController.getContext().getResources().getDimension(R.dimen.TextSize_small);
protected CustomTextView txtTitle;
protected CustomImageView imgBack;
protected ImageView imgLogo;
public KoalaAppBar(Context context) {
super(context);
init(context , null);
}
public KoalaAppBar(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init(context , attrs);
}
public KoalaAppBar(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context , attrs);
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public KoalaAppBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
if(context != null){
findViews(context);
}
if(attrs != null){
initAttribute(context,attrs);
}
}
private void initAttribute(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KoalaAppBar);
String title = a.getString(R.styleable.KoalaAppBar_appTitle);
if(title == null || title.isEmpty()){
title = DEFAULT_TITLE;
}
int titleColor = a.getColor(R.styleable.KoalaAppBar_appTitleColor, DEFAULT_TITLE_COLOR);
float fontSize = a.getDimension(R.styleable.KoalaAppBar_appTitleFontSize, DEFAULT_TITLE_FONT_SIZE);
boolean logoVisibility = a.getBoolean(R.styleable.KoalaAppBar_appLogoVisibility , true);
initTitle(title , titleColor , fontSize);
initLogo(logoVisibility);
a.recycle();
}
private void initLogo(boolean logoVisibility) {
if(logoVisibility){
this.imgLogo.setVisibility(VISIBLE);
}else{
this.imgLogo.setVisibility(GONE);
}
}
private void initTitle(String title, int titleColor, float fontSize) {
this.txtTitle.setText(title);
this.txtTitle.setTextColor(titleColor);
this.txtTitle.setTextSize(fontSize);
}
private void findViews(Context context) {
View rootView =
LayoutInflater.from(context).inflate(
R.layout.koala_appbar,
this,
true
);
this.txtTitle = rootView.findViewById(R.id.appBar_txtTitle);
this.imgBack = rootView.findViewById(R.id.appBar_imgBack);
this.imgLogo = rootView.findViewById(R.id.appbar_imgLogo);
}
}
how to create an object of the class, and provide value to constructor like AttributeSet etc. and also setText("")
public class CustomTextView extends AppCompatTextView {
public CustomTextView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint1 = new Paint(Paint.ANTI_ALIAS_FLAG);
paint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
textPaint.setTextSize(getTextSize());
}
#Override
public void onDraw(Canvas canvas) {
TextPaint textPaint = getPaint();
// ..........
}
}
// how to use in java
CustomTextView cTV = new CustomTextView (...........)??
cTV.setText("how to create like that");
first of all you need to define the class.
public class CustomFontTextView extends AppCompatTextView {
private static final String CUSTOM_FONT = "cfont";
private static final String FONT_PATH = "fonts/";
private String ttfName;
private Typeface font;
private CharSequence text;
private BufferType type;
public CustomFontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public CustomFontTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
this.ttfName = attrs.getAttributeValue(AppConstants.NAMESPACE, CUSTOM_FONT);
if (ttfName.startsWith("#string/") || ttfName.startsWith("#")) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomFontTextView);
this.ttfName = ta.getString(R.styleable.CustomFontTextView_cfont);
ta.recycle();
}
this.setPaintFlags(this.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
try {
font = Typeface.createFromAsset(context.getAssets(), FONT_PATH + ttfName);
setTypeface(font);
} catch (Exception e) {
e.printStackTrace();
font = Typeface.defaultFromStyle(Typeface.NORMAL);
setTypeface(font);
}
setText(text, type);
}
#Override
public void setText(CharSequence text, BufferType type) {
try {
this.text = text;
this.type = type;
if (font == null)
return;
CustomFontStyling customFontStyling = new CustomFontStyling(getContext(), font);
super.setText(customFontStyling.getCustomText(text.toString()), type);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
After you need to add the styleable in your attrs.xml
<declare-styleable name="CustomFontTextView">
<attr name="cfont" format="string" />
</declare-styleable>
And finally on your xml layout
<YOURAPPPACKAGE.CustomFontTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cfont="#string/open_sans_regular" />
I just create Constructor for CustomTextView Class
public CustomTextView(Context context) {
this(context, null);
}
Now we can easily access any properties of CustomTextView Class.
I'm trying to make a custom EditText for currency which means I need to have a prefix of it for the currency and I have to limit users' input to numbers only.
This is my custom EditText code
public OpenSansEditText(Context context, AttributeSet attrs) {
super(context, attrs);
paint = getPaint();
applyCustomFont(context, attrs);
}
public OpenSansEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
paint = getPaint();
applyCustomFont(context, attrs);
}
private void applyCustomFont(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.OpenSansET);
...
// Prefix
String prefix = a.getString(R.styleable.OpenSansET_prefix);
if (prefix != null) {
mPrefix = prefix;
} else {
mPrefix = "";
}
// Prefix Color
int prefixColor = a.getColor(R.styleable.OpenSansET_prefixColor, 0);
if (prefix != null) {
mPrefixColor = prefixColor;
} else {
mPrefixColor = ContextCompat.getColor(context, R.color.miBlack);
}
a.recycle();
}
...
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (!mPrefix.equals("")) {
getPaint().getTextBounds(mPrefix, 0, mPrefix.length(), mPrefixRect);
mPrefixRect.right += getPaint().measureText(" "); // add some offset
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!mPrefix.equals("")) {
paint.setColor(mPrefixColor);
canvas.drawText(mPrefix, super.getCompoundPaddingLeft(), getBaseline(), paint);
}
}
#Override
public int getCompoundPaddingLeft() {
return mPrefix.equals("") ? super.getCompoundPaddingLeft()
: super.getCompoundPaddingLeft() + mPrefixRect.width();
}
This is how I use it in xml :
<com.asta.www.classes.OpenSansEditText
android:id="#+id/shopping_filter_priceMinRange"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.4"
android:gravity="center"
android:hint="#string/min"
android:textColor="#color/miBlack"
android:textColorHint="#color/miGrey"
app:prefix="$"
app:prefixColor="#color/miBlack" />
<com.asta.www.classes.OpenSansEditText
android:id="#+id/shopping_filter_priceMaxRange"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.4"
android:gravity="center"
android:hint="#string/max"
android:inputType="number"
android:textColorHint="#color/miGrey"
app:prefix="$"
app:prefixColor="#color/miBlack" />
Which yields :
Only the first one without inputType as number has the currency sign shown, whereas the second ET doesn't have its currency sign shown.
How to achieve currency prefix as text and still keeping inputType to numbers only for user? And I don't want to use two views, namely EditText and TextView to left of it, both inside a ViewGroup to achieve that.
For this type of scenarios I use Compound views. Please see below code for more information.
First create a layout for your custom view like below.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/txt_prefix"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="$" />
<EditText
android:id="#+id/et_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="number" />
</LinearLayout>
Now create a new class which should extends the LinearLayout. See below code.
public class OpenSansEditText extends LinearLayout {
private TextView txtPrefix;
private EditText etValue;
private String prefix = "$";
private int prefixColor = Color.BLACK;
public OpenSansEditText(Context context) {
super(context);
initializeViews(context, null);
}
public OpenSansEditText(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
initializeViews(context, attrs);
}
public OpenSansEditText(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initializeViews(context, attrs);
}
private void initializeViews(Context context, AttributeSet attrs) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.opensansedittext_view, this,true);
if (attrs != null) {
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.OpenSansEditText);
prefix = a.getString(R.styleable.OpenSansEditText_prefix);
prefixColor = a.getColor(R.styleable.OpenSansEditText_prefixColor, Color.BLACK);
}
}
public CharSequence getValue(){
return etValue.getText();
}
public CharSequence getPrefix(){
return txtPrefix.getText();
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
txtPrefix = (TextView) findViewById(R.id.txt_prefix);
etValue = (EditText) findViewById(R.id.et_value);
txtPrefix.setText(prefix);
txtPrefix.setTextColor(prefixColor);
}
}
And then add your attributes to attribute xml file Ex: (attrs.xml in my case)
<resources>
<declare-styleable name="OpenSansEditText">
<attr name="prefix" format="string"/>
<attr name="prefixColor" format="color"/>
</declare-styleable>
</resources>
Now you can use it anywhere in the project as below
<com.asta.www.classes.OpenSansEditText
android:layout_width="match_parent"
android:layout_height="match_parent"
app:prefix="$"
app:prefixColor="#f00"/>
Hope this will help you to solve your problem. Thanks...
In the end I found this link https://gist.github.com/kennydude/5407963 which helps me in the right direction. So what it does is I think making the prefix as Drawable using this class :
private class TagDrawable extends Drawable {
public String text = "";
public void setText(String s){
text = s;
// Tell it we need to be as big as we want to be!
setBounds(0,0,getIntrinsicWidth(),getIntrinsicHeight());
invalidateSelf();
}
#Override
public void draw(#NonNull Canvas canvas) {
// I don't know why this y works here, but it does :)
// (aka if you are from Google/are Jake Wharton and I have done it wrong, please tell me!)
canvas.drawText( text, 0, mLine0Baseline + canvas.getClipBounds().top, mTextPaint );
}
#Override public void setAlpha(int i) {}
#Override public void setColorFilter(ColorFilter colorFilter) {}
#Override public int getOpacity() {return PixelFormat.UNKNOWN;}
#Override public int getIntrinsicHeight (){
return (int)mFontHeight;
}
#Override public int getIntrinsicWidth(){
return (int)mTextPaint.measureText( text );
}
}
And draw it to the left of the TextView like
TagDrawable left = new TagDrawable();
left.setText("$");
setCompoundDrawablesRelative(left, null, null, null);
The link I supplied even has suffix support which I haven't tried.
I create an autoCompleteTextView as below Layout and Java class :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/autoCompleteTextViewGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:minHeight="#dimen/component_height">
<android.support.design.widget.TextInputLayout
android:id="#+id/textInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:animateLayoutChanges="true">
<AutoCompleteTextView
android:id="#+id/autoCompleteTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:completionThreshold="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
<android.support.v4.widget.ContentLoadingProgressBar
android:id="#+id/progressBar"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:indeterminate="true"
android:indeterminateDrawable="#anim/anim_indeterminate_mini"
android:interpolator="#anim/anim_progress_interpolator"
android:visibility="visible" />
</FrameLayout>
and Java class is :
public class MAutoCompleteText extends LinearLayout {
AutoCompleteTextView autoCompleteTextView;
ContentLoadingProgressBar progressBar;
TextInputLayout textInputLayout;
ViewGroup autoCompleteTextViewGroup;
public MAutoCompleteText(Context context) {
super(context);
init(context);
}
public MAutoCompleteText(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public MAutoCompleteText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
#TargetApi(21)
public MAutoCompleteText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
private void init(Context context) {
inflate(context, R.layout.layout_auto_complete_text, this);
autoCompleteTextViewGroup = (ViewGroup) findViewById(R.id.autoCompleteTextViewGroup);
textInputLayout = (TextInputLayout) findViewById(R.id.textInputLayout);
autoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);
progressBar = (ContentLoadingProgressBar) findViewById(R.id.progressBar);
}
public void setAdapter(ArrayAdapter<String> adapter) {
autoCompleteTextView.setAdapter(adapter);
}
public String getText() {
return autoCompleteTextView.getText().toString();
}
public void setErrorEnabled(boolean status) {
textInputLayout.setErrorEnabled(status);
}
public void setError(int errorId) {
textInputLayout.setError(getContext().getString(errorId));
}
public int getVisibility() {
return autoCompleteTextViewGroup.getVisibility();
}
public void setVisibility(int visibility) {
autoCompleteTextViewGroup.setVisibility(visibility);
autoCompleteTextViewGroup.setMinimumHeight(R.dimen.component_height);
}
public void setProgressBarVisibility(int visibility) {
progressBar.setVisibility(visibility);
}
public MAutoCompleteText setHint(int hintId) {
autoCompleteTextView.setHint(hintId);
return this;
}
public void setImeOption(int imeOption) {
autoCompleteTextView.setImeOptions(imeOption);
}
}
Everything work OK. I setVisibility(GONE) and my component hide from UI,
but when I use setVisibility(VISIBLE) doesn't happen any thing !!!!
How can I display my component programmatically?
I found answer of my problem , at least it works now ... :)
I change setVisibility to below code :
public void setVisibility(int visibility) {
autoCompleteTextViewGroup.setVisibility(visibility);
if (visibility == View.VISIBLE) {
textInputLayout.setVisibility(visibility);
autoCompleteTextView.setVisibility(visibility);
progressBar.setVisibility(visibility);
requestLayout();
}
}
In fact requestLayout(); reDraw layout of my component on UI again and it`s appear correctly .
I am trying to implement a custom typeface on an EditText. Does anyone have a better approach as opposed to what I'm currently doing?
Typeface myFont = Typeface.createFromAsset(getAssets(), "fonts/myfont.ttf");
edittext.setTypeface(myFont);
Because I have lots of EditTexts...
public class CEditText extends EditText {
private Context context;
private AttributeSet attrs;
private int defStyle;
public CEditText(Context context) {
super(context);
this.context=context;
init();
}
public CEditText(Context context, AttributeSet attrs) {
super(context, attrs);
this.context=context;
this.attrs=attrs;
init();
}
public CEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context=context;
this.attrs=attrs;
this.defStyle=defStyle;
init();
}
private void init() {
Typeface font=Typeface.createFromAsset(getContext().getAssets(), "fonts/myfont.ttf");
this.setTypeface(font);
}
#Override
public void setTypeface(Typeface tf, int style) {
tf=Typeface.createFromAsset(getContext().getAssets(), "fonts/myfont.ttf");
super.setTypeface(tf, style);
}
#Override
public void setTypeface(Typeface tf) {
tf=Typeface.createFromAsset(getContext().getAssets(), "fonts/myfont.ttf");
super.setTypeface(tf);
}
call this class in XML as follows
<yourpackagename.CEditText android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp">
</yourpackagename.CEditText>
Create a new class that extends EditText like
public class CustomEditTextNormal extends EditText
{
public CustomEditTextNormal(Context context)
{
super(context);
init(context);
}
public CustomEditTextNormal(Context context, AttributeSet attrs)
{
super(context, attrs);
init(context);
}
public CustomEditTextNormal(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
init(context);
}
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
}
public void init(Context context)
{
try
{
Typeface myFont = Typeface.createFromAsset(context.getAssets(), "fonts/myfont.ttf");
setTypeface(mSearchAndSend.HelveticaLight);
}
catch (Exception e)
{
Logger.LogError(e);
}
}
}
and include it on your XML like
<com.package.name.CustomEditText/>
How about create a new class that inherits EditText and sets the typeface you want and then instantiate the new class in the xml?
Create a new class which inherits from EditText, and then override the public void setTypeface(Typeface tf, int style) method and add your own font.
You need to make one method in Common class Like,
public void setExternalFonts(EdiText tv) {
Typeface tf = Typeface.createFromAsset(context.getAssets(),
"fonts/myfont.ttf");
tv.setTypeface(tf);
}
Now call this method as
yourClassName.setExternalFonts(yourEditText);
Create a new class which inherits from EditText, and then override the public void setTypeface(Typeface tf, int style) method and add your own font.
And use in your activity like this
FontLoader.setQuickSandTypeface(YourEditText) in your activity
try this one
public void overrideFonts(final Context context, final View v) {
try {
if (v instanceof ViewGroup) {
ViewGroup vg = (ViewGroup) v;
for (int i = 0; i < vg.getChildCount(); i++) {
View child = vg.getChildAt(i);
overrideFonts(context, child);
}
} else if (v instanceof EditText) {
((EditText) v).setTypeface(Typeface.createFromAsset(context.getAssets(), "roboto_thin.ttf"));
}
} catch (Exception e) {
e.printStackTrace();
}
}
Try this. Also useful for Buttons, TextViews.. whatever!
<your.namespace.app.FontEditText
app:font="montserrat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
How is possible? This way!
public class FontEditText extends EditText {
public FontEditText(Context context) {
this( context, null );
}
public FontEditText(Context context, AttributeSet attrs) {
this( context, attrs, 0 );
init( context, attrs );
}
public FontEditText(Context context, AttributeSet attrs, int defStyle) {
super( context, attrs, defStyle );
init( context, attrs );
}
public FontEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super( context, attrs, defStyleAttr, defStyleRes );
init( context, attrs );
}
private void init(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes( attrs, R.styleable.Fonts );
if ( ta != null ) {
String fontAsset = ta.getString( R.styleable.Fonts_font );
if ( !StringUtils.isEmpty( fontAsset ) ) {
int type = Integer.parseInt( fontAsset );
Typeface typeFace = FontManager.getInstance( context ).getByType( type );
ta.recycle();
super.setTypeface( typeFace );
}
}
}
}
public class FontManager {
private static FontManager Instance;
private Context context;
private Typeface robotoCondensedBold;
private Typeface robotoCondensed;
private Typeface robotoLight;
private Typeface kronica;
private Typeface montserrat;
private Typeface montserratLight;
private Typeface keepCalmMedium;
private FontManager(Context context) {
this.context = context;
this.robotoCondensedBold = Typeface.createFromAsset( context.getAssets(), "fonts/RobotoCondensed-Bold.ttf" );
this.robotoCondensed = Typeface.createFromAsset( context.getAssets(), "fonts/RobotoCondensed-Regular.ttf" );
this.robotoLight = Typeface.createFromAsset( context.getAssets(), "fonts/Roboto-Light.ttf" );
this.kronica = Typeface.createFromAsset( context.getAssets(), "fonts/kronika.ttf" );
this.montserrat = Typeface.createFromAsset( context.getAssets(), "fonts/Montserrat-Regular.ttf" );
this.montserratLight = Typeface.createFromAsset( context.getAssets(), "fonts/Montserrat-Light.ttf" );
this.keepCalmMedium = Typeface.createFromAsset( context.getAssets(), "fonts/KeepCalmMedium.ttf" );
}
public synchronized static FontManager getInstance(Context context) {
if ( Instance == null )
Instance = new FontManager( context );
return Instance;
}
public Typeface getByType(int type) {
switch ( type ) {
case 0:
return FontManager.getInstance( context ).getRobotoCondensedBold();
case 1:
return FontManager.getInstance( context ).getRobotoLight();
case 2:
return FontManager.getInstance( context ).getKronica();
case 3:
return FontManager.getInstance( context ).getRobotoCondensed();
case 4:
return FontManager.getInstance( context ).getMontserrat();
case 5:
return FontManager.getInstance( context ).getMontserratLight();
case 6:
return FontManager.getInstance( context ).getKeepCalmMedium();
default:
return Typeface.DEFAULT;
}
}
public Typeface getRobotoCondensedBold() {
return robotoCondensedBold;
}
public Typeface getKronica() {
return kronica;
}
public Typeface getRobotoCondensed() {
return robotoCondensed;
}
public Typeface getRobotoLight() {
return robotoLight;
}
public Typeface getMontserrat() {
return montserrat;
}
public Typeface getMontserratLight() {
return montserratLight;
}
public Typeface getKeepCalmMedium() {
return keepCalmMedium;
}
In addition, a font_attrs.xml in your res folder:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="Fonts">
<attr name="font" format="enum">
<enum name="robotoCondensedBold" value="0"/>
<enum name="robotoLight" value="1"/>
<enum name="kronica" value="2"/>
<enum name="robotoCondensed" value="3"/>
<enum name="montserrat" value="4"/>
<enum name="montserratLight" value="5"/>
<enum name="keepCalmMedium" value="6"/>
</attr>
</declare-styleable>
</resources>
Note that you only need to modify the FontManager and the font_attrs.xml to customize your fonts!