Как указать, где искать метод OnClick, когда на фрагменте происходит событие onClick
Я создал проект в Android Studio с активностью по умолчанию в качестве активности в Навигаторе навигации
Затем созданы два новых фрагмента с именами Myfragment1 и Myfragment2.
Затем реализованы методы для вызова соответствующих фрагментов, в зависимости от того, какая опция выбрана из панели навигации. Я загружаю эти фрагменты с помощью метода инфляции LayoutInflater. Код для этого был помещен в метод onCreateView класса MainActivity.
Когда фрагмент Myfragment1 загружается, если я нажимаю кнопку добавления, которая находится на Myfragment1, тогда выдается ошибка "java.lang.IllegalStateException: Could not find a method".
Я создал слушатель для кнопки в onCreateView файла Myfragment1.java
Я указал, что он должен искать метод 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
программно либо в вашем фрагменте, либо в вашей деятельности.