Sergey Efimov
Sergey Efimov

Reputation: 491

Implementing OnDraw method on static layout view

I want to implement onDraw() method for layout I have customized in Android Studio. I know how to do this with custom view, but I want to do this with my customized view and can't get info about this on the internet. This is the code for layout:

public class MainActivity extends ActionBarActivity
{
    CustomDrawableView mCustomDrawableView;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        mCustomDrawableView = new CustomDrawableView(this);

        //layoutMain.addView(mCustomDrawableView);
        //setContentView(mCustomDrawableView);
        //mCustomDrawableView.requestFocus();
    }
}

The custom drawable view:

class CustomDrawableView extends View
{
    private ShapeDrawable mDrawable;

    public CustomDrawableView(Context context)
    {
        super(context);

        int x = 10;
        int y = 10;
        int width = 300;
        int height = 50;

        mDrawable = new ShapeDrawable(new OvalShape());
        mDrawable.getPaint().setColor(0xff74AC23);
        mDrawable.setBounds(x, y, x + width, y + height);
    }

    protected void onDraw(Canvas canvas)
    {
        mDrawable.draw(canvas);
    }
}

The activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                android:paddingBottom="@dimen/activity_vertical_margin"
                tools:context=".MainActivity">

    <TextView
        android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textView"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Button"
        android:id="@+id/button"
        android:layout_below="@+id/textView"
        android:layout_toEndOf="@+id/textView"
        android:layout_marginTop="82dp"/>

</RelativeLayout>

The problem is i can choose only one view: static with no OnDraw() or dynamic with OnDraw() but without all my buttons/sliders and other elements. Can i combine them and implement main OnDraw() ?

        02-06 19:33:49.793    1823-1823/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
     java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.cepp.myapplication2/com.example.cepp.myapplication2.MainActivity}: android.view.InflateException: Binary XML file line #26: Error inflating class com.example.cepp.myapplication2.CustomDrawableView
                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
                at android.app.ActivityThread.access$600(ActivityThread.java:141)
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
                at android.os.Handler.dispatchMessage(Handler.java:99)
                at android.os.Looper.loop(Looper.java:137)
                at android.app.ActivityThread.main(ActivityThread.java:5041)
                at java.lang.reflect.Method.invokeNative(Native Method)
                at java.lang.reflect.Method.invoke(Method.java:511)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
                at dalvik.system.NativeStart.main(Native Method)
      Caused by: android.view.InflateException: Binary XML file line #26: Error inflating class com.example.cepp.myapplication2.CustomDrawableView
                at android.view.LayoutInflater.createView(LayoutInflater.java:596)
                at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
                at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
                at android.support.v7.app.ActionBarActivityDelegateBase.setContentView(ActionBarActivityDelegateBase.java:228)
                at android.support.v7.app.ActionBarActivity.setContentView(ActionBarActivity.java:102)
                at com.example.cepp.myapplication2.MainActivity.onCreate(MainActivity.java:98)
                at android.app.Activity.performCreate(Activity.java:5104)
                at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
            at android.app.ActivityThread.access$600(ActivityThread.java:141)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5041)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
            at dalvik.system.NativeStart.main(Native Method)
      Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet]
                at java.lang.Class.getConstructorOrMethod(Class.java:460)
                at java.lang.Class.getConstructor(Class.java:431)
                at android.view.LayoutInflater.createView(LayoutInflater.java:561)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
            at android.support.v7.app.ActionBarActivityDelegateBase.setContentView(ActionBarActivityDelegateBase.java:228)
            at android.support.v7.app.ActionBarActivity.setContentView(ActionBarActivity.java:102)
            at com.example.cepp.myapplication2.MainActivity.onCreate(MainActivity.java:98)
            at android.app.Activity.performCreate(Activity.java:5104)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
            at android.app.ActivityThread.access$600(ActivityThread.java:141)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5041)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
            at dalvik.system.NativeStart.main(Native Method)

Upvotes: 0

Views: 1561

Answers (1)

h0x0
h0x0

Reputation: 495

You never place the view in the activity. Treat you custom view just like any other View and put it in the layout

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:paddingLeft="@dimen/activity_horizontal_margin"
            android:paddingRight="@dimen/activity_horizontal_margin"
            android:paddingTop="@dimen/activity_vertical_margin"
            android:paddingBottom="@dimen/activity_vertical_margin"
            tools:context=".MainActivity">

    <TextView
        android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        <!--Add this line or the custom view will push these off the screen-->
        android:layout_parentTop="true"
        <!--  ************************ -->
        android:id="@+id/textView"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Button"
        android:id="@+id/button"
        android:layout_below="@+id/textView"
        android:layout_toEndOf="@+id/textView"
        android:layout_marginTop="82dp"/>

    <com.you.yourapp.CustomDrawableView  <!--com.you.yourapp is a stand in for the package name for your apk-->
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="+@id/button" />

</RelativeLayout>

then it will behave less or more like and ImageView

EDIT 2: That pattern is usually an error in the View code. Look at the Priview (all the way to the right in Android Studio, when you have the xml file open). If the view is ok, it will show up in the preview. If it isn't it will tell you where the exceptions are.

Upvotes: 1

Related Questions