从某些 class 调用 Fragment 中的方法

Call method in Fragment from some class

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

MainFragment

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 获取实例,以及从 Whosebug 获取更多可能的解决方案,但仍然得到相同的空对象引用。

你的问题是你的助手 class 正在创建一个与显示的片段没有关联的全新 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);
    }
}

那么你的控制器应该不依赖于片段,而是接受你定义的接口的实例

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");
        }
    }
}    

但是,为具有要显示的内容的 LiveData 的片段制作一个 ViewModel 会好得多。 Fragment 只会观察 LiveData,而 ViewModel 可以处理查询数据库助手并将数据放入 LiveData。