アプリでビューページャーを作成し、その上でFragmentを拡張するクラスを使用しています。インスタンスを作成するとき、すべての要素(画像、テキストなど)を渡して、それをBundleに格納し、onCreateで使用できます。しかし、フラグメントのボタンのリスナーを格納できません。これが私のクラスです:
public class RegWizardFragmentInfo extends Fragment {
private static final String IMAGE = "image";
private static final String TEXT = "text";
private static final String BUTTON = "buttonText";
private View.OnClickListener buttonCallBack;
private Button button;
private int image;
private int text;
private int buttonText;
public RegWizardFragmentInfo newInstance(int image, int text, int buttonText, View.OnClickListener callback) {
RegWizardFragmentInfo fragment = new RegWizardFragmentInfo();
Bundle bundle = new Bundle();
bundle.putInt(IMAGE, image);
bundle.putInt(BUTTON, buttonText);
bundle.putInt(TEXT, text);
fragment.setArguments(bundle);
fragment.setRetainInstance(true);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.onActivityCreated(savedInstanceState);
this.image = getArguments().getInt(IMAGE);
this.text = (getArguments() != null) ? getArguments().getInt(TEXT)
: -1;
this.buttonText = (getArguments() != null) ? getArguments().getInt(BUTTON)
: -1;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.fragment, container, false);
//Extract all the views and add the image and texts
return rootView;
}
では、取得したリスナーをnewInstanceに保存して、onCreateViewメソッドのボタンに追加するにはどうすればよいでしょうか。
助けてくれてありがとう。
Fragment
でコールバックを使用できます:
public class RegWizardFragmentInfo extends Fragment {
private Button button;
private OnClickCallback callback;
public interface OnClickCallback {
void onClick();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
callback = (OnClickCallback) context;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
callback.onClick();
}
});
}
}
この新しいインターフェイスを親に実装しますActivity
他の答えは、リスナーをonAttach
に割り当てます。これは機能しますが、呼び出し側のActivity
(匿名クラスなどではなく)がインターフェースを実装する必要があります。さらに、Context
で指定されたonAttach
をインターフェイスのインスタンスにキャストする必要があります。これは、クラッシュを引き起こす可能性があり、一般に不正な形式と見なされます。代わりに、Fragment
内にリスナーを設定するメソッドを作成できます。
public class RegWizardFragmentInfo extends Fragment {
private OnClickListener mListener;
public interface OnClickListener {
void onClick();
}
/**
* Call at any time after this fragment has been constructed.
*/
public void setListener(OnClickListener listener) {
mListener = listener;
}
/* ...other stuff... */
}
このアプローチには3つの欠点があると思います。
Fragment
をインスタンス化するたびに、追加のメソッドを呼び出す必要があります。mListener
がいつでも設定されることを保証することはできません。 Fragment
コードにnullチェックを付ける必要がある場合があります。さまざまな異なるリスナーでFragment
を再利用したいと思います。したがって、Bundle
を使用できないため、アプローチは理想的ではありません。より良いアプローチは、コールバック設計パターンを使用することです。
_public class RegWizardFragmentInfo extends Fragment {
public interface RegWizardCallback {
void onClick();
}
}
_
あなたのActivity
はそのインターフェースを実装します。 Fragment
はアクティビティ内にのみ存在するため、ライフサイクルメソッドonAttach()
を使用して、アクティビティからコールバックインスタンスを取得できます。このようになります
_public class RegWizardFragmentInfo extends Fragment {
private RegWizardCallback callback;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
callback = (RegWizardCallback) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement RegWizardCallback ");
}
}
public interface RegWizardCallback {
void onClick();
}
}
_
これで、Buttonのリスナー内で_callback.onClick
_を呼び出すだけです。