Fragmentのいくつかの穴
6117 ワード
インスタンスの作成
一般的にFragmentを作成するには、次のような方法があります.
OneFragment fragment = new OneFragment();
作成時にパラメータを渡す必要がある場合は
OneFragment fragment = new OneFragment(xxx);
これなら普通は大丈夫ですが、特殊な場合には問題が発生します.例えば
・
の場合、Activityは
・
Activity、Activityに依存するFragmentもついてくる
、Fragmentはデフォルトの
を呼び出すので、実行できなくなる
初期化作業を行います.解決策:
newInstance
の方法でFragmentインスタンスを作成し、作成時に
をBundle
の中に入れ、setArguments()
を入れてonCreate()
の中から取り出す.このように上記のような特殊な場合であっても、onCreate()
メソッドで
を取り出して初期化作業を行うことができる.public static OneFragment newInstance(int args){
OneFragment oneFragment = new OneFragment();
Bundle bundle = new Bundle();
bundle.putInt("someArgs", args);
oneFragment.setArguments(bundle);
return oneFragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = getArguments();
int args = bundle.getInt("someArgs");
}
つうしんモード
通常、3つの通信シーンがあります.
Fragment
なので、自然に持っているFragment
の
、あるいはfindFragmentById()
とfindFragmentByTag()
のいずれの方法でも入手できるFragment
の
なので、Fragment
まで操作できる.getActivity()
方法で入手可能 Activity
、さらに可能
宿主Activity
.getActivity()
方法でActivityが得られる以上、自然にできる
その他Fragment
の場合、
・
・のプログラミング思想に合致しない.Fragmentは自分のことをよくすればいい.Fragment間の制御表示などの操作は、Activityが統一的に管理しなければならない.解決方法:外部にインタフェースの形式を開放することによって、FragmentのActivityに対するいくつかの操作をActivityによって管理する.Fragment操作Activityに相当しますが、Fragmentは1つのインタフェースしか提供しておらず、ActivityがFragmentの操作が必要な方法を自覚的に入れるようにしています.
実装方法は次のとおりです.
public class OneFragment extends Fragment implements View.OnClickListener{
public interface IOneFragmentClickListener{
void onOneFragmentClick();
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View contentView = inflater.inflate(R.layout.fragment_one, null);
contentView.findViewById(R.id.edt_one).setOnClickListener(this);
return contentView;
}
@Override
public void onClick(View v) {
if (getActivity() instanceof IOneFragmentClickListener){
((IOneFragmentClickListener) getActivity()).onOneFragmentClick();
}
}
}
Fragmentが定義した対外インタフェースIOneFragmentClickListenerをホストActivityで実現すれば、FragmentがActivityを呼び出す機能を実現できる.
次のようにすることもできます.
public class OneFragment extends Fragment implements View.OnClickListener{
private IOneFragmentClickListener clickListener;
public interface IOneFragmentClickListener{
void onOneFragmentClick();
}
public void setClickListener(IOneFragmentClickListener clickListener) {
this.clickListener = clickListener;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View contentView = inflater.inflate(R.layout.fragment_one, null);
contentView.findViewById(R.id.edt_one).setOnClickListener(this);
return contentView;
}
@Override
public void onClick(View v) {
clickListener.onOneFragmentClick();
}
}
原理は同じですが、最初の方法と比較して、ホストActivityにリスニング設定を追加する必要があります.
oneFragment.setClickListener(this);
Fragment重複問題
理由:
Activity
のonCreate()
またはFragment
のonCreateView()
にFragmentをロードし、もし
の場合(例えば画面の回転、メモリの回収、フォントの交換などの場合に強殺されて再起動)に遭遇した場合は、システムの
により自動的に手伝ってくれる Fragment
、その後再起動してくれる
、しかし、私たちのonCreate()またはonCreateView()メソッド内でまた add
になったので
.mHidden
パラメータは保存に使用するFragment
(mHidden=tureは非表示、mHidden=falseは表示)例えば2つのFragmentがあり、1つがture状態、1つがfalse状態である場合、インタフェースが再起動する場合、システムは
手伝ってあげる
この場合mHidden状態 Fragment
すべてのFragmentデフォルトmHiddenはfalse(すなわち
)なので
となります.ケース2はv 4-24.00+で始まり、上記mHiddenが保存されていない問題を公式に修復したので、24.00+のv 4パッケージを使用している場合は、ケース2の問題を考慮しないことができます.でも!もしあなたがV 4パックのFragmentではなくandroidを使っていたら.app.FragmentパッケージのFragmentでは、問題は依然として存在します!
解決策:
// ,
if (savedInstanceState == null){
//
}
public class BaseFragment extends Fragment {
private static final String STATE_SAVE_IS_HIDDEN = "STATE_SAVE_IS_HIDDEN";
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
...
if (savedInstanceState != null) {
boolean isSupportHidden = savedInstanceState.getBoolean(STATE_SAVE_IS_HIDDEN);
FragmentTransaction ft = getFragmentManager().beginTransaction();
if (isSupportHidden) {
ft.hide(this);
} else {
ft.show(this);
}
ft.commit();
}
@Override
public void onSaveInstanceState(Bundle outState) {
...
outState.putBoolean(STATE_SAVE_IS_HIDDEN, isHidden());
}
}
remove()メソッドはスタックから出られません
まだピットを踏む必要があります...
getActivity()空のポインタ
まだピットを踏む必要があります...
複数のFragmentが同時にスタックを出る深いピットBUG
まだピットを踏む必要があります...
深坑Fragmentターンフィールドアニメーション(v 4パッケージのFragmentのみを解析)
まだピットを踏む必要があります...
参考Fragment全解析シリーズ(一):年に踏んだ穴