android:src attrs for custom view - android

Is there a way to set default android attrs to the custom view, that would be available when defining this view in xml?. For example, I need to create CustomImageView that will be FrameLayout with ImageView and ProgressBar inside it. If I add such view in xml I want to set background or src of that view, for example. FrameLayout has no android:src attribute and it doesn't offer via Android Studio autocomplete window, can I make somehow Android Studio to know that this layout can process such attributes?

The trick is to put android:src in custom styleables, located at values/attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyView">
<attr name="android:src"/>
</declare-styleable>
</resources>
And having MyView class that is a descendant of a View, then in xml file we'd see this:

Related

Custom view attribute how to check is it selector or drawable

One of my custom view attribute is:
<attr name="socialViewAndroid_iconSrc" format="reference"/>
I need to check whether it is selector or direct icon drawable.
Passing selector:
app:socialViewAndroid_iconSrc="#drawable/selector"
Or passing icon drawable:
app:socialViewAndroid_iconSrc="#drawable/icon_drawable"
In custom view constructor:
mIconSrc = a.getResourceId(R.styleable.LikeViewHorizontal_socialViewAndroid_iconSrc, -1);
Now I need to know is mIconSrc a selector or icon drawable.

Android how to use app attribute for custom class options [duplicate]

I know it is possible to create custom UI element (by way of View or specific UI element extension). But is it possible to define new properties or attributes to newly created UI elements (I mean not inherited, but brand new to define some specific behavior I am not able to handle with default propertis or attributes)
e.g. element my custom element:
<com.tryout.myCustomElement
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Element..."
android:myCustomValue=<someValue>
/>
So is it possible to define MyCustomValue?
Thx
Yes. Short guide:
Create an attribute XML
Create a new XML file inside /res/values/attrs.xml, with the attribute and its type
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<declare-styleable name="MyCustomElement">
<attr name="distanceExample" format="dimension"/>
</declare-styleable>
</resources>
Basically you have to set up one <declare-styleable /> for your view that contains all your custom attributes (here just one). I never found a full list of possible types, so you need to look at the source for one I guess. Types that I know are reference (to another resource), color, boolean, dimension, float, integer and string. They are pretty self-explanatory
Use the attributes in your layout
That works the same way you did above, with one exception. Your custom attribute needs its own XML namespace.
<com.example.yourpackage.MyCustomElement
xmlns:customNS="http://schemas.android.com/apk/res/com.example.yourpackage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Element..."
customNS:distanceExample="12dp"
/>
Pretty straight forward.
Make use of the values you get passed
Modify the constructor of your custom view to parse the values.
public MyCustomElement(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyCustomElement, 0, 0);
try {
distanceExample = ta.getDimension(R.styleable.MyCustomElement_distanceExample, 100.0f);
} finally {
ta.recycle();
}
// ...
}
distanceExample is a private member variable in this example. TypedArray has lots of other things to parse other types of values.
And that's it. Use the parsed value in your View to modify it, e.g. use it in onDraw() to change the look accordingly.
In your res/values folder create attr.xml. There you can define your attribues:
<declare-styleable name="">
<attr name="myCustomValue" format="integer/boolean/whatever" />
</declare-styleable>
When you then want to use it in your layout file you have to add
xmlns:customname="http://schemas.android.com/apk/res/your.package.name"
and then you can use the value with customname:myCustomValue=""
Yes , you can.Just use <resource> tag.
like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="CodeFont" parent="#android:style/TextAppearance.Medium">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#00FF00</item>
<item name="android:typeface">monospace</item>
</style>
</resources>
link from official website

Custom linear layout in XML

