【问题标题】:Fragments gets null after orientation change方向更改后片段为空
【发布时间】:2019-01-17 07:02:00
【问题描述】:

我的Fragments 有问题。我有四个处于 portrait 模式的片段。

设置片段

public void setCorrectNavigationItem(int id) {
    if (id == R.id.nav_auftragsbilder) {
        fragment = new AuftragsbilderFragment();
        id = R.id.nav_auftragsbilder;
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    } else if (id == R.id.nav_auftragskorrektur) {
        fragment = new AuftragskorrekturFragment();
        id = R.id.nav_auftragskorrektur;
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    } else if (id == R.id.nav_lagerplatz) {
        fragment = new LagerplatzFragment();
        id = R.id.nav_lagerplatz;
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    } else if (id == R.id.nav_biegenstatus) {
        fragment = new BiegestatusFragment();
        id = R.id.nav_biegenstatus;
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }
    _navigationView.setCheckedItem(id);
    _selectedMenuItem = id;

    SharedPreferences.Editor editor = menuCheck.edit();
    editor.putInt("id", id);
    editor.commit();

    //Fragment öffnen
    if (fragment != null) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction ft = fragmentManager.beginTransaction();
        ft.replace(R.id.fragment_container, fragment);
        ft.commit();
    }
}

所以在我的片段设置方法中,我现在必须为每个不同的片段设置方向。我不得不将我的 'BiegestatusFragment' 更改为 landscape,在那里我调用了一个扫描条形码的方法,intent result 我在我的 Fragment 中设置了参数。

这是我的条形码扫描Activity

//Biegestatus Begleitschein-Barcodes
public void makeBiegestatusBegleitscheinBarcode() {
    _lastAction = ACTION_BIEGESTATUS_BEGLEITSCHEIN_BARCODE;
    if (!checkCameraPermission(this, PERMISSIONS)) {
        ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
    } else {
        Intent intent = new Intent(this, ContinuousCaptureActivity.class);
        startActivityForResult(intent, 1);
    }
}

意图结果

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (data != null) {
        ArrayList<String> begleitscheine = data.getStringArrayListExtra("begleitscheine");
        if (resultCode == 1 && begleitscheine != null) {
            //HERE IT IS NULL
            ((BiegestatusFragment) fragment).setBegleitscheine(begleitscheine);
        } else {
            Toast.makeText(this, "Scannen abgebrochen", Toast.LENGTH_LONG).show();
        }
    } else {
        Toast.makeText(this, "Unbekannter Fehler aufgetreten, Entwickler kontaktieren.", Toast.LENGTH_LONG).show();
    }
}

CreateView 上的片段

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_biegestatus, container, false);

    _cardEdit = (EditText) v.findViewById(R.id.workerEdit);
    _scrollViewArticles = (ScrollView) v.findViewById(R.id.scrollViewArticles);
    _searchImageLayout = (LinearLayout) v.findViewById(R.id.searchImageLayout);
    _personalNummer = (EditText) v.findViewById(R.id.workerEdit);
    _progressBar = (LinearLayout) v.findViewById(R.id.progressBar);
    _maschinenPicker = (NumberPicker) v.findViewById(R.id.maschinenPicker);
    _pickerHolder = (LinearLayout) v.findViewById(R.id.pickerHolder);
    _scanBegleitscheinBtn = (Button) v.findViewById(R.id.scanBegleitscheinBtn);

    return v;
}

方法应该被调用

public void setBegleitscheine(ArrayList<String> begleitscheine) {
    _begleitscheine = begleitscheine;
}

现在我的 Fragment 为空,因为 orientation 发生了变化。 删除方向设置方法解决了我的问题。但我需要把这个片段放在风景中。

错误

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: at.co.era.bilder.erabilderapp, PID: 21835
                  java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=1, data=Intent {  launchParam=MultiScreenLaunchParams { mDisplayId=0 mBaseDisplayId=0 mFlags=0 }(has extras) }} to activity {at.co.era.bilder.erabilderapp/at.co.era.bilder.erabilderapp.HomeActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void at.co.era.bilder.erabilderapp.BiegestatusFragment.setBegleitscheine(java.util.ArrayList)' on a null object reference
                      at android.app.ActivityThread.deliverResults(ActivityThread.java:4520)
                      at android.app.ActivityThread.handleSendResult(ActivityThread.java:4563)
                      at android.app.ActivityThread.-wrap22(ActivityThread.java)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1698)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:154)
                      at android.app.ActivityThread.main(ActivityThread.java:6776)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
                   Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void at.co.era.bilder.erabilderapp.BiegestatusFragment.setBegleitscheine(java.util.ArrayList)' on a null object reference
                      at at.co.era.bilder.erabilderapp.HomeActivity.onActivityResult(HomeActivity.java:1130)
                      at android.app.Activity.dispatchActivityResult(Activity.java:7280)
                      at android.app.ActivityThread.deliverResults(ActivityThread.java:4516)
                      at android.app.ActivityThread.handleSendResult(ActivityThread.java:4563) 
                      at android.app.ActivityThread.-wrap22(ActivityThread.java) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1698) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:154) 
                      at android.app.ActivityThread.main(ActivityThread.java:6776) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386) 

【问题讨论】:

  • 实例化片段的首选方法是通过 newInstance。看看this
  • 把它改成newInstance...但是当调用id的方法说我的_maschinenPicker是null String maschine = _maschinen.get(_maschinenPicker.getValue());

标签: java android android-fragments fragment


【解决方案1】:
 //Fragment öffnen
    if (fragment != null) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction ft = fragmentManager.beginTransaction();
        ft.replace(R.id.fragment_container, fragment);
        ft.addToBackStack(null); // or you can give it any name instead of null to get the frament when poping the fragment from backstack
        ft.commit();
    }

【讨论】:

  • 仍然面临同样的问题。其他想法?
【解决方案2】:

您可以通过将清单中的以下行添加到您的活动标签来强制您的活动在方向更改后不重新加载

android:configChanges="orientation" 

【讨论】:

  • 谢谢你的回答...我很久以前添加了它,但仍然有这个问题。
  • 请通过 addToBackStack("withSomeName") 将您的片段添加到后台堆栈中添加在 API 级别 11 中将此事务添加到后台堆栈。这意味着事务将在提交后被记住,并在以后从堆栈中弹出时反转其操作。
  • 怎么做?
  • 当一个方向收费时强制你的活动不被重新创建不是一个好主意,它需要创建以便使用布局,不同方向的res
  • @AjayChauhan 我只使用纵向模式...仅用于我需要横向的单个片段。
【解决方案3】:

在片段内部,在 onCreateView() 中尝试使用:

setRetainInstance(true);

在此处查看文档: https://developer.android.com/reference/android/app/Fragment#setRetainInstance(boolean)

【讨论】:

  • 你把“retainInstance(true);”放在哪里了?
  • 在onCreateView()的开头,后来我在它的底部尝试了
  • 我的意思是在哪个片段中?
  • 在我的 BiegestatusFragment 中一直保持为空...在我的 IntentResult 中为空
  • 正如我在您的代码中看到的那样,您正在为 LANDSCAPE 使用两个片段,您需要为两个片段都设置为 true。
猜你喜欢
  • 2013-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-13
  • 1970-01-01
相关资源
最近更新 更多