簡體   English   中英

從onResume活動調用時,片段視圖為null

[英]Fragment views null when called from onResume activity

我想閱讀NFC標簽,當活動處於前台時,我能夠閱讀。 但是,當活動不在前台並且檢測到NFC標簽時,該活動將無法繼續並引發如下異常:

java.lang.NullPointerException: Attempt to invoke virtual method 'void  android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference

我正在將Viewpager與FragmentPagerAdapter一起使用來設置選項卡。 所有這些設置都是通過onCreate()方法完成的,如下所示:

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    /*assert getSupportActionBar() != null;
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);*/


    viewPager = (ViewPager) findViewById(R.id.viewpager);
    setupViewPager(viewPager);

    tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(viewPager);

    mWriteFragmentIndex = 1;
    mReadFragmentIndex = 0;

    mNfcAdapter = NfcAdapter.getDefaultAdapter(MainActivity.this);
    mPendingIntent = PendingIntent.getActivity(MainActivity.this, 0,
            new Intent(MainActivity.this, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
}

片段尋呼機適配器如下所示:

private void setupViewPager(ViewPager viewPager) {

    adapter = new ViewPagerAdapter(getSupportFragmentManager());

    mReadFragment = new ReadFragment();
    adapter.addFragment(mReadFragment, "Read");


    mWriteFragment = new WriteFragment();
    adapter.addFragment(mWriteFragment, "Write");

    viewPager.setAdapter(adapter);

}

class ViewPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public ViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }


    @Override
    public Object instantiateItem(ViewGroup container, int position) {

        Fragment fragment = (Fragment) super.instantiateItem(container, position);

        if(fragment instanceof ReadFragment){
            mReadFragment = (ReadFragment) fragment;
        }
        if(fragment instanceof WriteFragment){
            mWriteFragment = (WriteFragment) fragment;
        }
        return fragment;
    }


}

當活動不在前台時檢測到NFC標簽時,我會在onResume方法中收到NFC意圖。 然后,我在片段中調用一個方法來讀取標簽。

    private void readIfTag(Intent intent){

    if(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()) || NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())){

        if(mReadFragment != null) {

           mReadFragment.readTag(intent);

            if(viewPager.getCurrentItem() != mReadFragmentIndex) {
                viewPager.setCurrentItem(mReadFragmentIndex);
            }

        }

    }

}

標記已正確讀取(我可以在日志中看到從標記中檢索到的文本),但是當片段嘗試更新其視圖時會引發異常。

從日志中可以看到,PagerAdapter的InstantiateItem()以及片段的onCreateView()隨后在readIfTag()方法之后執行,這就是片段視圖為空的原因。 我不明白為什么這是我做錯的地方。

希望對代碼的任何部分提供任何幫助。 謝謝。

更新下面給出了被調用片段中的方法。 注意,mInstructionTextView.setText(“”)是引發異常的行。 因此,換句話說,片段以某種方式存在,但它的視圖不存在。

 public void readTag(Intent intent) {

    String action = intent.getAction();
    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {

        String type = intent.getType();
        if (MIME_TEXT_PLAIN.equals(type)) {

            Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            Ndef ndef = Ndef.get(tag);
            if (ndef == null) {
                // NDEF is not supported by this Tag.
                return;
            }
            NdefMessage ndefMessage = ndef.getCachedNdefMessage();

            NdefRecord[] records = ndefMessage.getRecords();
            for (NdefRecord ndefRecord : records) {
                if (ndefRecord.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT)) {
                    try {
                        String result =  readText(ndefRecord);


                                mInstructionTextView.setText("");

我設法通過使用Activity和Fragment之間的接口來解決此問題。

問題在於訪問Fragment視圖的方法是在FragmentPagerAdapter完全實例化Fragments(准確地說,是它們的視圖)之前執行的。

因此,我要做的是在Activity必須實現的Fragment中創建一個接口。 在Fragment的onCreateView()末尾,我在接口中調用了該方法。 在該方法的實現中(在Activity中),我調用了用於讀取標簽的方法。

也許嘗試在inResume中調用您調用的代碼

void onResumeFragments()

並引用docu

這是onResume()的面向片段的版本,您可以重寫它以在恢復其片段的同一點在Activity中執行操作。

不要將代碼放在onCreate onCreate()在onCreateView()之前被調用,因此您無法在onCreate()獲得視圖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM