0

最终更新

原来我的问题全错了。这就是我使用 Fragment 标签的方式。请参阅下面的答案以获得完整的解释。

更新 3:所以我继续搞砸了几个小时,没有这样的运气。我已经能够让它不会崩溃。但现在我相信我知道问题可能出在哪里。它让我calendarAdapter的 as null 因为它是 null,但不是出于我的意图。它似乎onCreateView运行了两次,一次显然是在发送任何内容之前和在我正式发送一些参数之后。这当然不应该发生......我想。我将在底部提供我的 ActionBar 设置的部分,以便您可以让我知道我是否做错了什么,以便按原样设置此行为。


由于某种原因,我对这个特定的事情有疑问,我不知道为什么。我有一个 ActivityMainDisplayActivity和一个 Fragment MainDislpayFragment。可以想象,Activity 在应用启动时设置了 Fragment。现在这就是问题所在,我一直在尝试将newInstance来自日历的三个数字作为参数发送到构造函数中。然后我从构造函数中创建了日历。但是我的应用程序崩溃了。奇怪的是,当我阻止日历被静态字段使用时,应用程序按预期工作,但尝试使用来自构造函数的任何内容的日历会导致它崩溃。这是一个示例方法:

private static Calendar cal;

static MainDisplayFragment newInstance(Context context, int y, int m, int d) {

    c = context;
    MainDisplayFragment f = new MainDisplayFragment();
    //static global Calendar now
            cal = Calendar.getInstance();
            cal.set(y, m, d);
}//end of static newInstance method

现在重要的是要注意,即使我尝试将 Calendar 取出并将其放入 onCreate 并且仅将静态整数作为全局返回并将它们设置在那里,它仍然会导致崩溃。值得注意的错误和奇怪的事情是它似乎认为 Calendar 出于某种原因为空。正如你所知道的那样,它肯定是被创造出来的。但现在我开始认为日历和静态字段存在问题。如果没有,那么我可能有一个错误,但如果可以的话,我想排除它。感谢任何人的回应。

更新:我应该提到我使用该日历信息只不过是传递到我的MyCalendarAdapter. 无论我是只发送数字作为参数还是日历本身,它都会崩溃。我看到的第一个空异常是我试图设置MyCalendarAdapter.

第 75 行将是这里的最后一行:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    view = inflater.inflate(R.layout.main_fragment, container, false);
    calendarAdapter = new MyCalendarAdapter(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH));

更新 2


经过更多的混乱,我意识到问题出在MyCalendarAdapter,但这是一个没有意义的问题。如果您实例化一个不带参数的 calendarAdapter ,它似乎可以完美地工作,但是带参数它会崩溃。这是两个构造函数,MyCalendarAdapter因此人们可以看到看起来没有任何问题,这使情况变得更糟,因为我不知道如何解决这个问题。同样重要的是要知道我试图移动到片段的这段代码最初来自一个运行良好的活动。

public MyCalendarAdapter() {
    thisMonth = Calendar.getInstance();
    now = new MonthDisplayHelper(thisMonth.get(Calendar.YEAR), thisMonth.get(Calendar.MONTH));//creating Helper for month display
    currentDay = thisMonth.get(Calendar.DAY_OF_MONTH);//sets current day

    ...

}

public MyCalendarAdapter(int year, int month, int currentDay) {
    thisMonth = Calendar.getInstance();
    now = new MonthDisplayHelper(year, month);
    this.currentDay = currentDay;

    ...

}

完整的错误列表


