Как указать, где искать метод OnClick, когда на фрагменте происходит событие onClick

  1. Я создал проект в Android Studio с активностью по умолчанию в качестве активности в Навигаторе навигации

  2. Затем созданы два новых фрагмента с именами Myfragment1 и Myfragment2.

  3. Затем реализованы методы для вызова соответствующих фрагментов, в зависимости от того, какая опция выбрана из панели навигации. Я загружаю эти фрагменты с помощью метода инфляции LayoutInflater. Код для этого был помещен в метод onCreateView класса MainActivity.

  4. Когда фрагмент Myfragment1 загружается, если я нажимаю кнопку добавления, которая находится на Myfragment1, тогда выдается ошибка "java.lang.IllegalStateException: Could not find a method".

  5. Я создал слушатель для кнопки в onCreateView файла Myfragment1.java

  6. Я указал, что он должен искать метод nClick в классе DatabaseActivity, но он по-прежнему выдает ошибку

MainActivity.java

public class MainActivity extends ActionBarActivity
    implements NavigationDrawerFragment.NavigationDrawerCallbacks {

       private NavigationDrawerFragment mNavigationDrawerFragment;
       private CharSequence mTitle;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mNavigationDrawerFragment = (NavigationDrawerFragment)
            getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
    mTitle = getTitle();

    // Set up the drawer.
    mNavigationDrawerFragment.setUp(
            R.id.navigation_drawer,
            (DrawerLayout) findViewById(R.id.drawer_layout));
}

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

        View rootView;
        switch (getArguments().getInt(ARG_SECTION_NUMBER)) {
            case 1:
                rootView = inflater.inflate(R.layout.fragment_myfragment1, container, false);
                break;
            case 2:
                rootView = inflater.inflate(R.layout.fragment_myfragment2, container, false);
                break;
            default:
                rootView = inflater.inflate(R.layout.fragment_myfragment1, container, false);
        }
        return rootView;
    }
}

Myfragment1.java

public class Myfragment1 extends Fragment implements View.OnClickListener
{

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
   View view  = inflater.inflate(R.layout.fragment_myfragment1, container, false);
    Button add = (Button) view .findViewById(R.id.button_add);
    add.setOnClickListener(this);
    return view ;
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.button_add:
            DatabaseActivity d= new DatabaseActivity();
            d.newProduct(v);
            break;
    }
}

}

Класс DatabaseActivity

public class DatabaseActivity extends ActionBarActivity 
{
    EditText productBox;
    EditText quantityBox;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        productBox = (EditText) findViewById(R.id.productBox);
        quantityBox = (EditText) findViewById(R.id.quantityBox);
    }

    public void newProduct (View view) {
        MyDBHandler dbHandler = new MyDBHandler(this, null, null, 1);
        int quantity = Integer.parseInt(quantityBox.getText().toString());
        Product product = new Product(productBox.getText().toString(), quantity);
        dbHandler.addProduct(product);
        productBox.setText("");
        quantityBox.setText("");
    }
}

Myfragment1.xml

<FrameLayout 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" tools:context="com.test.masterflow1.Myfragment1">

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


<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/delete_string"
    android:id="@+id/button_remove"
    android:onClick="removeProduct"
    android:layout_gravity="right|bottom" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/find_string"
    android:id="@+id/button_find"
    android:onClick="lookupProduct"
    android:layout_gravity="left|bottom" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/add_string"
    android:id="@+id/button_add"
    android:onClick="newProduct"
    android:layout_gravity="center_horizontal|bottom" />

<EditText
    android:layout_width="263dp"
    android:layout_height="wrap_content"
    android:id="@+id/productBox"

    android:layout_below="@+id/productID_Box"
    android:layout_alignParentEnd="true"
    android:layout_marginTop="72dp"
    android:layout_alignStart="@+id/productID_Box"
    android:layout_gravity="right|top" />

<EditText
    android:layout_width="51dp"
    android:layout_height="76dp"
    android:id="@+id/quantityBox"
    android:layout_centerVertical="true"
    android:layout_alignEnd="@+id/button3"
    android:layout_toEndOf="@+id/button2"
    android:layout_gravity="right|center_vertical" />

<TextView
    android:layout_width="64dp"
    android:layout_height="59dp"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:id="@+id/productID_Box"
    android:layout_alignWithParentIfMissing="false"
    android:layout_alignParentEnd="true"
    android:layout_alignStart="@+id/quantityBox"
    android:layout_gravity="right|top" />

LogCat

