主要目标是主要从自己的班级更新片段信息。
主要活动:
public class MainActivity extends AppCompatActivity {
final Handler GUIHandler = new Handler();
final Runnable r = new Runnable()
{
public void run()
{
updateFragments();
GUIHandler.postDelayed(this, 1000);
}
};
@Override
protected void onPause() {
super.onPause();
GUIHandler.removeCallbacks(r);
}
@Override
protected void onResume() {
super.onResume();
GUIHandler.postDelayed(r, 600);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
...
mViewPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new PagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
mViewPager.setAdapter(mPagerAdapter);
...
}
private void updateFragments() {
mPagerAdapter.updateFragments();
}
PagerAdapter:
public class PagerAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;
private Observable mObservers = new FragmentObserver();
public PagerAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
@Override
public Fragment getItem(int position) {
mObservers.deleteObservers(); // Clear existing observers.
switch (position) {
case 0:
FragmentWeather weatherTab = new FragmentWeather();
weatherTab.setActivity(mActivity);
if(weatherTab instanceof Observer)
mObservers.addObserver((Observer) weatherTab);
return weatherTab;
case 1:
FragmentMemo tab2 = new FragmentMemo();
return tab2;
case 2:
FragmentHardware tab3 = new FragmentHardware();
return tab3;
default:
return null;
}
}
public void updateFragments() {
mObservers.notifyObservers();
}
}
FragmentObserver
public class FragmentObserver extends Observable {
@Override
public void notifyObservers() {
setChanged(); // Set the changed flag to true, otherwise observers won't be notified.
super.notifyObservers();
Log.d("Observer", "Sending notification");
}
}
FragmentWeather:
public class FragmentWeather extends Fragment implements Observer {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
return layout;
}
public void setTemperatures(){
Log.d("Android", "setTemperatures is called");
}
@Override
public void update(Observable observable, Object data) {
setTemperatures();
}
}
现在的问题是,在应用程序启动时创建Fragments时,PagerAdapter::getItem()
不会被调用。这意味着WeatherFragment
与mObservers
无关。如果我滑动到第三个视图然后向后滑动,一切正常。如何对其进行重组以使其正常工作?
答案 0 :(得分:2)
这一行:
mObservers.deleteObservers(); // Clear existing observers.
正在移除所有观察者,但是方法getItem
被多次调用,这意味着只有最后一次调用任何观察者停留在那里。 删除此行。
此外,以下代码是一个非常糟糕的模式,它会在几种情况下出错:
case 0:
FragmentWeather weatherTab = new FragmentWeather();
weatherTab.setActivity(mActivity);
if(weatherTab instanceof Observer)
mObservers.addObserver((Observer) weatherTab);
return weatherTab;
这是因为片段在必要时由系统重新创建,因此setActivity
毫无意义,因此addObserver
也是如此。在系统需要销毁/重新创建碎片的那一刻,你将会发现旧碎片的内存泄漏,旧活动以及新活动未获得活动并且无法启用观察员。
这里最好的情况是依赖碎片的自然回调。下面是一个例子(ps:用心脏打字,我确定可能会有一些错误,但你会得到这个想法)
public interface ObservableGetter{
public Observable getObservable();
}
public void MyFragment extends Fragment implements Observer {
@Override onAttach(Activity activity){
super.onAtttach(activity);
if(activity instanceof ObservableGetter){
((ObservableGetter)activity).getObservable().
addObserver(this);
}
}
@Overrude onDetach(){
Activity activity = getActivity();
if(activity instanceof ObservableGetter){
((ObservableGetter)activity).getObservable().
removeObserver(this);
}
super.onDetach();
}
}
然后你可以让活动实现ObservableGetter并在其上设置Observable。
然后您的adapter
代码就是:
case 0:
return new FragmentWeather();
所有其余逻辑都使用常规回调。
我希望它有所帮助。