11-08 18:26:35.710: E/AndroidRuntime(7839): FATAL EXCEPTION: main
11-08 18:26:35.710: E/AndroidRuntime(7839): java.lang.RuntimeException: Unable to start 
activity ComponentInfo{com.zeroe/com.zeroe.MainDisplayActivity}:   
android.view.InflateException: Binary XML file line #9: Error inflating class fragment
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at   
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.app.ActivityThread.access$600(ActivityThread.java:130)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.os.Handler.dispatchMessage(Handler.java:99)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.os.Looper.loop(Looper.java:137)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.app.ActivityThread.main(ActivityThread.java:4745)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
java.lang.reflect.Method.invokeNative(Native Method)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
java.lang.reflect.Method.invoke(Method.java:511)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at    
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
dalvik.system.NativeStart.main(Native Method)
11-08 18:26:35.710: E/AndroidRuntime(7839): Caused by: android.view.InflateException: 
Binary XML file line #9: Error inflating class fragment
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.view.LayoutInflater.inflate(LayoutInflater.java:489)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.view.LayoutInflater.inflate(LayoutInflater.java:396)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.view.LayoutInflater.inflate(LayoutInflater.java:352)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:256)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.app.Activity.setContentView(Activity.java:1867)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
com.zeroe.MainDisplayActivity.onCreate(MainDisplayActivity.java:60)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.app.Activity.performCreate(Activity.java:5008)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
11-08 18:26:35.710: E/AndroidRuntime(7839):     ... 11 more
11-08 18:26:35.710: E/AndroidRuntime(7839): Caused by: java.lang.NullPointerException
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
com.zeroe.MainDisplayFragment.onCreateView(MainDisplayFragment.java:80)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.app.FragmentManagerImpl.moveToState(FragmentManager.java:807)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1013)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1112)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.app.Activity.onCreateView(Activity.java:4664)
11-08 18:26:35.710: E/AndroidRuntime(7839):     at 
android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:680)
11-08 18:26:35.710: E/AndroidRuntime(7839):     ... 21 more

设置 Fragment 的 ActionBar 部分

@Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
    Toast.makeText(this, "Position is "+itemPosition, Toast.LENGTH_SHORT).show();
    if(itemPosition == 0) {
        FragmentTransaction ft = getFragmentManager().beginTransaction();

        //check to see if one already exists and remove it
        Fragment prev = getFragmentManager().findFragmentByTag(MAIN_FRAGMENT);
        if(prev!=null) {
            ft.remove(prev);
            Toast.makeText(this, "Fragment was found", Toast.LENGTH_SHORT).show();
        }
        MyCalendarAdapter calendarAdapter = new MyCalendarAdapter(year, month, day);
        //Log.d("MAINDISPLAYACTIVTY", "calendarAdapter year is "+calendarAdapter.getCalendar().getYear());
        currentFragment = MainDisplayFragment.newInstance(this, year, month, day, calendarAdapter);
        ft.add((MainDisplayFragment)currentFragment, MAIN_FRAGMENT);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        //ft.addToBackStack(null); //i do not want this behavior
        ft.commit();
        return true;
    }
... continues on with the other cases

设置 ActionBar 的 Activity 中的 onCreate

final ActionBar bar = getActionBar();
    bar.setDisplayShowTitleEnabled(false);
    bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
    bar.setListNavigationCallbacks(new ArrayAdapter<String>(bar.getThemedContext(), android.R.layout.simple_list_item_1, android.R.id.text1,
                                                    new String[]{"MONTH", "WEEK", "DAY"}), this);

    if(savedInstanceState == null) {
        bar.setSelectedNavigationItem(0);
    } else {
        bar.setSelectedNavigationItem(savedInstanceState.getInt(SELECTED_NAVIGATION_STATE));
    }
4

1 回答 1

1

所以我弄清楚我的问题是什么。在有关 Fragments 的 Android 文档中,这一点并不太清楚。我在 main.xml 文件中使用了该<fragment/>标签。我正确使用了它,并且在创建我的 Fragment 时,我也正确设置了它。不幸的是,我没有得到我希望的行为。

事实证明,如果您在 xml 中使用片段标签,那么在setContentView运行时它也会立即运行您的 Fragment 类(至少当它在文件中遇到标签时)。这意味着如果您的 Fragment 依赖于您从中启动它的 Activity 的信息,它将没有它,并且基本上运行两次;当 setContentView 运行时,以及当您实际运行 Fragment 时。这很重要,因为我假设您可以选择任何一种方式来运行您的 Fragment。但实际上,你设计应用程序或处理它的方式实际上决定了你应该走哪条路,硬编码片段或在运行中务实。

也许这对 android 专家来说是显而易见的,但我是 Fragments 的新手,所以我猜这是一个菜鸟错误。无论哪种情况,这都应该在 Android 文档中详细说明。希望这可以帮助其他对这个问题完全困惑的人。

于 2012-11-09T06:10:57.517 回答