22733-22733/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.IllegalStateException: Could not find a method newProduct(View) in the activity class com.test.masterflow1.MainActivity for onClick handler on view class android.support.v7.internal.widget.TintButton with id 'button_add'
        at android.view.View$1.onClick(View.java:3791)
        at android.view.View.performClick(View.java:4439)
        at android.widget.Button.performClick(Button.java:139)
        at android.view.View$PerformClick.run(View.java:18395)
        at android.os.Handler.handleCallback(Handler.java:725)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:176)
        at android.app.ActivityThread.main(ActivityThread.java:5317)
        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:1102)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.NoSuchMethodException: newProduct [class android.view.View]
        at java.lang.Class.getConstructorOrMethod(Class.java:460)
        at java.lang.Class.getMethod(Class.java:915)
        at android.view.View$1.onClick(View.java:3784)
        at android.view.View.performClick(View.java:4439)
        at android.widget.Button.performClick(Button.java:139)
        at android.view.View$PerformClick.run(View.java:18395)
        at android.os.Handler.handleCallback(Handler.java:725)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:176)
        at android.app.ActivityThread.main(ActivityThread.java:5317)
        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:1102)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
        at dalvik.system.NativeStart.main(Native Method)

2 ответа

newProduct() при нажатии кнопки Add теперь вызывается. Сделал много исправлений, так что не знаю, где была ошибка. Внимательно следуйте коду, и я думаю, вы сами разберетесь.

myfragment1.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"
    tools:context="com.test.masterflow1.Myfragment1">

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

    <Button
        android:id="@+id/button_remove" <!--Use "@+id/..." for setting IDs -->
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right|bottom"
        android:onClick="removeProduct"
        android:text="Delete" />

    <Button
        android:id="@+id/button_find"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/button_remove" <!--And "@id/..." for referring them-->
        android:layout_gravity="left|bottom"
        android:onClick="lookupProduct"
        android:text="Find" />

    <Button
        android:id="@+id/button_add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/button_find"
        android:layout_gravity="center_horizontal|bottom"
        android:onClick="newProduct"
        android:text="Add" />

<!-- your other widgets-->

    </RelativeLayout>

Myfragment1.java

Следуйте надлежащему соглашению об именах Java. Обратитесь к руководству Google по стилю Java.

public class Myfragment1 extends Fragment implements View.OnClickListener {


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

    View view = inflater.inflate(R.layout.myfragment1, container, false);
    Button add = (Button) view.findViewById(R.id.button_add);
    add.setOnClickListener(this);
    return view;
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.button_add:
            DatabaseActivity d = new DatabaseActivity();
            d.newProduct(v);
            break;
    }
}}

MainActivity.java

  public class MainActivity extends AppCompatActivity {
    //Removed the navigation drawer code for simplicity

        private CharSequence mTitle;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            // Do this for adding the fragment programatically. There's also .replace() when you want to replace the added fragment with another fragment.
 getFragmentManager().beginTransaction().add(R.id.framelayout_activity_main, new Myfragment1()).commit();
  //There's no onCreateView() lifecycle method in Activities. It belongs in Fragments. Move the code from your onCreateView() appropriately. 

   }}

Мой Activity_main.xml был таким.

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

DatabaseActivity.java

public class DatabaseActivity extends ActionBarActivity {

EditText productBox;
EditText quantityBox;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    productBox = (EditText) findViewById(R.id.productBox);
    quantityBox = (EditText) findViewById(R.id.quantityBox);
}

public void newProduct(View view) {
    Log.i("DatabaseActivity", "newProduct() Called");
    // do the DbHandler stuff here.

}}

Подумайте о том, чтобы пройти курсы Android по Udacity. Они идеально подходят для начинающих.

----РЕДАКТИРОВАТЬ----

Я думаю, что ошибка могла быть в вашем MainActivity#onCreateView() . Попробуйте переместить этот блок переключателей в Myfragment1#onCreateView(). Аналогом фрагмента действия onCreate() класса Activity является onCreateView (). Прочитайте жизненные циклы Деятельности и Фрагмента.

Вы указываете метод, который хотите вызвать здесь:

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/add_string"
    android:id="@+id/button_add"
    android:onClick="newProduct" <-- this is what it's trying to call
    android:layout_gravity="center_horizontal|bottom" />

Обратите внимание, сообщение об ошибке не в том, что он не может найти onClick метод, но он не может найти newProduct метод на Activity:

Не удалось найти метод newProduct(View) в классе активности com.test.masterflow1.MainActivity

Вам нужно будет удалить onClick свойство из XML и установить onClickListener программно либо в вашем фрагменте, либо в вашей деятельности.

Другие вопросы по тегам