1

I have an XML file with a button that has an onClick = "BeginRecall" defined. I have implemented the method in my java class file as well but somehow it shows as it is not used and it crashes my application when i press the button with the Method not found error.

I find this strange as this is not the first instance where I use the onClick in my package. Appreciate if someone can point out what I missed.

This is the XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="fantasy.myapplication.Fragment_treasures">

<!-- TODO: Update blank fragment layout -->

... I removed the other stuff

<Button
    android:text="Begin Ancestral Recall"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/btn_research"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true"
    android:onClick="BeginRecall"/>

<ImageView
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:id="@+id/iv_research"
    android:layout_below="@+id/btn_research"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="28dp" />

</RelativeLayout>

This is my Fragment_treasures class

package fantasy.myapplication;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import java.util.Random;

import cn.pedant.SweetAlert.SweetAlertDialog;
import fantasy.myapplication.Player.Player;

import static android.app.Activity.RESULT_OK;

public class Fragment_treasures extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PLAYER = "thisplayer";
private static final int RESEARCH_COST = 501;
private Player currentplayer;

private Button btn_research;
private ImageView iv_research;
private int GENERATE_SUMMON = 1;

String[] card_common;
String[] card_novel;
String[] card_epic;
String[] card_legendary;
String[] card_event;
TypedArray card_imgs;


// Chance table
private final int chance_common = 100;
private final int chance_novel = 85;
private final int chance_epic = 90;
private final int chance_legendary = 95;
//chance_event by default would be (100 - chance_legendary)

private OnFragTreasureInteractionListener mListener;

public Fragment_treasures() {
    // Required empty public constructor
}

public static Fragment_treasures newInstance(Player player) {
    Fragment_treasures fragment = new Fragment_treasures();
    Bundle args = new Bundle();
    args.putParcelable(ARG_PLAYER, player);
    fragment.setArguments(args);
    return fragment;
}

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

    Bundle bundle = this.getArguments();
    if (bundle != null){
        currentplayer = bundle.getParcelable(ARG_PLAYER);
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.fragment_treasures, container,     false);

    Activity activity = getActivity();
    if(activity != null && isAdded()) {
        card_common = getResources().getStringArray(R.array.card_common);
        card_novel = getResources().getStringArray(R.array.card_novel);
        card_epic = getResources().getStringArray(R.array.card_epic);
        card_legendary =     getResources().getStringArray(R.array.card_legendary);
        card_event = getResources().getStringArray(R.array.card_event);


        btn_research = (Button) v.findViewById(R.id.btn_research);
        iv_research = (ImageView) v.findViewById(R.id.iv_research);
    }
    return v;
}

public void BeginRecall(View v) {

    if (currentplayer.crystals > 501) {
        final Random rand = new Random();
        int rint = rand.nextInt(100) + 1;

        if (rint <= chance_common) {
            TypedArray card_imgs = getResources().obtainTypedArray(R.array.img_card_common);
            rint = rand.nextInt(card_imgs.length());
            iv_research.setImageResource(card_imgs.getResourceId(rint, 0));
        } else if (rint <= chance_novel) {
            rint = rand.nextInt(card_novel.length);
        } else if (rint <= chance_epic) {
            rint = rand.nextInt(card_epic.length);
        } else if (rint <= chance_legendary) {
            rint = rand.nextInt(card_legendary.length);
        } else {
            rint = rand.nextInt(card_event.length);
        }

        Intent i = new Intent(getActivity(),Activity_Recall.class);
        startActivityForResult(i,GENERATE_SUMMON);

        //if (mListener != null){
        //mListener.onFragTreasureInteraction(RESEARCH_COST);
        //}
    } else {
        new SweetAlertDialog(getActivity(), SweetAlertDialog.ERROR_TYPE)
                .setTitleText("Oops...")
                .setContentText("Not enough crystals!")
                .show();
    }

}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == GENERATE_SUMMON && resultCode == RESULT_OK){
        String s = data.getStringExtra("data");
        Toast.makeText(getContext(),s, Toast.LENGTH_SHORT).show();
    }

}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof OnFragTreasureInteractionListener) {
        mListener = (OnFragTreasureInteractionListener) context;
    } else {
        throw new RuntimeException(context.toString()
                + " must implement OnFragmentInteractionListener");
    }



}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}


public interface OnFragTreasureInteractionListener {
    // TODO: Update argument type and name
    void onFragTreasureInteraction(int crystals);
}
}

This is the error:

01-08 02:23:41.762 2924-2924/? E/AndroidRuntime: FATAL EXCEPTION: main
                                             Process: fantasy.myapplication, PID: 2924
                                             java.lang.IllegalStateException: Could not find method BeginRecall(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'btn_research'

1 Answers1

0

Your error says you have included your xml inside another[in your fragment which is loaded inside your base activity] let's sat its parent xml, and that xml is not in the same class[of course you have it in your fragment class not in your activity].So you need to define your method in your parent activity !

solution : you are having that BeginRecall inside fragment that method should be inside the activity where you load the fragment!

If you want to handle clicks inside the fragment class then do something like below without using your own method

  public class Fragment_treasures extends Fragment implements OnClickListener{

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {

            View v = inflater.inflate(R.layout.fragment_treasures, container, false);

            Button b = (Button) v.findViewById(R.id.StartButton);
            b.setOnClickListener(this);
            return v;
        }

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.StartButton:

                ...

                break;
            }
        }
    }

For more : Read How to handle button clicks using the XML onClick within Fragments

Community
  • 1
  • 1
Charuක
  • 12,953
  • 5
  • 50
  • 88