Android Fragment onClickbutton方法

我试图在我的onClick(View v)XML中调用该方法,但不能与Fragment一起使用。 这是错误。

01-17 12:38:36.840: E/AndroidRuntime(4171): java.lang.IllegalStateException: Could not find a method insertIntoDb(View) in the activity class main.MainActivity for onClick handler on view class android.widget.Button with id 'btn_conferma' 

MainActivity.java

 public void insertIntoDb(View v) { ... } 

xml代码

  <Button android:id="@id/btn_conferma" style="?android:attr/borderlessButtonStyle" android:layout_width="0.0dip" android:layout_height="45dp" android:layout_marginLeft="2dp" android:layout_weight="1.0" android:background="@drawable/bottoni" android:gravity="center_horizontal|center_vertical" android:onClick="insertIntoDb" android:text="SALVA" android:textColor="#ffffff" android:textSize="16sp" /> 

你的活动必须有

 public void insertIntoDb(View v) { ... } 

不是片段。

如果你不想在上面的活动。 初始化片段中的button并将侦听器设置为相同。

 <Button android:id="@+id/btn_conferma" // + missing 

然后

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_rssitem_detail, container, false); Button button = (Button) view.findViewById(R.id.btn_conferma); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // do something } }); return view; } 

另一个select可能是让您的片段实现View.OnClickListener并覆盖片段中的onClick(View v)。 如果你需要让你的片段与活动交谈,只需添加一个接口和所需的方法,并让活动实现接口并覆盖它的方法。

 public class FragName extends Fragment implements View.OnClickListener { public FragmentCommunicator fComm; public ImageButton res1, res2; int c; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_test, container, false); } @Override public void onAttach(Activity activity) { super.onAttach(activity); try { fComm = (FragmentCommunicator) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement FragmentCommunicator"); } } @Override public void onActivityCreated(Bundle savedInstanceState) { res1 = (ImageButton) getActivity().findViewById(R.id.responseButton1); res1.setOnClickListener(this); res2 = (ImageButton) getActivity().findViewById(R.id.responseButton2); res2.setOnClickListener(this); } public void onClick(final View v) { //check for what button is pressed switch (v.getId()) { case R.id.responseButton1: c *= fComm.fragmentContactActivity(2); break; case R.id.responseButton2: c *= fComm.fragmentContactActivity(4); break; default: c *= fComm.fragmentContactActivity(100); break; } public interface FragmentCommunicator{ public int fragmentContactActivity(int b); } public class MainActivity extends FragmentActivity implements FragName.FragmentCommunicator{ int a = 10; //variable a is update by fragment. ex. use to change textview or whatever else you'd like. public int fragmentContactActivity(int b) { //update info on activity here a += b; return a; } } 

http://developer.android.com/training/basics/firstapp/starting-activity.html http://developer.android.com/training/basics/fragments/communicating.html

这不是一个问题,这是一个Android的devise。 看到这里 :

您应该将每个片段devise为一个模块化且可重用的活动组件。 也就是说,由于每个片段都使用自己的生命周期callback来定义自己的布局和自己的行为,因此您可以在多个活动中包含一个片段,因此您应该devise重用并避免直接操作其他片段中的一个片段。

一个可能的解决方法是在你的MainActivity中做这样的事情:

 Fragment someFragment; ...onCreate etc instantiating your fragments public void myClickMethod(View v){ someFragment.myClickMethod(v); } 

然后在你的Fragment类中:

 public void myClickMethod(View v){ switch(v.getid()){ // Your code here } } 

其他人已经说过,onClick中的方法在活动中search,而不是在片段中search。 不过,如果你真的想要的话,这可能的。

基本上,每个视图都有一个标签(可能为null)。 我们将根视图的标记设置为使该视图膨胀的片段。 然后,很容易search视图父母,并检索包含点击button的片段。 现在,我们find方法名称并使用reflection来从检索的片段中调用相同的方法。 简单!

在一个扩展Fragment的类中:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_id, container, false); OnClickFragments.registerTagFragment(rootView, this); // <========== !!!!! return rootView; } public void onButtonSomething(View v) { Log.d("~~~","~~~ MyFragment.onButtonSomething"); // whatever } 

所有的活动都来自相同的ButtonHandlingActivity:

 public class PageListActivity extends ButtonHandlingActivity 

ButtonHandlingActivity.java:

 public class ButtonHandlingActivity extends Activity { public void onButtonSomething(View v) { OnClickFragments.invokeFragmentButtonHandlerNoExc(v); //or, if you want to handle exceptions: // try { // OnClickFragments.invokeFragmentButtonHandler(v); // } catch ... } } 

它必须为所有xml onClick处理程序定义方法。

COM /示例/ customandroid / OnClickFragments.java:

 package com.example.customandroid; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import android.app.Fragment; import android.view.View; public abstract class OnClickFragments { public static class FragmentHolder { Fragment fragment; public FragmentHolder(Fragment fragment) { this.fragment = fragment; } } public static Fragment getTagFragment(View view) { for (View v = view; v != null; v = (v.getParent() instanceof View) ? (View)v.getParent() : null) { Object tag = v.getTag(); if (tag != null && tag instanceof FragmentHolder) { return ((FragmentHolder)tag).fragment; } } return null; } public static String getCallingMethodName(int callsAbove) { Exception e = new Exception(); e.fillInStackTrace(); String methodName = e.getStackTrace()[callsAbove+1].getMethodName(); return methodName; } public static void invokeFragmentButtonHandler(View v, int callsAbove) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException { String methodName = getCallingMethodName(callsAbove+1); Fragment f = OnClickFragments.getTagFragment(v); Method m = f.getClass().getMethod(methodName, new Class[] { View.class }); m.invoke(f, v); } public static void invokeFragmentButtonHandler(View v) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException { invokeFragmentButtonHandler(v,1); } public static void invokeFragmentButtonHandlerNoExc(View v) { try { invokeFragmentButtonHandler(v,1); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } public static void registerTagFragment(View rootView, Fragment fragment) { rootView.setTag(new FragmentHolder(fragment)); } } 

而下一个冒险将是proguard混淆…

PS

当然,devise应用程序的目的在于让数据能够存储在模型中,而不是存储在Activities或Fragments(从MVCModel-View-Controller的angular度来看是控制器 )中。 视图是你通过xml定义的,加上自定义视图类(如果你定义它们,大多数人只是重用已经存在的东西)。 经验法则:如果某些数据肯定要经过屏幕回放,那么它们就属于Model

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.writeqrcode_main, container, false); // Inflate the layout for this fragment txt_name = (TextView) view.findViewById(R.id.name); txt_usranme = (TextView) view.findViewById(R.id.surname); txt_number = (TextView) view.findViewById(R.id.number); txt_province = (TextView) view.findViewById(R.id.province); txt_write = (EditText) view.findViewById(R.id.editText_write); txt_show1 = (Button) view.findViewById(R.id.buttonShow1); txt_show1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.e("Onclick","Onclick"); txt_show1.setVisibility(View.INVISIBLE); txt_name.setVisibility(View.VISIBLE); txt_usranme.setVisibility(View.VISIBLE); txt_number.setVisibility(View.VISIBLE); txt_province.setVisibility(View.VISIBLE); } }); return view; } 

你还好吗 !!!!

 button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // do something } }); 

对我来说是真的