简体   繁体   English

Android Java:片段在onCreateView()中返回空视图

[英]Android Java: Fragments returning null view in onCreateView()

I am currently working on a program that uses an MVC design pattern and fragments in android java. 我目前正在研究使用MVC设计模式和android java中的片段的程序。 I have figured out one of my fragments and gotten it working but when I copied the other fragments to follow the same code structure (with specialized functionality), I get a null pointer exception in the onCreateView method. 我已经弄清楚了我的一个片段并使它工作,但是当我复制其他片段以遵循相同的代码结构(具有特殊功能)时,在onCreateView方法中出现了空指针异常。

I'm on my junk laptop right now and it can't seem to handle android emulation so I can post the exact error code tomorrow. 我现在在我的垃圾笔记本电脑上,它似乎无法处理android仿真,因此明天可以发布确切的错误代码。 I have my source code though and I have been hitting my head against the wall long enough to know where it is breaking. 虽然我有我的源代码,但我已经在墙上碰了很长时间,以了解它在哪里破裂。

EDIT: I see my problem. 编辑:我看到我的问题。 I'm testing the my code by calling a method from within the View.java class from each fragment. 我正在通过从每个片段的View.java类中调用一个方法来测试我的代码。 This method updates a table in the view. 此方法更新视图中的表。 Since the views haven't been displayed on screen yet, onCreateView() hasn't been called for them. 由于视图尚未显示在屏幕上,因此尚未为其调用onCreateView()。 Since onCreateView() hasn't been called, trying to access the view results in a null pointer. 由于尚未调用onCreateView(),因此尝试访问视图将导致空指针。 Is there any good way to call onCreateView() for each fragment from my MainActivity just so I can initialize the views early? 有什么好方法可以为MainActivity中的每个片段调用onCreateView(),以便我可以尽早初始化视图?

(Part of the working fragment): (工作片段的一部分):

    public class DispatchView extends Fragment {
private final List<DispatchModel> models = new ArrayList<DispatchModel>();

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.dispatchfragment, container,
            false);
    return view;
}

All fragments, except for DispatchView, break upon returning view. 除DispatchView之外的所有片段都会在返回视图时中断。 They are returning null rather than an actual object. 他们返回null而不是实际对象。 Part of one of the broken fragments: 破碎片段之一的一部分:

    public class ConnectionsLogView extends Fragment {
private final List<ConnectionsLogModel> models = new ArrayList<ConnectionsLogModel>();

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.connectionslogfragment,
            container, false);
    return view;
}

The fragments are declared and initialized. 片段被声明和初始化。 They (any of them except the Dispatch MVC) break after I try to push a new data entry (class) into them. 我尝试将新的数据条目(类)推入它们后,它们(除Dispatch MVC之外的任何一个)都断开了。 In my MainActivity.java: 在我的MainActivity.java中:

    public class MainActivity extends Activity {
// Declare Tab Variables and fragment objects
private mDMI             app;
ActionBar.Tab            Tab1, Tab2, Tab3, Tab4;
Fragment                 dispatchTab          = new DispatchView();
Fragment                 dispatchLogTab       = new DispatchLogView();
Fragment                 activeConnectionsTab = new ConnectionsView();
Fragment                 connectionLogTab     = new ConnectionsLogView();
DispatchModel            dispatchModel;
DispatchController       dispatchController;
DispatchLogModel         dispatchLogModel;
DispatchLogController    dispatchLogController;
ConnectionsModel         connectionsModel;
ConnectionsController    connectionsController;
ConnectionsLogModel      connectionsLogModel;
ConnectionsLogController connectionsLogController;

public MainActivity() {
    super();
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    app = (mDMI) getApplication();
    dispatchModel = app.getDispatchModel();
    dispatchController = new DispatchController(dispatchTab, dispatchModel);
    dispatchLogModel = app.getDispatchLogModel();
    dispatchLogController = new DispatchLogController(dispatchLogTab,
            dispatchLogModel);
    connectionsModel = app.getConnectionsModel();
    connectionsController = new ConnectionsController(activeConnectionsTab,
            connectionsModel);
    connectionsLogModel = app.getConnLogModel();
    connectionsLogController = new ConnectionsLogController(
            connectionLogTab, connectionsLogModel);
    setContentView(R.layout.activity_main);

The xml strings are identified In my R.java: xml字符串在我的R.java中标识:

    public static final class layout {
    public static final int activity_login=0x7f030000;
    public static final int activity_main=0x7f030001;
    public static final int connectionsfragment=0x7f030002;
    public static final int connectionslogfragment=0x7f030003;
    public static final int dispatchfragment=0x7f030004;
    public static final int dispatchlogfragment=0x7f030005;
}

Don't create your fragments that way. 不要以这种方式创建片段。 Instead use a standard Android pattern: 而是使用标准的Android模式:

public class FeedFragment extends Fragment {
   public FeedFragment() {
     super();
   }
   public static FeedFragment newInstance(Context context) {
     if (context != null) {
       sContext = context.getApplicationContext();
     } else {
       sContext = YourApp.getInstance().getApplicationContext();
     }
     return new FeedFragment();
   }
 }

Then don't create them like that in your activity… 然后不要在您的活动中像那样创建它们…

instead use a standard Android pattern in your Activity: 而是在Activity中使用标准的Android模式:

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        FragmentManager fm = getSupportFragmentManager();
        Fragment fragment = fm.findFragmentById(R.id.content_frame);
        if ( fragment == null ) {
            fragment = FeedFragment.newInstance(this);
            fm.beginTransaction()
                    .add(R.id.content_frame, dispatchTab, "DISPATCH_FRAG")
                    .commit();
        }
    }

To retrieve the fragment later you can do… 要稍后检索片段,您可以...

final FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentByTag("DISPATCH_FRAG);
if (fragment != null) {
   // cast and use your fragment
}

You can even store a reference if you need it later. 如果以后需要,甚至可以存储参考。

Regarding your null problem, it's really hard to tell without the exact crash/log. 关于您的null问题,如果没有确切的崩溃/日志,很难说出来。

But your code is a little bit messy and that may be the cause. 但是您的代码有点混乱,这可能是原因。 Fragment LifeCycle is tricky. 片段生命周期非常棘手。

I fixed it myself. 我自己修好了。 If the view returns null, my update functions dont try to add rows and entries to the (nonexisting) table in the (nonexisting) view. 如果该视图返回null,则我的更新函数不会尝试向(不存在)视图中的(不存在)表添加行和条目。 I implemented this in each view like so: 我在每个视图中都这样实现了:

public void update(final BlockingDeque<Dispatch> dispatches) {
    View view = getView();
    // do not update if the view is null (device is not displaying that
    // fragment)
    if (view != null) {
        TableLayout t = (TableLayout) view.findViewById(R.id.dispatchTable);
        t.removeAllViews();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM