colymore
colymore

Reputation: 12326

Abstract class in CustomView android error instantiting

i am doing a customviews implementing an abstract class, with this code:

public abstract class ReplyView extends View {

    protected RelativeLayout baseLayout;

    public ReplyView(Context context) {
        super(context);
        init(context);
    }

    public ReplyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public ReplyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    public void init(Context context) {
        setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        baseLayout = new RelativeLayout(context);
        baseLayout.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        initializeComponents();
    }


    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        onImplementationDraw();
        baseLayout.draw(canvas);
    }

    public abstract void initializeComponents();

    public abstract void onImplementationDraw();

    public abstract String getResult();
}

And this is a implementation:

public class YesNoReplyView extends ReplyView {

    private ToggleButton toggleButton;

    public YesNoReplyView(Context context) {
        super(context);
    }

    public YesNoReplyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public YesNoReplyView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void initializeComponents() {
        toggleButton = new ToggleButton(getContext());
        toggleButton.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
        toggleButton.setTextOn("Si");
        toggleButton.setTextOn("No");
//        toggleButton.setBackground(getContext().getResources().getDrawable(R.drawable.selector_toggle));
    }

    @Override
    public void onImplementationDraw() {

    }

    @Override
    public String getResult() {
        String result = toggleButton.isChecked() ? "Si" : "No";
        return result;
    }
}

I have this in my fragment:

public class ReplyFragment extends Fragment {

    @InjectView(R.id.replyView)
    ReplyView replyView;
    private int replie;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        replie = getArguments().getInt("reply");
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        initReplyView();
        View view = inflater.inflate(R.layout.work_reply_fragment, container, false);
        ButterKnife.inject(this, view);
        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    private void initReplyView() {
        switch (replie) {
            case 1:
                replyView = new TextReplyView(getActivity());
                break;
            case 2:
                replyView = new IntNumberReplyView(getActivity());
                break;
            case 3:
                //Fecha replyView = new
                break;
            case 4:
                replyView = new YesNoReplyView(getActivity());
                break;
            case 5:
                replyView = new GoodBadReplyView(getActivity());
                break;
            case 6:
                //Decimal
                break;
            case 7:
                //mes año
                break;
            case 8:
                replyView = new YearReplyView(getActivity());
                break;
            case 9:
                replyView = new TextReplyView(getActivity());
                break;
            default:
                replyView = null;
                break;
        }
    }
}

In my XML i have a view with this customview.

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fontawesometext="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="32dp"
        android:layout_marginBottom="16dp"
        android:layout_marginRight="16dp">

        <com.beardedhen.androidbootstrap.FontAwesomeText
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="4dp"
            android:textSize="45sp"
            android:textColor="#737373"
            android:id="@+id/faIcon"
            fontawesometext:fa_icon="fa-question" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="Este es un eaa asd jemplo de pregunta blablabla"
            android:id="@+id/tvQuestion"
            android:textColor="@color/primary"
            android:textStyle="bold"
            android:textSize="28sp"
            android:typeface="monospace"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="32dp"
            android:layout_marginBottom="16sp" />
    </LinearLayout>

    <view
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/replyView"
        class="com.firext.android.activities.work.reply.ui.ReplyView" />


</LinearLayout>

And i get this error:

08-21 21:15:08.915  14180-14180/com.firext.android E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.firext.android, PID: 14180
    android.view.InflateException: Binary XML file line #44: Error inflating class com.firext.android.activities.work.reply.ui.ReplyView
            at android.view.LayoutInflater.createView(LayoutInflater.java:629)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:739)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:802)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:500)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:410)
            at com.firext.android.activities.work.reply.ReplyFragment.onCreateView(ReplyFragment.java:46)
            at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:938)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1115)
            at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
            at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1478)
            at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:478)
            at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:163)
            at android.support.v4.view.ViewPager.populate(ViewPager.java:1068)
            at android.support.v4.view.ViewPager.populate(ViewPager.java:914)
            at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1436)
            at android.view.View.measure(View.java:16987)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5257)
            at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
            at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
            at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
            at android.view.View.measure(View.java:16987)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5257)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:314)
            at android.view.View.measure(View.java:16987)
            at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:704)
            at android.view.View.measure(View.java:16987)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5257)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:314)
            at android.view.View.measure(View.java:16987)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5257)
            at com.android.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:447)
            at android.view.View.measure(View.java:16987)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5257)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:314)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2429)
            at android.view.View.measure(View.java:16987)
            at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1986)
            at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1157)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1368)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1044)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5749)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
            at android.view.Choreographer.doCallbacks(Choreographer.java:580)
            at android.view.Choreographer.doFrame(Choreographer.java:550)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
            at android.os.Handler.handleCallback(Handler.java:738)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5070)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:836)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:631)
     Caused by: java.lang.InstantiationException: Can't instantiate abstract class com.firext.android.activities.work.reply.ui.ReplyView
            at ja

Whats wrong?

Upvotes: 2

Views: 2037

Answers (2)

Code-Apprentice
Code-Apprentice

Reputation: 83557

<view
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/replyView"
    class="com.firext.android.activities.work.reply.ui.ReplyView" />

Here is where you are attempting to instantiate an abstract class. You cannot use ReplyView here. Rather you should do something like

<com.firext.android.activities.work.reply.ui.YesNoReplyView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/replyView" />

Note that you can use your custom view's name directly as a tag.

Edit:

After looking more closely at your code, you seem to need something more dynamic than this. At the moment, I don't have any good suggestions for you. Perhaps you should start a new question regarding your design. Be sure to include details about your specific requirements.

Also, you can probably simplify your custom view classes by using a XML layout rather than overriding initializeComponents().

Upvotes: 1

Judah Schvimer
Judah Schvimer

Reputation: 136

You can't instantiate an abstract class. Abstract classes are meant to be subclassed. If you want to contractualize those methods making an auxiliary interface might help, but it really depends on your intended design.

http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

Upvotes: 1

Related Questions