私は次の方法を使用して、フラグメントを表示/非表示することで(NavigationDrawerで)フラグメントを切り替えます。
protected void showFragment(int container, Fragment fragment, String tag, String lastTag, boolean addToBackStack ) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
if ( lastTag != null && !lastTag.equals("")) {
Fragment lastFragment = fragmentManager.findFragmentByTag( lastTag );
if ( lastFragment != null ) {
transaction.hide( lastFragment );
}
}
if ( fragment.isAdded() ) {
transaction.show( fragment );
}
else {
transaction.add( container, fragment, tag );
}
if ( addToBackStack ) {
transaction.addToBackStack( tag );
}
transaction.commit();
// set the active tag
activeFragTag = tag;
}
私が不明なのは、フラグメントのライフサイクルのどのメソッドを表示または非表示にするときに呼び出されるか?(onShow()またはonHide()などのメソッドがないため、何を使用すべきかよくわからない)。特定のフラグメントを表示および非表示にして特定のアクションを実行したい。
アクティビティのライフサイクルと同様に、フラグメントが表示されると、Androidが onStart() を呼び出します。 onStop()
は通常、フラグメントが非表示になると呼び出されますが、後で呼び出すこともできます。
レイアウトに応じて、フラグメントがまだ表示されていないが、表示されている親コンテナに属している場合でも、AndroidはonStart()
を呼び出すことができます。たとえば、これはAndroid.support.v4.view.ViewPager
に対して有効です。この場合、 Fragment.setUserVisibleHint()
メソッドをオーバーライドする必要があります。いずれにせよ、BroadcastReceiversまたは他のリスナーを登録/登録解除する必要がある場合、onStart()
およびonStop()
メソッドは常に呼び出されるため、安全に使用できます。
注:一部のフラグメントコンテナは、非表示のフラグメントを開始したままにすることができます。この状況を処理するには、 Fragment.onHiddenChanged(boolean hidden)
をオーバーライドできます。 ドキュメント によると、フラグメントが開始および可視(非表示ではない)の両方である必要があります。
更新:Android.support.v4.widget.DrawerLayout
を使用すると、引き出しの下にあるフラグメントは、引き出しが開いていても開始され、表示されたままになります。この場合、DrawerLayout.setDrawerListener()
を使用し、onDrawerClosed()
およびonDrawerOpened()
コールバックをリッスンする必要があります。
私はこのメソッドを@オーバーライドして問題を解決します:
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (hidden) {
//do when hidden
} else {
//do when show
}
}
オフコースで次の方法で@Overriedeを実行できます:
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// Do your Work
} else {
// Do your Work
}
}
ビューページャーの動作におけるフラグメントは、通常のフラグメントコンテナとは異なります。
このコードを試してください:
boolean mIsVisibleToUser;
/**
* is visible to user
*/
public void show() {
//do when show
}
/**
* is invisible to user
*/
public void hide() {
//do when gone
}
@Override
public void onResume() {
super.onResume();
if (!mIsVisibleToUser && getUserVisibleHint()) {
mIsVisibleToUser = true;
show();
}
}
@Override
public void onPause() {
super.onPause();
if (mIsVisibleToUser && getUserVisibleHint()) {
mIsVisibleToUser = false;
hide();
}
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isResumed()) {
if (mIsVisibleToUser != isVisibleToUser) {
mIsVisibleToUser = isVisibleToUser;
if (isVisibleToUser) show();
else hide();
}
}
}
public boolean isVisibleToUser() {
return mIsVisibleToUser;
}
このコードを試してください:
@Override
public void setUserVisibleHint(boolean visible)
{
super.setUserVisibleHint(visible);
if (visible && isResumed())
{
onResume();
}
}
@Override
public void onResume()
{
super.onResume();
if (!getUserVisibleHint())
{
return;
}
//Add your code this section
}
setUserVisibleHint()でこれを試してください
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser && getView() != null){
isActive = true;
init();
}else if(isVisibleToUser && getView() == null){
isActive = false;
}else{
isActive = true;
}
}
そして、このコードをonCreateView()で作成します。
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if(!isActive){
init();
}
}
「onCreateView」(または「onActivityCreated」)および「onHiddenChanged」を使用できます。最初のショーには「onCreateView」を使用し、後のショーには「onHiddenChanged」を使用します。 「setMenuVisibility」はトランザクション制御で呼び出されません。
@Override
public View OnCreateView() {
// fragment will show first
}
@Override
public void onHiddenChanged(boolean hidden) {
if (!hidden) {
// fragment will show
}
else {
// fragment will hide
}
}
フラグメントが表示されていて、アクティビティでビューページャーを使用しているときにフラグメントメソッドを呼び出す別の方法。
//まず、インターフェイスを作成します
public interface ShowFragmentVisible{
public void showFragment();}
//その後、このインターフェースはそのようなフラグメント内に実装します
public class MyFragment extends Fragment implements
ShowFragmentVisible {
@Override
public void showFragment() {
}
//アクティビティに進み、インターフェイスのオブジェクトを作成し、addOnViewpagerListenerのときに内部を呼び出します
ShowFragmentVisible showFragmentVisible;
@Override
public void onAttachFragment(Fragment fragment) {
super.onAttachFragment(fragment);
if (fragment instanceof ShowFragmentVisible) {
showFragmentVisible = (ShowFragmentVisible) fragment;
}
}
//your viewpager method
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if (position==0){
showFragmentVisible.showFragment();
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
this is another alternative,but its work for me successfully
setUserVisibleHint
の前にonCreateView
を呼び出します。私が使用するsetUserVisibleHint内のビューを更新することはできません
public void setMenuVisibility(final boolean visible)
forvisibility and onHiddenChanged()は初めて呼び出しませんでした。非表示の状態が変化すると呼び出されます。 fragment is visible by default
であるため。このメソッドを初めて実現するには、mFragmentTransaction.hide(oldFragment)
を呼び出す必要があります。
注
setUserVisibleヒントを使用してビューを更新する場合 このメソッドを使用する
もちろんsetUserVisibleHint
またはsetMenuVisibility
をオーバーライドできますが、Context
またはActivity
にアクセスする必要がある場合、それらはnullになります!常に手元にコンテキストが存在する別のメソッドonStart
がありますが、フラグメントの作成時に一度だけ呼び出され、ページャーでフラグメント間を移動し始めると、呼び出されないことがわかります2番目のビュー以降。
だから...今何をすべきか?
回避策は非常に簡単です。最初の訪問にはonStart
を使用し、後の訪問にはsetMenuVisibility
を使用します。コードはおそらく次のようになります。
フラグメントクラス:
public class MyFragmentClass{
private boolean isCurrentVisible = false;
...
@Override
public void onStart() {
super.onStart();
if (isCurrentVisible)
doSth();
}
@Override
public void setMenuVisibility(boolean menuVisible){
super.setMenuVisibility(menuVisible);
this.isCurrentVisible = menuVisible;
if(menuVisible && getContext() != null)
doSth();
}
これにより、Context
は常にdoSth()
メソッドで利用可能になります。