I'm a beginner. I want to define the xml for a custom EditText and then programmatically add those custom edittexts at runtime without using a bunch of code to customize the editTexts. This could be similar to implementing custom buttons, textviews, etc. from libraries...although it would be my own. What is the best way to approach this?
Thanks!
Alternative code apart from code shared in above comment link is below :
basically this code makes easy for user to customize the fonts etc.
public class MyEditText extends EditText {
public MyEditText(Context context) {
super(context);
}
public MyEditText(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes(context, attrs);
}
public MyEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
parseAttributes(context, attrs);
}
private void parseAttributes(Context context, AttributeSet attrs) {
TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.Simplified);
int typefaceValue = values.getInt(R.styleable.Simplified_typeface, 0);
values.recycle();
setTypeface(MyFontUtil.obtaintTypeface(context, typefaceValue));
}
}
XML
<com.my.mtetno.widget.MyEditText
android:id="#+id/uname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#drawable/lh_edit_field_without_border"
android:inputType="textEmailAddress"
android:maxLines="1"
android:overScrollMode="always"
android:textSize="#dimen/login_page_edit_text_size"
app:typeface="simplified_regular" />
Related
I want to implement a custom ImageView with some predefined attributes based on the xml file. To do that I prepared a layout wrapped within merge tag:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:id="#+id/my_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="center"
android:src="#drawable/icon" />
</merge>
And extended ImageView class:
public class CustomImageView extends LinearLayout{
public ImageFormField(Context context) {
super(context);
init();
}
public ImageFormField(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public ImageFormField(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public ImageFormField(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init() {
View.inflate(getContext(), R.layout.custom_image_view, this);
}
}
It works so far, but I actually don't need that LinearLayout as I could extend directly from the ImageView. By extending ImageView I'd like to have the possibility to override src parameter from the default layout.
So I removed merge tag to have only ImageView in the layout and tried this:
public class CustomImageView extends AppCompatImageView{
public ImageFormField(Context context) {
super(context);
init();
}
public ImageFormField(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public ImageFormField(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
View.inflate(getContext(), R.layout.custom_image_view, null); //can't pass root here
}
}
... but the image is simply not displayed. I want to be able to use my view this way:
<com.my.package.CustomImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
with possibility to override src attribute. Is there a way to do that by inflating layout or do I have to go deep with attributes (including custom ones)?
UPDATE
By "overriding src attribute I mean that by default image will have source from its xml file, but user can use it that way to pass another value within this custom view:
<com.my.package.CustomImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/another_icon" />
To provide a "default" image but also allow the user to override that default by specifying the android:src attribute, you can do this:
package com.example.stackoverflow;
import android.content.Context;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
public class CustomImageView extends AppCompatImageView {
public CustomImageView(Context context, AttributeSet attrs) {
super(context, attrs);
if (getDrawable() == null) {
setImageResource(R.drawable.default_image);
}
}
}
Then you can use it like this:
<!-- will display `default_image` -->
<com.example.stackoverflow.CustomImageView
android:layout_width="200dp"
android:layout_height="200dp"/>
Or:
<!-- will display `other_image` -->
<com.example.stackoverflow.CustomImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:src="#drawable/other_image"/>
There's no need to inflate anything inside the custom image view, and no need to create custom attributes (though you could certainly create custom attributes and use them if you wanted to).
You could update the Java code to apply other "default" styles too.
What is correct way to extend EditText?
The problem is following:
I have empty application from template with two EditText:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="one"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="two"/>
</LinearLayout>
It works fine:
Then I create my custom view from EditText:
public class CuteEditText extends EditText {
public CuteEditText(Context context) {
this(context, null);
}
public CuteEditText(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CuteEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// some special initialization will be here
}
}
And when I change EditText to my CuteEditText, interface works incorrectly:
The problem is not only with view ot UI. If I type something in first EditText and than touch the second one, nohing happens: input will continue in first.
The same behaviour if I inherite CuteEditText from AppCompatEditText.
What is wrong?
Sources for experiment are available at https://github.com/tseglevskiy/EditTextExperiment
Your construtors are broken. This is how it should look:
public class CuteEditText extends EditText {
public CuteEditText(Context context) {
super(context);
}
public CuteEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CuteEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
You don't need the third constructor overload. The first one is for creating the view programmatically and the second one is for creating the view from xml. Those two should be enough for most cases.
public class CuteEditText extends EditText {
public CuteEditText(Context context) {
this(context, null);
}
public CuteEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
I am trying to replace the text in a customized text view. the purpose is to force the text to be LTR; In order to do that, I am adding the "\u200E" prefix to my text.
Right now the setText() does not take any affect on the customized textView.
public class LocalizedTextView extends TextView {
public LocalizedTextView(Context context) {
super(context);
init(context);
}
public LocalizedTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public LocalizedTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
this.setText("\u200E" + getText().toString());
}
}
And this is the customized element:
<com.tempProject.customviews.LocalizedTextView
android:id="#+id/item_text"
style="#style/DrawerSectionText"
android:textDirection="ltr" />
Any Idea to force textView with RTL content to align to the left for devices older than 4.2.0, will be more than welcome.
The android:supportsRtl flag has to be set to true in the manifest.
I want to create a custom view a thing like a power switch ( a switch that switches between ON and OFF). When I have started to implement it I faced 3 constructors for View class:
public CusatomView(Context context) {
super(context);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
Now my question is: Which one of these constructors I should complete it to retrieve my own XML attribute (for instance: textOn and textOff)?
And what is the role of each?
Ideally, you should do your stuff in a separate method and call this from all three constructors, because you never know which of the constructor will be called. Here are the roles:
CusatomView(Context context) creates a new view with no attributes initialized.
CustomView(Context context, AttributeSet attrs) is invoked when you set attributes like layout_height or layout_width in your layout.xml
CustomView(Context context, AttributeSet attrs, int defStyle) is used when you set styles to your view.
You should create another funciton init and call it in all.
public CusatomView(Context context) {
super(context);
init();
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CustomView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
The thing is any of this constructors can be used to instantiate your custom view. As in when you create a view in java code you just provide context and when it is created from xml attrs is also supplied.
I wonder if there is a way to change the font of all the text views in an android application in single time ? By all the text views i mean programmatically or dynamically created text views and the text views created separately using XML layout files (Drag n drop)?
I know i can create a new theme with different required fonts and use it . But i can only see the theme applies to dynamically created text views within the program but not the one's in XML layout .
Can you please let me know if there is any solution for this or the only option is to change the font of each text view manually.
The easiest way is to extend the TextView widget:
public class FontTextView extends TextView {
private String mTypefacePath;
public FontTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setAttrs(context, attrs, defStyle);
init(context);
}
public FontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
setAttrs(context, attrs, 0);
init(context);
}
public FontTextView(Context context) {
super(context);
init(context);
}
private void setAttrs(Context context, AttributeSet attrs, int defStyle) {
if (isInEditMode())
return;
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FontTextView, defStyle, 0);
mTypefacePath = a.getString(R.styleable.FontTextView_typeface);
a.recycle();
}
private void init(Context context) {
if (!TextUtils.isEmpty(mTypefacePath)) {
try {
setTypeface(Typeface.createFromAsset(context.getAssets(),
mTypefacePath));
} catch (Exception ex) {
// could not create the typeface from path
}
}
}}
You also need to define your typeface attribute.
Take a look on this to see a useful explanation about.