17

मैं एंड्रॉइड के support.v4 पैकेज का उपयोग कर रहा हूं ताकि एक व्यूपेगर विकसित हो सके जिसमें एकाधिक Fragment एस शामिल हैं।व्यूपेगर टुकड़े समय के साथ नष्ट हो रहे हैं?

जब उपयोगकर्ता पृष्ठ बदलता है तो मैं दृश्यों को छिपाने की कोशिश कर रहा हूं। इसलिए, मैंने अपने एडाप्टर को सुनने के लिए OnPageChangeListener लागू किया, और जब कोई पृष्ठ परिवर्तन होता है तो Fragment एस में update() विधि को कॉल करें। लेकिन मुझे NullPointerException मिल रहा है, और मैं यह नहीं समझ सकता कि क्यों।

यहाँ कोड है:

public class MyActivity extends FragmentActivity implements 
     OnPageChangeListener { 

    private static final int NUM_ITEMS = 2; 
    private ViewPager mPager; 
    private static SpaceAdapter mAdapter; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.fragment_pager); 

     mAdapter = new SpaceAdapter(getSupportFragmentManager()); 
     mPager = (ViewPager) findViewById(R.id.pager); 
     mPager.setAdapter(mAdapter); 

     mPager.setOnPageChangeListener(this); 
} 

    public static class SpaceAdapter extends FragmentPagerAdapter { 

     public SpaceAdapter(FragmentManager fm) { 
      super(fm); 
     } 

     @Override 
     public int getCount() { 
      return NUM_ITEMS; 
     } 

     @Override 
     public Fragment getItem(int position) { 
      switch (position) { 
      case 0: 
      return new MyFragment(); 
      case 1: 
      return new MyFragment(); 
      default: 
      return new MyFragment(); 
      } 
     } 
    } 

    @Override 
    public void onPageScrollStateChanged(int arg0) { 
     Log.i("pagination", "scroll state changed: " + arg0); 
} 

    @Override 
    public void onPageScrolled(int arg0, float arg1, int arg2) { 
     // Log.i("pagination", "page scroll: " + arg0 + " with: " + arg1 + ", " + arg2); 
     if (mAdapter.getItem(arg0) instanceof IUpdateOnPage) { 
      ((IUpdateOnPage) mAdapter.getItem(arg0)).updateOnPage(); 
     } 
    } 

    @Override 
    public void onPageSelected(int arg0) { 
     Log.i("pagination", "page selected: " + arg0); 
    } 
} 

और

public class MyFragment extends Fragment implements 
     SurfaceHolder.Callback, IUpdateOnPage { 

    private SurfaceView charts; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     View v = inflater.inflate(R.layout.crew, null); 
     bindViews(v); 
     return v; 
    } 

    private void bindViews(View v) { 
     charts = (SurfaceView) v.findViewById(R.id.civ_charts); 

     charts.getHolder().addCallback(this); 
     Log.i("wtf", "huh " + String.valueOf(charts == null)); // logs false 
    } 

    @Override 
    public void updateOnPage() { 
     if (charts != null) { 
      Log.i("crew surface", "hidden"); 
      charts.setVisibility(View.GONE); 
     } else { 
      Log.i("crew surface", "charts is null"); //THIS HERE gets logged 
     } 
    } 
} 

wWhen मैं कॉपी/पेस्ट किया मैं SurfaceHolder.Callback विधियां निकाल दी है, लेकिन वे कर रहे हैं। bindViews(v) विधि लॉग अगर charts == null, और यह हमेशा झूठी वापसी करता है। जब मैं पृष्ठ, updateOnPage कहलाता है, और charts == null सत्य देता है। ऐसा क्यों होता है और मैं इसके आसपास कैसे हो सकता हूं?

और इस लाइन है 108:

charts.setVisibility(View.GONE); 
+0

ठीक है, आगे की जांच के बाद, मुझे लगता है कि अंकन शुरू होने पर टुकड़ा नष्ट हो जाता है (भले ही दृश्य बना रहता है?)। जब स्वाइप करते हैं तो मैं अभी भी टुकड़ा "आधा" देख सकता हूं जब तक कि नया टुकड़ा पूर्ण-दृश्य में न हो जाए। इसलिए, यदि सभी संदर्भ एकत्र किए जा रहे हैं और जो कुछ भी बचा है, वह दृश्य है, मैं यह कैसे कर सकता हूं? – edthethird

