从某个类调用片段中的方法

Posted

技术标签:

【中文标题】从某个类调用片段中的方法【英文标题】:Call method in Fragment from some class 【发布时间】:2022-01-05 20:58:00 【问题描述】:

我一直在 androidStudio 中开发 Android 应用程序。 应用程序有Fragment,我们称它为MainFragment,以及单独的Java Class 文件,我们称它为SQLiteControler.class 问题是当我尝试从 SQLiteController 中的 Fragment 调用方法时,我得到 null object reference as error 这是一些缩小的代码:

主片段

public class MainFragment extends Fragment 
            ...
            //TextViews & ETC
            public View onCreateView(@NonNull LayoutInflater inflater,
                                     ViewGroup container, Bundle savedInstanceState) 
                view = inflater.inflate(R.layout.fragment_profil, container, false); 
           return view:
    
    public void someMethod(...)
     textView.setText("abc");
    //somecode
   

SQLiteController

public class SQLiteDataHelper 
    private Context context;
    MainFragment mainFragment;

    public SQLiteDataHelper(Context context)
        this.context = context;
        mainFragment = new MainFragment();

    
    public void anothermethod()
    mainFragment.someMethod(...)
    

注意 这是缩小的代码

我已经尝试了一些解决方案,例如从 MainFragment 和 ETC 获取实例,以及从 *** 获取更多可能的解决方案,但仍然获得相同的空对象引用。

【问题讨论】:

【参考方案1】:

您的问题是您的助手类正在创建一个全新的 MainFragment 实例,该实例与显示的片段没有关联(视图将为空)。

您不应该在帮助程序中创建新的片段实例。您应该定义某种接口并使用它来处理这种类型的耦合(或使用 ViewModel 和 LiveData - 首选)。如果你想走自定义接口路线,你可以这样定义一个接口:

interface DBDisplayer 
    public void showText(String msg);

然后你可以让你的片段实现这个接口:

public class MainFragment extends Fragment implements DBDisplayer 

    // I'll assume your helper is a singleton - if not, you'll need to figure
    // out how to get an instance of it in your fragment.
    private SQLiteDataHelper dbHelper = SQLiteDataHelper.getInstance();
    
    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) 
        view = inflater.inflate(R.layout.fragment_profil, container, false); 
        return view:
    
    
    @Override 
    public void onResume() 
        super.onResume();
        dbHelper.setDisplayer(this);
    
    
    @Override 
    public void onPause() 
        super.onPause();
        // remove the displayer when the fragment is not being shown
        dbHelper.setDisplayer(null);
    
    
    @Override 
    public void showText(String msg)
        textView.setText(msg);
    

那么你的控制器应该没有对 Fragment 的依赖,而是接受你定义的接口的一个实例

public class SQLiteDataHelper 
    private Context context;
    private DBDisplayer displayer = null;

    public SQLiteDataHelper(Context context)
        this.context = context;
    
    
    public void setDisplayer(DBDisplayer d) 
        displayer = d;
    
    
    public void anothermethod()
        if( displayer != null ) 
            displayer.showText("some words");
        
    
    

然而,为片段创建一个 ViewModel 会更好,该片段具有 LiveData 用于您想要显示的内容。 Fragment 只会观察 LiveData,而 ViewModel 可以处理查询数据库助手并将数据放入 LiveData。

【讨论】:

以上是关于从某个类调用片段中的方法的主要内容,如果未能解决你的问题,请参考以下文章

从Asynctask ONPostExecute调用片段方法

如何从主要活动中调用片段方法

从片段调用活动方法

从活动中调用片段中的非静态方法?

从片段内部调用活动方法[重复]

从活动中调用片段方法