I'm using some simvot number picker in application, I want to create custom widget for that and use in all of project, now i'm create this files but I can not set any value for custom widget.
My attributes:
<declare-styleable name="CNumberPicker">
<attr name="maxValue" format="string" />
<attr name="minValue" format="string" />
<attr name="value" format="string" />
</declare-styleable>
My Custom NumberPicker widget:
public class CNumberPicker extends net.simonvt.numberpicker.NumberPicker implements OnClickListener {
private int maxValue;
private int minValue;
private int value;
public CNumberPicker(Context context) {
super(context);
}
public CNumberPicker(Context context, AttributeSet attrs) {
super(context, attrs);
processAttributeSet(attrs);
}
public CNumberPicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CNumberPicker, defStyle, 0);
processAttributeSet(attrs);
maxValue = Integer.parseInt(a.getString(R.styleable.CNumberPicker_maxValue));
minValue = Integer.parseInt(a.getString(R.styleable.CNumberPicker_minValue));
a.recycle();
setOnClickListener(this);
}
#Override
public void onClick(View v) {
}
private void processAttributeSet(AttributeSet attrs) {
this.setMaxValue(attrs.getAttributeIntValue(null, "maxValue", 0));
}
}
My defined widget into xml:
<com.sample.widget.CNumberPicker
android:id="#+id/np_choose_hour"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:layout_weight="0.20"
android:gravity="center_horizontal"
app:maxValue="10"
app:minValue="1"
app:value="5">
</com.sample.widget.CNumberPicker>
how to set value defined into xml in layout?
You have to inflate the layout in code.
public CNumberPicker(Context context) {
super(context);
LayoutInflater.from(context).inflate(R.layout.cnumberpicker, this);
}
presuming the layout file is cnumberpicker.xml
EDIT: These 3 functions are constructors. Any one of them could be called to construct the object. By using this instead of super we can force all constructors to end up calling the 3 parameter constructor. You need some cohesion here. You don't want to copy paste code every time you make one change.
public CNumberPicker(Context context) {
this(context, null);
}
public CNumberPicker(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CNumberPicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CNumberPicker, defStyle, 0);
processAttributeSet(attrs);
// this method allows a default value if no attributes are given. You should use them.
maxValue = Integer.parseInt(a.getString(R.styleable.CNumberPicker_maxValue,"10"));
minValue = Integer.parseInt(a.getString(R.styleable.CNumberPicker_minValue,"0"));
a.recycle();
}
Related
I got the error when use attribute in child view of a CustomLayout (I have define a custom LayoutParams to allow child view use this attribute)
However, code's still RUNNING and display correct value (you can check my code below, when I run app it will display "Hello" in logcat)
Here is my code
style.xml
<declare-styleable name="CustomRelativeLayout_Layout">
<attr name="title" format="string" />
</declare-styleable>
CustomRelativeLayout class
public class CustomRelativeLayout extends RelativeLayout {
public CustomRelativeLayout(Context context) {
this(context, null);
}
public CustomRelativeLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new CustomLayoutParams(getContext(), attrs);
}
#Override
public void onViewAdded(View child) {
super.onViewAdded(child);
CustomLayoutParams layoutParams = (CustomLayoutParams) child.getLayoutParams();
Log.i("TAG", "title = " + layoutParams.title);
}
final class CustomLayoutParams extends RelativeLayout.LayoutParams {
String title;
CustomLayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
TypedArray ta =
c.obtainStyledAttributes(attrs, R.styleable.CustomRelativeLayout_Layout);
title = ta.getString(R.styleable.CustomRelativeLayout_Layout_title);
ta.recycle();
}
}
}
Of course, I can disable it by add tools:ignore="MissingPrefix" but I don't like this much. Any help or suggestion would be great appreciated.
Here is my demo https://github.com/PhanVanLinh/AndroidPassAttributeToChildVIew
After many try, I found a solution for my problem
Change title to layout_title will make the error gone
<declare-styleable name="CustomRelativeLayout_Layout">
<attr name="title" format="string" />
</declare-styleable>
The magic is layout_ because the error still happened if I use like
title_, title_dasdasdsad, lo_title, title_23232
I need to style the text for textview as per the below image
The font being used is CARTER ONE font
This is my textview class
public class CustomTextViewCarter extends TextView {
private static Typeface mTypeface;
public CustomTextViewCarter(final Context context) {
this(context, null);
}
public CustomTextViewCarter(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomTextViewCarter(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
if (!isInEditMode()) {
if (mTypeface == null) {
mTypeface = Typeface.createFromAsset(context.getResources().getAssets(), "carter_one.ttf");
}
setTypeface(mTypeface);
}
}
}
But the the same kind of text doesn't appear. How can it be done?
Use this code for show custom TextView
Step-1:
CustomTextView.java
public class CustomTextView extends TextView {
private static final String TAG = "TextView";
public CustomTextView(Context context) {
super(context);
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
setCustomFont(context, attrs);
}
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setCustomFont(context, attrs);
}
private void setCustomFont(Context ctx, AttributeSet attrs) {
TypedArray a = ctx.obtainStyledAttributes(attrs,R.styleable.CustomTV);
String customFont = a.getString(R.styleable.CustomTV_customFont);
setCustomFont(ctx, customFont);
a.recycle();
}
public boolean setCustomFont(Context ctx, String asset) {
Typeface tf = null;
try {
tf = Typeface.createFromAsset(ctx.getAssets(), asset);
} catch (Exception e) {
Log.e(TAG, "Could not get typeface: "+e.getMessage());
return false;
}
setTypeface(tf);
return true;
}
}
Step-2:
After that write below code in your styles.xml file
<declare-styleable name="CustomTV">
<attr name="customFont" format="string"></attr>
</declare-styleable>
Step-3:
Use CustomTextView in your xml file
Here com.app.demo is my package name.. use your package name instead of that,
<com.app.demo.CustomTextView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="hello"
android:textColor="#color/text"
android:textStyle="bold"
app:customFont="carter_one.ttf" />
Try this.
You can set ttf by making your own textview implementation.
It will works above API 15 (Ice cream sandwich).
https://stackoverflow.com/a/5185587/850347
<com.lht.ui.MyTextView
android:text="Hello friends"
lht:ttf_name="ITCBLKAD.TTF"
/>
i'm created simple widget extends from ImageView, in this simle code i want to set image into ImageView from layout xml,i want change background imageview image and change image to set other image into ImageView, but my problem in first time dont show image
1) i'm create new attribute into attr.xml:
<declare-styleable name="CIconButton">
<attr name="button_icon" format="integer" />
<attr name="background_icon" format="reference" />
</declare-styleable>
2) use CIconButton class into layout:
<!-- xmlns:app="http://schemas.android.com/apk/res/com.sample.app.tpro" -->
<com.sample.widget.CIconButton
android:id="#+id/imgv_update_selected_phones"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
app:button_icon="#drawable/icon_add_action" />
3) CIconButton class
public class CIconButton extends ImageView implements OnClickListener {
private Drawable mSelectedBackground;
public CIconButton(Context context) {
super(context, null);
}
public CIconButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CIconButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CIconButton, defStyle, 0);
mSelectedBackground = a.getDrawable(R.styleable.CIconButton_button_icon);
setImageDrawable(mSelectedBackground);
a.recycle();
setOnClickListener(this);
}
#Override
public void onClick(View v) {
}
}
PROBLEM:
my custom widgets class dont show image set into layout xml, for example this class dont show icon_add_action from drawable
My problem resolved , i must be change second constructor as :
public CIconButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
to:
public CIconButton(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
this call last this class constrctor
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" />
I create an attribute in attrs.xml file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="Custom">
<attr name="src" format="integer" />
</declare-styleable>
</resource>
And in my code, I get the value of the attribute like this:
attrs.getAttributeIntValue("mynamespace", "src", -1);
It works. I get the value of 'src' from the layout xml file.
But my question is why android does not generate a value in R class so that I don't need to use the string 'src' again in my java code?
Instead use the TypedArray
public CustomView(final Context context) {
this(context, null);
}
public CustomView(final Context context,
final AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomView(final Context context,
final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.Custom, defStyle, 0);
int src = a.getInt(R.styleable.Custom_src, 0);
a.recycle();
}