+0

यदि आपको 'NullPointerException' मिल रहा है, तो क्या आप लॉगकट आउटपुट पोस्ट कर सकते हैं? –

+0

अच्छी तरह से मैं वास्तव में इसे पकड़ रहा हूं इसलिए एक अपवाद फेंक दिया नहीं गया है। समस्या 'charts.setVisibility (View.GONE) है;'। चार्ट शून्य है। यह कोड के दूसरे नमूने के बहुत अंत में है, ठीक है 'else' से ऊपर। जोड़ा गया स्टैक ट्रेस। – edthethird

उत्तर

33

जब आप अपने ViewPager प्रारंभ निम्नलिखित जोड़ें,

mPager.setOffscreenPageLimit(NUM_ITEMS-1); 

आपके मामले में, यह (1 को ऑफ स्क्रीन पृष्ठों की संख्या सेट हो जाएगा यानी यह अतिरिक्त ऑफ-स्क्रीन पेज को स्मृति में रखेगा जब अन्य पृष्ठ वर्तमान में फ़ोकस में है)। यह आपके ViewPager को सभी Fragment एस को ध्यान में रखेगा, भले ही वे फोकस में न हों।

+0

जो एक और मामूली प्रदर्शन मुद्दा तय करता था, मैं आपको धन्यवाद देता था! लेकिन यह तब भी दुर्घटनाग्रस्त हो जाता है जब यह टुकड़ा एक ही शून्य सूचक के साथ दिखाया जाता है .. – edthethird

+0

वास्तव में, जो मूल समस्या को हल करता है। मुझे setVisibilty (View.gone) को और कॉल करने की आवश्यकता नहीं है। अजीब, लेकिन धन्यवाद!बस स्पष्ट करने के लिए - SurfaceView ठीक से पेजिंग नहीं कर रहा था, जब भी मैं स्वाइप करता था तब भी यह सभी पृष्ठों पर बना रहता था। – edthethird

+0

यह अजीब बात है क्योंकि v4 में 'setOffscreenPageLimit' डिफ़ॉल्ट रूप से 1 (और NUM_ITEMS - 1 बराबर 1) होगा, लेकिन मुझे खुशी है कि आपकी समस्या हल हो गई है। – louielouie

4

मैंने आपके कोड की जांच की और मुझे लगता है कि समस्या यह है कि onPageScrolled में, आप getItem पर कॉल कर रहे हैं। यह कार्यान्वयन (जो वास्तव में वेब पर इसके अधिकांश कार्यान्वयन की तरह है) प्रत्येक बार एक नया उदाहरण देता है। हालांकि, मैंने देखा है कि अधिकांश उदाहरण getItem पर कॉल नहीं करते हैं, इसलिए यह आमतौर पर ठीक है।

आपके मामले में, मैं lazily पकड़ होगा getItem में टुकड़ा बनाने के लिए: अगर यह उस स्थिति के लिए मौजूद नहीं है, तो बनाने यह, और फिर एक ArrayList या कुछ अन्य संग्रह में यह पर लटका, लेकिन अगर यह पहले से मौजूद है , बस इसे उस संग्रह से वापस कर दें।

अन्यथा, आप एक खंड उदाहरण ए बनाते हैं, फिर किसी अन्य खंड उदाहरण बी पर स्क्रॉल करें। आप कुछ दृश्यों को साफ करने के लिए खंड उदाहरण ए को बताने का प्रयास करते हैं, लेकिन आप ऐसा करने के लिए एक नया खंड उदाहरण सी बताते हैं। इसे अभी तक अपने विचारों को स्थापित करने का मौका नहीं मिला है, इसलिए आपको चार्ट के लिए शून्य सूचक मिल रहा है।

+0

ओह यह एक अच्छा मुद्दा है। मुझे यह कार्यान्वयन किसी Google नमूने से कहीं मिला है, लेकिन मैं टुकड़ों को बनाए रखने के लिए किसी सरणी या कुछ को कार्यान्वित करने की जांच करूंगा। धन्यवाद! – edthethird

संबंधित मुद्दे