- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我的应用程序由几个 fragment 组成。到目前为止,我已经将对它们的引用存储在自定义 Application 对象中,但我开始认为我做错了什么。
当我意识到我的 fragment 对 mActivity 的所有引用在方向更改后都变为空时,我的问题就开始了。因此,当我在方向更改后调用 getActivity() 时,会抛出 NullPointerException。在调用 getActivity() 之前,我已经检查过我的 fragment 的 onAttach() 是否被调用,但它仍然返回 null。
以下是我的 MainActivity 的精简版,它是我的应用程序中唯一的 Activity 。
public class MainActivity extends BaseActivity implements OnItemClickListener,
OnBackStackChangedListener, OnSlidingMenuActionListener {
private ListView mSlidingMenuListView;
private SlidingMenu mSlidingMenu;
private boolean mMenuFragmentVisible;
private boolean mContentFragmentVisible;
private boolean mQuickAccessFragmentVisible;
private FragmentManager mManager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*
* Boolean variables indicating which of the 3 fragment slots are visible at a given time
*/
mMenuFragmentVisible = findViewById(R.id.menuFragment) != null;
mContentFragmentVisible = findViewById(R.id.contentFragment) != null;
mQuickAccessFragmentVisible = findViewById(R.id.quickAccessFragment) != null;
if(!savedInstanceState != null) {
if(!mMenuFragmentVisible && mContentFragmentVisible) {
setupSlidingMenu(true);
} else if(mMenuFragmentVisible && mContentFragmentVisible) {
setupSlidingMenu(false);
}
return;
}
mManager = getSupportFragmentManager();
mManager.addOnBackStackChangedListener(this);
final FragmentTransaction ft = mManager.beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
if (!mMenuFragmentVisible && mContentFragmentVisible) {
/*
* Only the content fragment is visible, will enable sliding menu
*/
setupSlidingMenu(true);
onToggle();
ft.replace(R.id.contentFragment, getCustomApplication().getSportsFragment(), SportsFragment.TAG);
} else if (mMenuFragmentVisible && mContentFragmentVisible) {
setupSlidingMenu(false);
/*
* Both menu and content fragments are visible
*/
ft.replace(R.id.menuFragment, getCustomApplication().getMenuFragment(), MenuFragment.TAG);
ft.replace(R.id.contentFragment, getCustomApplication().getSportsFragment(), SportsFragment.TAG);
}
if (mQuickAccessFragmentVisible) {
/*
* The quick access fragment is visible
*/
ft.replace(R.id.quickAccessFragment, getCustomApplication().getQuickAccessFragment());
}
ft.commit();
}
private void setupSlidingMenu(boolean enable) {
/*
* if enable is true, enable sliding menu, if false
* disable it
*/
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// launch the fragment that was clicked from the menu
}
@Override
public void onBackPressed() {
// Will let the user press the back button when
// the sliding menu is open to display the content.
if (mSlidingMenu != null && mSlidingMenu.isMenuShowing()) {
onShowContent();
} else {
super.onBackPressed();
}
}
@Override
public void onBackStackChanged() {
/*
* Change selected position when the back stack changes
*/
if(mSlidingMenuListView != null) {
mSlidingMenuListView.setItemChecked(getCustomApplication().getSelectedPosition(), true);
}
}
@Override
public void onToggle() {
if (mSlidingMenu != null) {
mSlidingMenu.toggle();
}
}
@Override
public void onShowContent() {
if (mSlidingMenu != null) {
mSlidingMenu.showContent();
}
}
}
以下是 CustomApplication 的精简版本。我对这一实现的想法是保证在我的应用程序的整个生命周期中每个 fragment 只有一个实例。
public class CustomApplication extends Application {
private Fragment mSsportsFragment;
private Fragment mCarsFragment;
private Fragment mMusicFragment;
private Fragment mMoviesFragment;
public Fragment getSportsFragment() {
if(mSsportsFragment == null) {
mSsportsFragment = new SportsFragment();
}
return mSsportsFragment;
}
public Fragment getCarsFragment() {
if(mCarsFragment == null) {
mCarsFragment = new CarsFragment();
}
return mCarsFragment;
}
public Fragment getMusicFragment() {
if(mMusicFragment == null) {
mMusicFragment = new MusicFragment();
}
return mMusicFragment;
}
public Fragment getMoviesFragment() {
if(mMoviesFragment == null) {
mMoviesFragment = new MoviesFragment();
}
return mMoviesFragment;
}
}
我对有关如何最好地实现多个 fragment 以及如何维护它们的状态的技巧非常感兴趣。供您引用,到目前为止,我的应用程序包含 15 个以上的 fragment 。我做了一些研究,似乎 FragmentManager.findFragmentByTag() 是一个不错的选择,但我未能成功实现它。
除了 mActivity 引用在方向更改后变为 null 之外,我的实现似乎运行良好,这让我相信我也可能有一些内存泄漏问题。
如果您需要查看更多代码,请告诉我。我有意避免包含 fragment 代码,因为我坚信问题与我的 Activity 和 Application 实现有关,但我可能错了。
感谢您的宝贵时间。
最佳答案
My thoughts behind this implementation was to guarantee only one instance of each fragment throughout my application's life cycle
这可能是您遇到困难的部分原因,如果不是全部的话。
在配置更改时,Android 将重新创建您的 fragment ,方法是使用公共(public)零参数构造函数创建一个新实例。因此,您的全局范围 fragment 不会“保证每个 fragment 只有一个实例”。
请删除此自定义 Application
类。请允许 fragment 自然地重新创建,或者如果它们需要为单个 Activity 的生命而活,请使用 setRetainInstance(true)
。不要尝试跨 Activity 重用 fragment 。
关于android - 方向更改后, fragment 对 mActivity 的引用变为空。无效的 fragment 状态维护,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15744445/
我正在与 svgpath 合作为了操作 svgs,我需要更改坐标系,使 y 变为 x,x 变为 y。我的问题是有什么办法可以做到这一点。我尝试围绕点 0 0 旋转并按图形的高度进行平移。 最佳答案 作
我有一个来源 Observable那: 注册一些 BroadcastReceivers当它订阅时 取消订阅时取消注册。 我只希望在订阅者数量从 0 增加到 1,或从 1 增加到 0 时发生订阅副作用。
def string_transf(): input('Enter a word or string') #letters = 'abcdefghijklmnopqrstvwxyz'
这个问题在这里已经有了答案: 关闭 12 年前。 Possible Duplicate: Format Number like StackoverFlow (rounded to thousands
我是 R 的初学者,有一个任务,我必须创建一个函数,其中所有数字都重新缩放,Inf 映射到 1,-Inf 映射到 0。我了解如何进行重新缩放,我只是不知道如何添加到函数中,所以 Inf 变为 1,-I
我有一个由二进制值组成的单字节字符数组,我试图将它拆分成一个二维 int 数组(低 nybble 和高 nybble)。这是我的代码: int nybbles[2][4]; //[0][] is lo
有人可以解释为什么 FLEX 4.5 XMLDecoder 对我的 XML 数据这样做吗? var decoder:XMLDecoder = new XMLDecoder; var $object:O
问题: 我在使用 scanf() 时遇到问题。我从阅读论坛之类的地方知道 scanf() 在 C 中有很多问题,但我只是还在学习基础知识,所以我不知道所有的细节。 我想解决的代码片段。 #includ
我遇到了一个问题,其中 UIViewController.navigationController 变为 nil,我正在拼命寻找这个问题的答案。 UINavigationController 在应用程
我在做this教程。 基本上我的问题是,在 front_is_clear 为 false 后,它运行 Jump_over_hurdle,然后停止。 from my_lib import * while
我正在实现一个简单的 Drag'n'Drop Bahevior。首先我要订阅鼠标事件: protected override void OnAttached() { b
这是我的代码的简化版本: template TIterator findMaximalPosition(TIterator begin, TIterator end) { TIterator
大家好,我有这个代码 function computeChange(){ var change; var amountDue = parseFloat(document.getElementById(
就像我的其他问题一样,非常不言自明。问题是,当用户没有选择银行时,变量 bankMoney 在第一次调用 payDay 时会变为 NaN。不选择,它应该通过我的 random 函数进行随机化,但我认为
当我登录时,我已通过身份验证,但当我切换到另一个页面时,req.isAuthenticated 返回 false,并且我位于登录面板上。第二件事是,当我登录时,我不断收到错误“发送后无法设置 head
下面一行 filterM (\x -> Just (x > 0)) [2, 1, 0, -1] 输出 Just [2,1] 和行 filterM (\x -> Just (x > 0)) [] 显示
这可以完美地使用整数进行拓扑排序,但是我想让它与作为参数的字符串类型兼容。有人对如何从这里更改数据结构有任何指导吗?或者我是否必须重写整个内容才能使 [add.edge("a","b");] 工作?我
我正在尝试调试此应用程序,但存在一个大问题。当我尝试将数组保存到数据文件时,一切正常。但是,如果我关闭应用程序并重新打开数组中的 bool 值,则变为 nil。这是保存数组的代码: NSString
程序运行时,有一系列的ListView窗体。我们用项目(作为字符串)填充其中之一,并检查选择状态是否已更改。更改后,我们使用 FocusedItem.Text 获取所选项目的文本。第一次工作得很好,但
我正在编写一个 WP 插件,它连接到另一个 WP 站点,并获取一些数据作为返回(一些强大的条目,带有名称和其他内容)。 一切都很好,我的插件基本上按预期工作 - 但我今天注意到它有一些奇怪的编码问题
我是一名优秀的程序员,十分优秀!