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

【问题讨论】:

    标签: java android class methods fragment


    【解决方案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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-28
      • 1970-01-01
      • 2014-01-07
      • 1970-01-01
      • 2012-08-14
      • 2014-04-24
      • 1970-01-01
      • 2021-06-13
      相关资源
      最近更新 更多