我使用FragmentPagerAdapter从片段切换。我需要在制作片段开关时调用一些函数,并且在OnPause和OnResume上遇到一些麻烦,所以THIS问题我已经实现了一个接口OnPageSelectListener:
public interface OnPageSelectListener {
void onPageSelected();
void onPageNotVisible();
}
只要此页面到达前台,它就会调用OnPageSelected函数。工作得很好,除了我想在我的适配器上调用一个函数。我认为这样可行,除了我的适配器一直返回NULL(即使它被初始化并且数据在我的列表视图中被加载为首选)。
public class AfterCheckFragment extends Fragment implements OnPageSelectListener{
private ListView listView;
private List<Check> checkList;
private CheckListAdapter adapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_check, container, false);
System.out.println("VIEW create called");
//(.. some other stuff, not relevant for question..)
//initializing the adapter
listView = (ListView) view.findViewById(R.id.listView);
adapter = new CheckListAdapter(checkList,getActivity(),trainPosition);
listView.setAdapter(adapter);
adapter.handleButtonVisibility();
return view;
}
@Override
public void onPageSelected() {
if(this.adapter != null) {
System.out.println("adapter not null");
this.adapter.checkForActive();
}else{
System.out.println("Adapter is NULL");
}
}
@Override
public void onPageNotVisible() { //page is moved to backgroung
System.out.println("AFTER not active any more ");
}
}
现在是我的问题:为什么适配器(或片段中的任何其他对象)在返回我的片段时会返回null?当fragmentPager初始化时,片段的onActivityCreate函数被调用一次,但之后不再调用,并且适配器返回null ....
答案 0 :(得分:3)
你必须在初始化适配器和setAdapter()之后调用onPageSelected()否则适配器将始终返回null
答案 1 :(得分:2)
ViewPager
将创建和销毁片段(请参阅ViewPager.setOffscreenPageLimit()
)。所以onActivityCreated()
仅在片段第一次被恢复或设置时被调用。因此,可以创建片段而无需调用onActivityCreated()
。
我会建议覆盖onActivityCreated()
并在那里设置适配器,而不是onViewCreated()
。没有创建视图就不能显示片段,所以这是一个做这种事情的好地方。
如果您的OnPageSelectListener
逻辑有效,那就太好了。我发现知道片段实际位于用户面前的最佳方式是覆盖setPrimaryItem()
中的FragmentPagerAdapter
。将页面移出视图事件有点棘手,因为您必须保留对先前setPrimaryItem()
调用中的片段的引用。
答案 2 :(得分:2)
以下为什么我认为您的@echo off
setlocal & pushd .
call :FindNeedle "%~1" bar
:: My real script shuttles a few variables out of the local scope
popd & endlocal & goto :EOF
:: Subroutine
:FindNeedle
setlocal ENABLEEXTENSIONS
:: Category
set REQ=%~1
:: Subcategory
set NEEDLE=%~2
:: This call will either end up setting the HAYSTACK variable
:: (see below) or not doing anything at all. It also suppresses
:: error output if the call "fails"
call :CHECK_%REQ% > NUL 2>&1
:: Jump over the "subroutines" used to set HAYSTACK
goto :END_CHECK
:CHECK_FOO
set HAYSTACK=foo
goto :EOF
:CHECK_BAR
set HAYSTACK=foo bar
goto :EOF
:CHECK_BAZ
set HAYSTACK=foo bar baz
goto :EOF
:END_CHECK
:: FOUND should hold the name of the NEEDLE if found or be empty
set FOUND=
:: This checks that we have a HAYSTACK to look in. It then shows
:: what the HAYSTACK looks like and iterates over its elements.
:: Echoing each element it then checks if an element matches the
:: NEEDLE we're looking for and calls :SetVar to avoid delayed
:: expansion woes and set FOUND
if not "%HAYSTACK%" == "" @(
echo HAYSTACK ^= %HAYSTACK%
for %%i in (%HAYSTACK%) do @(
echo %%i
if "%NEEDLE%" == "%%i" echo Matched %%i&call :SetVar FOUND %%i
)
) else @(
echo ERROR: Empty haystack
endlocal & goto :EOF
)
if "%FOUND%" == "" @( echo ERROR: %NEEDLE% is not supported by %REQ%&endlocal&goto :EOF )
echo Found: %FOUND%
:: This subroutine also normally would shuttle out variables
endlocal & goto :EOF
:: This subroutine is a trick to set a variable inside of a
:: for loop without using delayed expansion
:SetVar
set %~1=%~2&goto :EOF
(我称之为CheckListAdapter
)为空:
listAdapter
提供给pagerAdapter
ViewPager
要求ViewPager
提供新的pagerAdapter
Fragment
告诉ViewPager
使用它FragmentManager
被称为onPageSelected
。目前还没有初始化。 (NPE)listAdapter
将片段拖入其所有阶段。FragmentManager
被召唤。您的onCreateView
已创建。不要尝试使用其外部片段的内部数据。它意味着作为一个独立的单元工作,如果你以不同的方式使用它,它将不会很好。由于片段是在稍后阶段初始化的,因此您无法像预期的那样使用它
您可以尝试在片段中执行您想要执行的操作,而不是listAdapter
,或者在托管pagerAdapter
中编写方法,并在准备好时从片段中调用它,甚至可以启动事件。
答案 3 :(得分:1)
这是因为Viewpager在调用oncreateView()/ onActivityCreated()中的片段之前调用OnpageSelected方式。
最好的方法是在Fragment的构造函数中膨胀您的视图并设置适配器。
或
使用成员变量存储片段是否处于活动状态。并使用oncreateview()中的变量来调用适配器上的函数。
答案 4 :(得分:1)
为什么不在你的寻呼机中使用viewpager.addOnPageChangeListener
后,在你的片段上设置了适配器和setOffscreenPageLimit()
而不是implements
?
下面是示例代码:
viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if(position == 1){ // if you want the second page, for example
//Your code here
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
当您在设置Activity
的{{1}}内进行操作。
答案 5 :(得分:0)
对我来说,我不得不在我的viewpager上打电话:
myViewPager.setSaveFromParentEnabled(false);