Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Referencing a custom Shape class in XML

I have been extending the standard range of Shape classes (RectShape, OvalShape and so on) by extending the Shape class to create my own custom set of shapes. For example, I have created a simple TriangleShape class, like so:

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.drawable.shapes.Shape;

public class TriangleLeftShape extends Shape {

@Override
public void draw(Canvas canvas, Paint paint) {
    Path path = new Path();
    path.setLastPoint(0, getHeight()/2);
    path.lineTo(getWidth(), getHeight());
    path.lineTo(getWidth(), 0);
    path.close();
    canvas.drawPath(path, paint);
    }
}

What I would like to do is create a Drawable resource entirely in XML using this class. Is this possible?

I'm aware that using one of the standard shapes is simply achieved by the following example, where the <shape> element represents a ShapeDrawable:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
<gradient android:startColor="#FFFF0000" android:endColor="#80FF00FF"
        android:angle="270"/>
</shape>

What I cannot see is how one would pass, in XML, a custom Shape class to this ShapeDrawable that's being defined in XML. I understand that the android:shape attribute is simply passing an enum value, which can only be rectangle, oval, line, or ring. It seems that there is no XML attribute to specify a custom Shape class.

However, the ShapeDrawable has a setShape() method, which seems to suggest I could programmatically set my custom Shape class, but not do it via XML.

How, if possible, can I make use of a custom Shape class in XML? I realise that I could create a custom View very easily to draw my basic shapes, but use of Drawables seems to have the advantage of being able to specify colours, etc. and other attributes in XML or styles / themes.

like image 702
Trevor Avatar asked Nov 05 '12 20:11

Trevor


1 Answers

Custom drawables cannot be referenced from xml, but you can easily create subclass which can be used in layouts.

package com.example;

import android.content.Context;
import android.graphics.Canvas;   
import android.text.Layout;
import android.util.AttributeSet;
import android.view.View;


public class TextView extends android.view.TextView {

    public TextView(Context context, AttributeSet attrs) {
        super(context, attrs);

        setBackground(new MyCustomDrawable());
    }    
}

and use it in layout.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <com.example.TextView android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:text="my textview with custom drawable as background" 
    />

</FrameLayout>

By using this trick you can not only set background with custom drawable but also set compound drawables(it class is derived from TextView/Button)

like image 51
curioushikhov Avatar answered Oct 08 '22 19:10

curioushikhov