Android: Creating a custom component programmatically does not reflect the style applied - java

Created a custom button which extends AppCompatButton. The following are the constructors used:
public CustomButton(Context context)
{
this(context, null);
}
public CustomButton(Context context, AttributeSet attrs)
{
this(context, attrs, R.style.customStyle);
}
public CustomButton(final Context context, final AttributeSet attrs, final int defStyleAttr)
{
super(context, attrs, defStyleAttr);
}
Constructing CustomButton through XML works fine. However, when constructed in Java, it does not reflect the customStyle properties. Tried debugging the code. Though it passes through the second constructor doesn't take up the properties.
Any leads would be highly appreciated.

I was able to solve this by creating a ContextThemeWrapper object when creating CustomButton programmatically.
In activity file:
CustomButton customButton = new CustomButton( new ContextThemeWrapper(this, R.style.customStyle));

Related

Loading custom fonts without using a context

I already know Java and how it works, but I am new with the android related stuff. I have a font I want to use, and I want to load it in a separate class, however all the sites I found that show an example require the context from the MainActivity object, because it uses the getAssets() function. I need to load the font in without using that function.
Example of what I was shown
// This works, but I don't have access to the getContext().getAssets()
// in my separate class. Is there anyway I can do this without this function or XML?
Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "fonts/ExampleFont.ttf");
create CustomTextView class and use it your xml directly as Regular textview like below
customtextview class file
public class CustomTextView extends TextView {
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CustomTextView(Context context) {
super(context);
init();
}
private void init() {
Typeface tf = Typeface.createFromAsset(getContext().getAssets(),
"fonts/opensans.ttf");
setTypeface(tf);
}
}
use this as
<core.com.example.CustomTextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="#color/colorBlack"
android:textSize="14sp"
android:text="Test text with custom font"
android:lineSpacingExtra="2dp"
/>
UPDATE
As #EugenPechanec commented you can try this method which demonstrate here.

Prevent Style Change of Button

I initially set background of button with this code at onCreateView.
uc.setBackgroundResource(R.drawable.saat_button_none);
If I initially set background or textColor of button I want to prevent style change when I use onClick
public void onClick(View v) {
switch (v.getId()) {
case R.id.bir:
uc.setBackgroundResource(R.drawable.saat_button); //Should not work
dort.setBackgroundResource(R.drawable.saat_button_sel);
bes.setBackgroundResource(R.drawable.saat_button_sel);
}
}
Is that possible?
Edit: I don't want to use if statement since I have lots of buttons I just want to lock style of button.
To do this, create a custom view simply by extending View and override all methods related to background and put your logic their if background has changed once then overridden method should throw exception saying that you can't change the style as it has been changed while setup the default look and feel.
public class CustomButton extends Button {
boolean backgroundChanged = true;
public CustomButton(Context context) {
this(context, null);
}
public CustomButton(Context context, #Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomButton(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public void setBackgroundResource(int resid) {
if(backgroundChanged){
throw new RuntimeException("you can't change the style as it has been changed while setup the default look and feel");
}
super.setBackgroundResource(resid);
}
}
At last in layout file replace <Button tag with <CustomButton

Android: How to set max to min values of numberpicker with offset of 10

I want to have number picker with values 10,20,30,40,50
when I'm doing like this:
minutePicker.setMaxValue(10);
minutePicker.setMinValue(1);
minutePicker.setDisplayedValues(values);
provided values is {"30", "40", "50", "60", "70"};
Im able to display values as expected but these are like edit text, when I'm taping on each value keyboard displays, how can I make it just display value as textview rather edit text
Create NumberPicker class like below
public class MyNumberPicker extends NumberPicker {
public MyNumberPicker(Context context, AttributeSet attrs) {
super(context, attrs);
processAttributeSet(attrs);
}
public MyNumberPicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
processAttributeSet(attrs);
}
private void processAttributeSet(AttributeSet attrs) {
//This method reads the parameters given in the xml file and sets the properties according to it
this.setMinValue(attrs.getAttributeIntValue(null, "min", 0));
this.setMaxValue(attrs.getAttributeIntValue(null, "max", 0));
}
}

How to read android default attributes of a View in java code

