蜂窝前(Android 3),每一个活动均已注册,以经过布局XML中的onClick
标记处理按钮单击: java
android:onClick="myClickMethod"
在该方法中,您可使用view.getId()
和switch语句来执行按钮逻辑。 android
随着Honeycomb的引入,我将这些活动分解为片断,能够在许多不一样的活动中重用这些片断。 按钮的大多数行为都是独立于活动的,我但愿代码驻留在Fragments文件中, 而无需使用为每一个按钮注册OnClickListener
的旧方法(1.6版以前)。 app
final Button button = (Button) findViewById(R.id.button_id); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // Perform action on click } });
问题是当个人布局膨胀时,仍然是托管活动正在接收按钮点击,而不是单个片断。 是否有一个好的方法 ide
在处理片断时,我宁愿使用代码中的单击处理,也不肯使用XML中的onClick
属性。 布局
将您的活动迁移到片断时,这变得更加容易。 您能够直接从每一个case
块调用click处理程序(之前在XML中设置为android:onClick
)。 this
findViewById(R.id.button_login).setOnClickListener(clickListener); ... OnClickListener clickListener = new OnClickListener() { @Override public void onClick(final View v) { switch(v.getId()) { case R.id.button_login: // Which is supposed to be called automatically in your // activity, which has now changed to a fragment. onLoginClick(v); break; case R.id.button_logout: ... } } }
在处理片断中的点击时,对我来讲,这比android:onClick
更简单。 spa
我更喜欢使用如下解决方案来处理onClick事件。 这也适用于活动和片断。 code
public class StartFragment extends Fragment implements OnClickListener{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_start, 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; } } }
这是另外一种方式: orm
1,建立一个BaseFragment像这样: 事件
public abstract class BaseFragment extends Fragment implements OnClickListener
2.使用
public class FragmentA extends BaseFragment
代替
public class FragmentA extends Fragment
3,活动中
public class MainActivity extends ActionBarActivity implements OnClickListener
和
BaseFragment fragment = new FragmentA; public void onClick(View v){ fragment.onClick(v); }
但愿能帮助到你。
除了Blundell的答案,
若是您有更多片断,而且拥有大量的onClicks:
活动:
Fragment someFragment1 = (Fragment)getFragmentManager().findFragmentByTag("someFragment1 "); Fragment someFragment2 = (Fragment)getFragmentManager().findFragmentByTag("someFragment2 "); Fragment someFragment3 = (Fragment)getFragmentManager().findFragmentByTag("someFragment3 "); ...onCreate etc instantiating your fragments public void myClickMethod(View v){ if (someFragment1.isVisible()) { someFragment1.myClickMethod(v); }else if(someFragment2.isVisible()){ someFragment2.myClickMethod(v); }else if(someFragment3.isVisible()){ someFragment3.myClickMethod(v); } }
在您的片断中:
public void myClickMethod(View v){ switch(v.getid()){ // Just like you were doing } }
Butterknife多是解决混乱问题的最佳解决方案。 它使用注释处理器生成所谓的“旧方法”样板代码。
可是onClick方法仍然能够与自定义充气机一块儿使用。
@Override public View onCreateView(LayoutInflater inflater, ViewGroup cnt, Bundle state) { inflater = FragmentInflatorFactory.inflatorFor(inflater, this); return inflater.inflate(R.layout.fragment_main, cnt, false); }
public class FragmentInflatorFactory implements LayoutInflater.Factory { private static final int[] sWantedAttrs = { android.R.attr.onClick }; private static final Method sOnCreateViewMethod; static { // We could duplicate its functionallity.. or just ignore its a protected method. try { Method method = LayoutInflater.class.getDeclaredMethod( "onCreateView", String.class, AttributeSet.class); method.setAccessible(true); sOnCreateViewMethod = method; } catch (NoSuchMethodException e) { // Public API: Should not happen. throw new RuntimeException(e); } } private final LayoutInflater mInflator; private final Object mFragment; public FragmentInflatorFactory(LayoutInflater delegate, Object fragment) { if (delegate == null || fragment == null) { throw new NullPointerException(); } mInflator = delegate; mFragment = fragment; } public static LayoutInflater inflatorFor(LayoutInflater original, Object fragment) { LayoutInflater inflator = original.cloneInContext(original.getContext()); FragmentInflatorFactory factory = new FragmentInflatorFactory(inflator, fragment); inflator.setFactory(factory); return inflator; } @Override public View onCreateView(String name, Context context, AttributeSet attrs) { if ("fragment".equals(name)) { // Let the Activity ("private factory") handle it return null; } View view = null; if (name.indexOf('.') == -1) { try { view = (View) sOnCreateViewMethod.invoke(mInflator, name, attrs); } catch (IllegalAccessException e) { throw new AssertionError(e); } catch (InvocationTargetException e) { if (e.getCause() instanceof ClassNotFoundException) { return null; } throw new RuntimeException(e); } } else { try { view = mInflator.createView(name, null, attrs); } catch (ClassNotFoundException e) { return null; } } TypedArray a = context.obtainStyledAttributes(attrs, sWantedAttrs); String methodName = a.getString(0); a.recycle(); if (methodName != null) { view.setOnClickListener(new FragmentClickListener(mFragment, methodName)); } return view; } private static class FragmentClickListener implements OnClickListener { private final Object mFragment; private final String mMethodName; private Method mMethod; public FragmentClickListener(Object fragment, String methodName) { mFragment = fragment; mMethodName = methodName; } @Override public void onClick(View v) { if (mMethod == null) { Class<?> clazz = mFragment.getClass(); try { mMethod = clazz.getMethod(mMethodName, View.class); } catch (NoSuchMethodException e) { throw new IllegalStateException( "Cannot find public method " + mMethodName + "(View) on " + clazz + " for onClick"); } } try { mMethod.invoke(mFragment, v); } catch (InvocationTargetException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new AssertionError(e); } } } }