我的代码的某些部分如何知道片段实例在屏幕上变得可见?
以下代码段将解释我的问题。
public class MyApp extends Application {
public static final String TAG = MyApp.class.getSimpleName();
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
...
@Override
public void onActivityResumed(Activity activity) {
Log.d(TAG, activity.getClass().getSimpleName() + " is on screen");
}
@Override
public void onActivityStopped(Activity activity) {
Log.d(TAG, activity.getClass().getSimpleName() + " is NOT on screen");
}
...
});
}
在这里,我可以跟踪我的应用中的任何活动何时出现在屏幕上。有没有办法在Fragments上扩展这种方法?
喜欢的东西
Activity.getFragmentManager().registerFragmentLifecycleCallbacks();
UPD。我对活动实现一无所知,他们是否使用片段以及如何使用它们(通过xml,ViewPager等注入)我班上唯一的东西是应用背景。我们假设Activity和Fragment实现是黑盒子,我无法进行任何更改。
答案 0 :(得分:5)
在您的片段中,覆盖onHiddenChanged(...)
方法:
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (hidden) {
Log.d(TAG, ((Object) this).getClass().getSimpleName() + " is NOT on screen");
}
else
{
Log.d(TAG, ((Object) this).getClass().getSimpleName() + " is on screen");
}
}
希望这对你有用!
答案 1 :(得分:5)
如果没有触及活动或片段代码,并且假设您不知道它所放置的标签或布局,那么您可以做的很少。我能看到的最好的是你可以在ActivityResumed和ActivityStopped回调中获取FragmentManager(因为这里有一个Activity引用)并应用BackstackChangedListener。这假设您在更改片段时使用了Backstack。
您要问的问题是,当您无法控制中间人,即已经缺乏Fragment回调的活动时,您希望在应用程序级别上对Fragments进行生命周期回调。它们通过FragmentManager完成大部分工作,并将自己的生命周期回调传播到Fragments,以便片段表现得恰当。片段中的onResume和onPause回调仅在首次创建时或者当Activity遇到这些回调时发生。 onAttachFragment中的Fragments只有一个生命周期回调函数,如果你可以覆盖它,它将为你提供对附加到Activity的Fragments的引用。但是你说你不能改变活动或片段,你想知道片段什么时候出现。
因此,如果您不使用背锯,我认为没有办法做您想做的事。
答案 2 :(得分:3)
要将片段放入Activity中,请使用Google使用的SlidingTabLayout
。在其中,您有ViewPager
和一些Adapter
来填充许多碎片。首先,您必须在项目中放置this和this个文件。然后here就如何实施SlidingTabLayout
提供了很好的教程。
1)在您的活动中实施SlidingTabLayout
后,您可以检测活动中何时以及哪些碎片可见:
mSlidingTabLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//Do nothing
}
@Override
public void onPageSelected(int position) {
if (position == 0) {
//Whenever first fragment is visible, do something
} else if (position == 1) {
//Whenever second fragment is visible, do something
} else if (position == 2) {
//Whenever third fragment is visible, do something
} else if (position == 3) {
//Whenever fourth fragment is visible, do something
}
}
@Override
public void onPageScrollStateChanged(int state) {
//Do nothing
}
});
2)当我回答here时,您可以检测片段是否在片段中可见,但是这可能会在onCreateView()
片段之前调用,因此请在链接:
@Override
public void setUserVisibleHint(boolean visible){
super.setUserVisibleHint(visible);
if (visible){
//when this Fragment is active, do something
}
}
3)您还可以在活动中更改每个标签的指标的颜色,如下所示:
mSlidingTabLayout.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
@Override
public int getIndicatorColor(int position) {
if (position == 0) {
return getResources().getColor(R.color.orange);
} else if (position == 1) {
return getResources().getColor(R.color.redDimmed);
} else if (position == 2) {
return getResources().getColor(R.color.yellow);
} else if (position == 3) {
return getResources().getColor(R.color.green);
} else {
return getResources().getColor(R.color.redLight);
}
}
@Override
public int getDividerColor(int position) {
return getResources().getColor(R.color.defaultActionBarBg);
}
});
答案 3 :(得分:1)
使用与活动相同的方式
在应用程序类中设置标志以检查片段的可见性,在片段
中使用下面的代码 @Override
public void onStart() {
super.onStart();
Log.e( "Fragment is visible", "Fragment is visible");
Application Class.isFragmentShow = true;
}
@Override
public void onPause() {
super.onPause();
Log.e("Fragment is not visible", "Fragment is not visible");
Application Class.isFragmentShow = false;
}
与片段进行通信,您必须调用添加了哪个片段的活动,然后使用下面的代码
MainFragment fragment = (MainFragment) fragmentManager.findFragmentByTag("MainFragment");
fragment.setFilter();
答案 4 :(得分:1)
不存在默认的方法,但你可以创建自己的Callbacks,我做了这个并且工作正常,首先需要一个BaseFragment类,我们将处理所有片段事件。
public class BaseFragment extends Fragment {
private String fragmentName;
private FragmentLifecycleCallbacks listener;
public void registerCallBacks(String fragmentName){
// handle the listener that implement 'MyApp' class
try{
listener = (FragmentLifecycleCallbacks) getActivity().getApplication();
} catch (ClassCastException e) {
throw new ClassCastException("Application class must implement FragmentLifecycleCallbacks");
}
// set the current fragment Name for the log
this.fragmentName = fragmentName;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if(listener!=null) {
listener.onAttachFragment(fragmentName);
}
}
@Override
public void onResume() {
super.onResume();
if(listener!=null) {
listener.onResumeFragment(fragmentName);
}
}
@Override
public void onStop() {
super.onStop();
if(listener!=null) {
listener.onStopFragment(fragmentName);
}
}
// 'MyApp' class needs implement this interface to handle all the fragments events
public interface FragmentLifecycleCallbacks{
void onStopFragment(String fragmentName);
void onResumeFragment(String fragmentName);
void onAttachFragment(String fragmentName);
}}
On' MyApp' class实现BaseFragment的接口
public class MyApp extends Application implements BaseFragment.FragmentLifecycleCallbacks{
public static final String TAG = MyApp.class.getSimpleName();
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onStopFragment(String fragmentName) {
Log.d(TAG, fragmentName + " is NOT on screen");
}
@Override
public void onResumeFragment(String fragmentName) {
Log.d(TAG, fragmentName + " is on screen");
}
@Override
public void onAttachFragment(String fragmentName) {
Log.d(TAG, fragmentName + " is attached to screen");
}}
现在你需要的每个片段都扩展了BaseFragment'并注册到全球监听者
public class FragmentA extends BaseFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_simple, container, false);
// here register to the global listener
registerCallBacks(FragmentA.class.getName());
return rootView;
}}
希望这有帮助!
答案 5 :(得分:0)
拦截活动中的onWindowFocusChanged()
并将其传播给感兴趣的片段。
答案 6 :(得分:0)
试试这个
private Boolean isFragmentVisible()
{
if(getFragmentManager().findFragmentByTag("TAG") != null && getFragmentManager().findFragmentByTag("TAG").isVisible())
{
//The fragment is visible
return true;
}
return false;
}
替代方式
private Boolean isFragmentVisible()
{
return getFragmentManager().findFragmentByTag("TAG") != null && getFragmentManager().findFragmentByTag("TAG").isVisible();
}
答案 7 :(得分:0)
您可以使用名为" onActivityCreated(Bundle)"的内置方法了解以下内容:此方法告诉已创建片段,因此您可以知道片段出现在屏幕上Click here for reference 希望它有所帮助
答案 8 :(得分:0)
我在不使用基础Fragment
或Activity
类的情况下查看了可用内容,但找不到任何内容。我已经实现了为应用程序中的所有片段提供基本(onAdded / onRemoved)功能的实现。当然可以扩展它以报告片段的当前状态(onAttach,onResume,onPause,onDetach,...)。
您可以在此处找到代码和示例:https://github.com/Nillerr/FragmentLifecycleCallbacks
它适用于非支持库片段和通过不同实现支持库片段。支持库类使用起来更安全,并且性能更好,因为不支持库使用Reflection来访问片段,而支持库FragmentManager
包含getFragments()
方法。
答案 9 :(得分:0)
如果要将Fragment设置为View,则可能有一个容器可以显示它。假设这个容器是一个ID为R.id.container的FrameLayout,你可以这样做:
Fragment f = fragmentManager.findFragmentById(R.id.container);
if (f instanceof YourFragment) {
// TODO something when YourFragment is ready
}
答案 10 :(得分:0)
此界面是否提供了对您有用的任何内容?
如果您无法覆盖Fragment自己的onResume()
方法,那么您最好的选择是创建自己的扩展ActivityLifecycleCallbacks的接口,然后将您的日志记录代码放入{{1方法。
您可以通过执行以下操作来获取指向Fragment的指针:
onFragmentResumed(Fragment yourFragment)
答案 11 :(得分:0)
如果您想检查片段是否可见,请检查isMenuVisible()
值。
这是片段的方法,当我必须从viewpager选择的项目中发出一些http请求时,我用它来检查可见片段。
希望这有帮助。
就我而言,我在onActivityCreated()中使用了这个方法。
答案 12 :(得分:0)
在片段覆盖方法中 setMenuVisibility 如果您正在使用ViewPager并从左右滑动,则在片段的可见性发生变化时会调用此方法。
以下是我项目中的示例
public abstract class DemosCommonFragment extends Fragment {
protected boolean isVisible;
public DemosCommonFragment() {
}
@Override
public void setMenuVisibility(boolean menuVisible) {
super.setMenuVisibility(menuVisible);
isVisible = menuVisible;
// !!! Do Something Here !!!
}
}
答案 13 :(得分:0)
动画监听器
我未检查所有用例,但存在未处理的异常。您可以使用它来适应您的用例。请随时评论您的意见或它没有解决的用例。
注意:您可以通过处理 enter
中的 onCreateAnimation
来添加 fragmentWillDisappear 和 fragmentDidDisappear。
父片段:
public class BaseFragment extends Fragment {
private Animation.AnimationListener animationListener;
private void setAnimationListener(Animation.AnimationListener animationListener) {
this.animationListener = animationListener;
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
fragmentWillAppear(animation);
}
@Override
public void onAnimationEnd(Animation animation) {
fragmentDidAppear(animation);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
AnimationSet animSet = new AnimationSet(true);
Animation anim = null;
try {
anim = AnimationUtils.loadAnimation(getActivity(), nextAnim);
} catch (Exception error) {
}
if (anim != null) {
anim.setAnimationListener(animationListener);
animSet.addAnimation(anim);
}
return animSet;
}
public void fragmentDidAppear(Animation animation) {
}
public void fragmentWillAppear(Animation animation) {
}
}
子片段:
class ChildFragment extends BaseFragment {
@Override
public void fragmentDidAppear(Animation animation) {
super.fragmentDidAppear(animation);
}
@Override
public void fragmentWillAppear(Animation animation) {
super.fragmentWillAppear(animation);
}
}