【问题标题】:Call Activity Method From Fragment从 Fragment 调用 Activity 方法
【发布时间】:2012-08-17 16:55:04
【问题描述】:

我正在处理片段。
我有一个Activity 和不同的fragments
每个fragment 需要访问Class(call it X) 以允许它访问数据库,但是,因为我有很多片段,所以我不想在每个片段中创建Class X 的不同实例,因为我认为这需要很多memory
那我该怎么办呢?
我写了这样的东西(用吸气剂),但它不起作用!

public class MyActivity {
  private ClassX classx;

  .....

  public ClassX getClassX() {
     return classx;
  }   
  .....
}

但是,我如何从fragment 调用它?

【问题讨论】:

    标签: android methods android-activity call fragment


    【解决方案1】:

    您可以在活动中使用静态对象,并从片段中使用它,或者在片段中调用 getActivity() 方法来访问整个活动对象/方法

    【讨论】:

    • 但是ClassX需要初始化一次。所以我不能使用静态方法:(
    • 为什么不在课堂上使用单例模式。您可以通过这种方式确保 ClassX 只初始化一次。
    【解决方案2】:

    定义一个名为Callbacks 的接口(或其他名称,如果您愿意)。在其中,有一个名为getClassX() 的公共方法。然后让你的Activity实现Callbacks接口。

    在您的 Fragments 中,在 onAttach 中,存储对 Callbacks 对象的引用(即您的活动通过以下方式:

    if(activity instanceof Callbacks)
        mCallbacks = (Callbacks)activity;
    

    这将保证 Fragments 能够调用该函数。 (如果您想稍后在另一个应用程序中重用片段)

    然后在您的活动中,在onCreate() 中,创建ClassX 的实例。在您的 getClassX() 方法中,只需返回对它的引用。

    如果您想从 Fragments 中引用它,请致电 mCallbacks.getClassX(),您应该会被排序。

    【讨论】:

    • 这是正确的方法。你可以在这里阅读更多:http://developer.android.com/training/basics/fragments/communicating.html
    【解决方案3】:

    这更像是一个 Java 问题和 android。

    如果您正在考虑访问数据库,请查看创建数据库单例。

    比如:

    public class Database {
    
        // This starts off null
        private static Database mInstance;
    
        /**
         * Singleton method, will return the same object each time.
         */
        public static final Database getInstance() {
            // First time this method is called by Database.getInstance() from anywhere
            // in your App. It will create this Object once.
            if(mInstance == null) mInstance = new Database();
            // Returns the created object from a statically assigned field so its never
            // destroyed until you do it manually.
            return mInstance;
        }
    
        //Private constructor to stop you from creating this object by accident
        private Database(){
          //Init db object
        }
    
    }
    

    然后从您的片段和活动中,您可以将以下字段放入您的类中(最好使用基础活动和片段来节省重复代码)。

    public abstract class BaseFragment extends Fragment {
    
        protected final Database mDatabase = Database.getInstance();
    
    }
    

    然后您的具体片段可以扩展您的BaseFragment,例如SearchListFragment extends BaseFragment

    希望这会有所帮助。

    singletonsdatabase 值得一读

    问候, 克里斯

    【讨论】:

    • 我立即开始阅读有关单例的内容。从未听说过,但听起来真的很有趣!所以如果我使用它,我将永远不需要用经典方式“MyObject a = new MyObject()”来初始化单例类?
    • 初始化在 Singleton 类中完成,因此静态调用该类:Database.getInstance() Android/Java 框架中的一个示例是:Calendar.getInstance() 这将为您创建 Calendar 对象。
    • 这是一种有用的方法,但只将它用于您总是需要/使用的对象,因为该对象被静态强引用,所以它几乎永远不会被GC'd。所以数据库/应用程序/首选项等避免模型数据!
    • 哇,太棒了!所以,为了确定......我可以使用 Database.getInstance() 从我的代码的每一部分调用 Database 类,并且代码将始终引用同一个实例?如果对象进入 GC 会发生什么?它会很慢还是会出错?
    • 正确。但只是为了您意识到它不像 Java 中的任何 Object 那样 100% 需要 GC,但这并不是要吓唬您,只是为了增加您的理解。无论哪种方式,如果它确实在生命周期之间被 GC 处理,至少你的 Activity/Fragment 等使用相同的对象,更糟糕的情况 - 但我以前从未遇到过这个问题 :)
    【解决方案4】:

    从片段调用你的活动方法

    ((MyActivity )  getActivity()).getClassX() ;
    

    【讨论】:

    • 这是最简单的方法,但它是最佳实践吗?
    • @Haraldo 使用 Interface for callBack 也是一个更好的选择。
    • 虽然这可能不是最佳实践,但它暂时解决了问题,为客户创造了价值。然后我们可以寻找最佳选择。
    【解决方案5】:

    你必须做额外的演员:

    Activity activity123 = getActivity();
    
    if(activity123 instanceof ParentActivity) {
        ((ParentActivity) activity123).someMethodInParentActivity();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多