【问题标题】:What is the correct way to deal with the deprecated Fragment events onAttach and onInflate处理已弃用的 Fragment 事件 onAttach 和 onInflate 的正确方法是什么
【发布时间】:2016-03-21 15:55:31
【问题描述】:

我已经阅读了一些关于已弃用代码的文章和答案(包括 this one),但我对如何处理(特别是)已弃用的 Fragment 事件处理程序 onInflate 有点困惑。

我已经替换了我的实现

public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState)

public void onInflate(Context context, AttributeSet attrs, Bundle savedInstanceState)

如果我在

如果我恢复原来的弃用代码(这样我现在已经实现了这两种方法),那么将调用弃用的代码,返回正确的功能,但现在正在调用弃用的方法(?)。

当我在 API23 机器上运行应用程序时,似乎调用了两个版本的处理程序。

所以问题是,这里发生了什么? 如果我正在编写应该在 API23 和更早版本上运行的代码,我是否需要实现已弃用的方法以及新的方法?

如果是这种情况,我是否需要“以防万一”寻找并实施其他已弃用的方法? (因此,是否有这些已弃用的“回码”方法的列表?)


更新:

我现在已经从使用android.app.Fragment 更改为android.support.v4.app.Fragment(即从原生片段到支持片段)并且应用程序现在按预期执行,替换处理程序代码针对所有版本运行,并且正在逐步通过 android来源如预期。

但问题仍然存在:为什么

为什么“本机”android.app.Fragment 实现被 **** 了?回顾之前的问题,这个问题早在 2015 年 9 月就被讨论过了。那么为什么它仍然是一个问题? 为什么在 API 11 之后的支持和原生 Fragment 的实现应该有所不同?

【问题讨论】:

  • 感谢您将 depreciated 编辑为 deprecated。我从来没有意识到我有阅读障碍! :)

标签: android android-fragments


【解决方案1】:

不,你不应该实现

public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState)

当某个方法被弃用时,您可以(通常)安全地使用替换函数。查看 Fragment 对 onInflate 的定义:

public void onInflate(Context context, AttributeSet attrs, Bundle savedInstanceState) {
        mCalled = true;
        final Activity hostActivity = mHost == null ? null : mHost.getActivity();
        if (hostActivity != null) {
            mCalled = false;
            onInflate(hostActivity, attrs, savedInstanceState);
        }
    }

 @Deprecated
    public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) {
        mCalled = true;
    }

如您所见,onInflate(Context context...)onInflate(Activity activity...) 的扩展,并且向后兼容。通过在重写的方法中调用 super.onInflate(context, attrs, savedInstanceState);,您可以放心地假设它适用于 API23 和更早版本。

如果我在

这似乎很奇怪,我无法重现它,我的日志是在非 v23 机器上使用这样的代码执行的:

@Override 
public void onInflate(Context context, AttributeSet attrs,
                                    Bundle savedInstanceState) {
        super.onInflate(context, attrs, savedInstanceState);
        Log.w(TAG, "I'm being executed");
    }

确保:

  1. 您正在导入 Fragment 的支持版本,android.support.v4.app.Fragment 而不是 android.app.Fragment,并且您使用 getSupportFragmentManager() 而不是 getFragmentManager()
  2. 您的build.gradle 中有support-v4appcompat-v7 以及compileSdkVersion 23 的最新库

当我在 API23 机器上运行应用程序时,两者似乎 处理程序的版本被调用。

这可以用onInflate(Context context...)代码来解释,如果它被一个Activity调用,调用onInflate(Activity activity...)

编辑

关于更新:

android.app.Fragment 的本机实现不应该向后兼容。因为这个事实,android.app.Fragment 的代码通常比android.support.v4.app.Fragment 的代码简单得多。

此外,本机实现中的某些功能无法在支持库中引入,因为它在设计上很困难,或者因为它不是开发人员的优先事项。例如。在本机实现中,在 onInflate() 源代码中有一些使用 Transition 来为新片段的入口或出口设置动画。这在支持库中找不到。

【讨论】:

  • 感谢您不厌其烦地回答。我可以看到为什么两个版本的处理程序都被调用为 v23。不过,我仍然没有接到 v23 之前版本的替换处理程序的电话。奇怪的是,我收到一条日志消息“I/dalvikvm:找不到方法 android.app.Fragment.onInflate,从方法 OdometerFragment.onInflate 引用”,这似乎很奇怪。单步执行 android Fragment 代码显示错误的源代码行这一事实让我相信我没有最新版本的东西。
  • 确保:1) 您正在导入 Fragment 的支持版本,android.support.v4.app.Fragment 而不是 android.app.Fragment,并且您使用 getSupportFragmentManager()的 getFragmentManager()。 2) 你的 build.gradle 中有最新的 support-v4 和 appcompat-v7 库以及 compileSdkVersion 23。
  • 感谢您的进一步提示。昨晚我尝试更改为“支持”片段,它为我解决了问题。我已经相应地更新了这个问题。我仍然对为什么原生和支持实现不同感到困惑。对我来说,这似乎是某个地方搞砸了。是的 - 我的具体问题已解决,但 app.android.Fragment 没有
  • 即使您的编辑问题是原始问题的扩展,并且可能值得单独发布新帖子,但我已经进行了一些编辑,其中一些要点可能会回答您的问题。您可能还想查看this
猜你喜欢
  • 2015-11-12
  • 1970-01-01
  • 1970-01-01
  • 2012-07-22
  • 2012-03-31
  • 2012-11-14
  • 2013-07-24
  • 1970-01-01
  • 2015-05-11
相关资源
最近更新 更多