I want to have a custom TextView called MyTextView and i want to set a default TextSize in it's constructor only if no TextSize has been set in it's XML definition. How can i detect if a TextSize has been set in it's XML definition?
public class MyTextView extends TextView{
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
//How can i read TextSize from AttribureSet??
//if no TextSize has been set then SetTextSize(defaultTextSize);
}
}
Can any one help me please?
You can obtain style attributes like
public class MyTextView extends TextView{
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
String size = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "textSize");
}
}
Here's example:
final Resources.Theme theme = context.getTheme();
TypedArray array = theme.obtainStyledAttributes(attrs, R.styleable.YourStylable, R.attr.YourDefStyleAttr, 0);
Try this float size = new TextView(this).getTextSize();

Class could not be instantiated XML

I am trying to incorporate a guided tour in my Android application, but I have run into a very simple error that I cannot solve. This error is in my XML file. Here it is:
The following classes could not be instantiated:
- com.rohit.ShowcaseView (Open Class, Show Exception)
Exception Details java.lang.NoSuchMethodException: com.rohit.ShowcaseView.<init>
(android.content.Context, android.util.AttributeSet)   at java.lang.Class.getConstructor0(Class.java:2730)   at java.lang.Class.getConstructor(Class.java:1676)   at android.view.LayoutInflater.inflate(LayoutInflater.java:469)   at android.view.LayoutInflater.inflate(LayoutInflater.java:373)
Here is my entire XML file:
<?xml version="1.0" encoding="utf-8"?>
<!-- This is our ShowCase template that we will use
whenever we want to showcase an item.
Here we can customise the colors of the showcase. -->
<com.rohit.ShowcaseView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:showcaseview="http://schemas.android.com/apk/res/com.rohit"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
showcaseview:sv_backgroundColor="#color/showcase_background"
showcaseview:sv_buttonText="#string/showcase_button_ok" />
Here is part of my ShowcaseView class:
protected ShowcaseView(Context context) {
this(context, null, R.styleable.CustomTheme_showcaseViewStyle);
}
protected ShowcaseView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// Get the attributes for the ShowcaseView
final TypedArray styled = context.getTheme()
.obtainStyledAttributes(attrs, R.styleable.ShowcaseView, R.attr.showcaseViewStyle,
R.style.ShowcaseView);
mBackgroundColor = styled
.getInt(R.styleable.ShowcaseView_sv_backgroundColor, Color.argb(128, 80, 80, 80));
int showcaseColor = styled
.getColor(R.styleable.ShowcaseView_sv_showcaseColor, Color.parseColor("#33B5E5"));
int titleTextAppearance = styled
.getResourceId(R.styleable.ShowcaseView_sv_titleTextAppearance,
R.style.TextAppearance_ShowcaseView_Title);
int detailTextAppearance = styled
.getResourceId(R.styleable.ShowcaseView_sv_detailTextAppearance,
R.style.TextAppearance_ShowcaseView_Detail);
buttonText = styled.getString(R.styleable.ShowcaseView_sv_buttonText);
styled.recycle();
metricScale = getContext().getResources().getDisplayMetrics().density;
mEndButton = (Button) LayoutInflater.from(context).inflate(R.layout.showcase_button, null);
mShowcaseDrawer = new ClingDrawerImpl(getResources(), showcaseColor);
// TODO: This isn't ideal, ClingDrawer and Calculator interfaces should be separate
mTextDrawer = new TextDrawerImpl(metricScale, mShowcaseDrawer);
mTextDrawer.setTitleStyling(context, titleTextAppearance);
mTextDrawer.setDetailStyling(context, detailTextAppearance);
ConfigOptions options = new ConfigOptions();
options.showcaseId = getId();
setConfigOptions(options);
init();
}
What am I doing wrong here? I can't find the solution. Any help regarding this issue is appreciated.
you need to define a constructor in your custom view that takes context and AttributeSet as params:
public ShowcaseView(Context context, AttributeSet attrs) {
super(context, attrs);
}
It is needed to construct the object from xml file.
Just add this constructor to your class and include additional code if needed.
See the related part of logcat output that complains about non-existence of this constructor:
Exception Details java.lang.NoSuchMethodException: com.rohit.ShowcaseView.<init>
(android.content.Context, android.util.AttributeSet)

Categories