I have a class extending LinearLayout which receives an array and creates a layout based on
the array.
Now creating the layout in the OnCreate method of the activity and using setContentView
to the layout.
I want to know whether I could use it in an XML as I would use LinearLayout or a similiar way in a layout xml file.
If you want to use your custom LinearLayout in your layout, declare a new element with <path_to_your_custom_layout_class....
Yes you can.
in XML layout:
<com.my.package.MyView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:MyStyleable="http://schemas.android.com/apk/res/com.my.package"
android:id="#id/id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
MyStyleable:attr1="ATTR1 VALUE"
MyStyleable:attr2="ATTR2 VALUE" />
Notice the custom xml namespace xmlns:MyStyleable which will contain the custom attributes.
Define the custom attributes in res/values/attr.xml :
<resources>
<attr name="attr1" format="string" />
<attr name="attr2" format="boolean" />
</resources>
Then in your custom view class, retrieve the values from XML :
String attr1 = a.getString(R.styleable.attr1);
boolean attr2 = a.getBoolean(R.styleable.attr2);
Hope it's clear. !

Including padding on activities with themes in android

I am trying to match the style of a website with my app and on the website there is always a 10 pixel border around every page that just shows the background. I am trying to set up my activities to include that with themes, so I don't need to pad every layout I write. Is there a way for me to theme this? I've been looking through all of the available theme items and haven't been able to find it, but this is my first time using themes.
I would approach this task by setting up a margin or padding in your top layer container in the hierarchy of views in activity.
First, define an attribute.
res/attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="desiredActivityBorder" format="dimension" />
</resources>
Then, in your layout for activty use this atribute:
layout/your_activiy.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:width="match_parent"
android:height="match_parent"
android:padding="?desiredActivityBorder">
... your views go in here ...
</LinearLayout>
Of course this assumes that your LinearLayout background is transparent so one can see through to background beneath.
All you have to do know is to set a value for this attribute in your theme.
<style name="YourTheme" parent="Holo.Theme ">
<item name=" desiredActivityBorder">10dp</item>
</style>

Error applying image style dynamically, why?

attrs.xml:
<declare-styleable name="AppTheme">
<attr name="actionbarCompatLogoStyle" format="reference" />
</declare-styleable>
styles.xml:
<style name="Theme.MyApp" parent="android:style/Theme.Light">
<item name="actionbarCompatLogoStyle">#style/ActionBarCompatLogo</item>
</style>
<style name="ActionBarCompatLogo">
<item name="android:layout_width">30dp</item><!-- original image is huge -->
<item name="android:layout_height">30dp</item>
<item name="android:src">#drawable/app_logo</item>
</style>
Problem: if I use this, image dimensions won't work (huge image):
ImageButton logo = new ImageButton(context, null, R.attr.actionbarCompatLogoStyle);
If I use this, it works (tiny image, which is what I want):
<ImageView style="#style/ActionBarCompatLogo"></ImageView>
Why?
Any attribute prefixed with layout_ is part of a LayoutParams object. LayoutParams are special arguments to the parent view about how it should lay out the child view. The type of LayoutParams you set on a view is dependent on what type of ViewGroup you are adding it to. Each container view type can be different and so can the LayoutParams. layout_weight is specific to LinearLayout, layout_below is for RelativeLayout, etc. layout_width and layout_height are part of the base ViewGroup LayoutParams.
The takeaway from this is that LayoutParams are not parsed by the view's constructor, they're parsed by another step that your code above isn't doing. (The LayoutInflater involves the parent ViewGroup's generateLayoutParams method.)
Since LayoutParams are dependent on the intended parent of the View it's not recommended to put LayoutParams in styles. It mostly works when you are inflating views from layout XML but it has other implications similar to the edge case you've found here and requires you to be aware of them. For example, a style may specify layout_weight for a LinearLayout but if a view with that style is added to a RelativeLayout instead it will not behave as expected since RelativeLayout does not support layout_weight.
As far as I know it's not possible to apply styles to specific views programmatically, only via XML.
What you can do is to set a theme on your activity inside the onCreate() method. Consult this question: android dynamically change style at runtime

Categories

Resources