तो मेरे पास इस गतिविधि के लिए अलग-अलग लेआउट हैं।

और मेरे पास अलग-अलग वर्ग हैं जो प्रत्येक एक लेआउट के साथ खुलते हैं और अपनी बात करते हैं।

मैं इन कक्षाओं को @Inject के माध्यम से गतिविधि में इंजेक्ट करता हूं। यह सब बिना किसी समस्या के है।

लेकिन जब मैं सक्रिय लेआउट में मौजूद नियंत्रणों में से किसी एक पर @InjectView का उपयोग करने का प्रयास करता हूं तो मुझे एक त्रुटि मिलती है।

11-02 19:17:31.086: ERROR/AndroidRuntime(1326): इसके कारण: java.lang.NullPointerException: क्लास में शून्य मान इंजेक्ट नहीं कर सकता be.baes.notes.View.EditNoteImpl.saveButton जब फ़ील्ड @Nullable नहीं है

यह तब कोड होगा।

public class EditNoteImpl implements EditNote {
    @Inject CancelEditNoteClickListener cancelEditNoteClickListener;
    @Inject SaveNoteClickListener saveNoteClickListener;
    @Inject Provider<Activity> activity;
    @InjectView(R.id.saveButton) Button saveButton;

    /* (non-Javadoc)
     * @see be.baes.notes.EditNote#activateEditNote()
     */
    @Override
    public void activateEditNote()
    {
        activity.get().setContentView(R.layout.editnote);

        this.saveButton.setOnClickListener(saveNoteClickListener);
    }
}

हालांकि मैं यह कर सकता हूं।

public class EditNoteImpl implements EditNote {
    @Inject CancelEditNoteClickListener cancelEditNoteClickListener;
    @Inject SaveNoteClickListener saveNoteClickListener;
    @Inject Provider<Activity> activity;
    private Button saveButton;

    /* (non-Javadoc)
     * @see be.baes.notes.EditNote#activateEditNote()
     */
    @Override
    public void activateEditNote()
    {
        activity.get().setContentView(R.layout.editnote);
        saveButton = (Button)activity.get().findViewById(R.id.saveButton);

        this.saveButton.setOnClickListener(saveNoteClickListener);
    }
}

क्या ऐसा करने का कोई बेहतर तरीका है?

8
chrissie1 2 नवम्बर 2011, 22:39
क्या कोई कारण है कि बटन @Nullable बनाना एक विकल्प नहीं है?
 – 
Cameron Hotchkies
2 नवम्बर 2011, 22:42
मैंने कोशिश की, लेकिन वह बटन को इंजेक्ट नहीं करता है।
 – 
chrissie1
2 नवम्बर 2011, 22:46
क्या आप रोबोगुइस 2.0 का उपयोग कर रहे हैं? यह 2.0 . में काम हो सकता है
 – 
emmby
3 नवम्बर 2011, 20:49
मैं 1.2 का उपयोग कर रहा था क्योंकि यह स्थिर रिलीज है। मैं 2.0 की कोशिश करूंगा।
 – 
chrissie1
4 नवम्बर 2011, 10:45
रोबोगुइस 2.0 @Nullable को सपोर्ट करता है। यह प्रश्न देखें stackoverflow.com/questions/15200701/…
 – 
v4r
14 मार्च 2014, 20:58

1 उत्तर

सबसे बढ़िया उत्तर

मैंने अभी रोबोगुइस का उपयोग करना शुरू किया है ताकि अधिक अनुभव वाला कोई और बेहतर उत्तर दे सके, लेकिन अब तक मैंने यही पाया है:

  • रोबोगुइस-1.1.2 (वर्तमान स्थिर रिलीज़) में, @InjectView आइटम केवल तभी इंजेक्ट किए जाते हैं जब setContentView() को गतिविधि में पहली बार कहा जाता है। चूंकि आपका कोड सहायक वर्गों से गतिशील रूप से setContentView() कॉल करता है, वहां इंजेक्शन वाली वस्तुओं को सही ढंग से इंजेक्ट नहीं किया जाएगा।

  • रोबोगुइस-2.0b2 (वर्तमान बीटा) में, एकाधिक setContentView() कॉल के लिए समर्थन है और आपका कोड काम करना चाहिए। हालांकि, इंजेक्ट किए गए दृश्य अभी भी संदर्भ गतिविधि (घोषित वर्ग के बजाय) से जुड़े हुए हैं, इसलिए प्रत्येक @InjectView को समान गतिविधि साझा करने वाले सभी सहायक वर्गों में संभावित रूप से @Nullable होने की भी आवश्यकता होगी।

चूंकि यहां समस्या एक ही गतिविधि में एकाधिक लेआउट (और इसलिए एकाधिक setContentView() कॉल) में निहित है, इसलिए आप जो चाहते हैं उसे करने का एक वैकल्पिक तरीका यह है कि इसे निम्नानुसार टाला जाए:

  • कई लेआउट होने के बजाय, सभी लेआउट को पैरेंट फ़्रेमलेआउट में लोड करने के लिए <include/> टैग का उपयोग करके एकल लेआउट का उपयोग करें:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <include layout="@layout/layout1" />

    <include layout="@layout/layout2" />

    <!-- other layouts... -->

</FrameLayout>
  • फिर, setContentView() को कॉल करने के बजाय, एक ऐसी विधि का उपयोग करें जो गतिविधि पर दृश्यमान लेआउट को टॉगल करेगी, कुछ इस तरह:
// instead of: activity.setContentView(R.layout.layout1);
// use: activity.showLayout(R.id.layoutview1);
public void showLayout(int layoutViewId) {
    final View view = findViewById(layoutViewId);
    final ViewGroup root = (ViewGroup) view.getParent();
    for (int i = 0; i < root.getChildCount(); i++) {
        final View v = root.getChildAt(i);
        v.setVisibility(v == view ? View.VISIBLE : View.GONE);
    }
}

उपरोक्त विकल्प को स्थिर और बीटा रोबोगुइस रिलीज़ दोनों के लिए काम करना चाहिए। यहां ट्रेड-ऑफ यह है कि हम हर एक को कई अलग-अलग समय पर लोड करने के बजाय एक ही समय में कई लेआउट लोड कर रहे हैं। ऐसा लगता है कि यह मेरे लिए काफी अच्छा काम करता है (हालांकि यह आपकी आवश्यकताओं के लिए अलग हो सकता है)।

एक बात मुझे ध्यान रखनी चाहिए कि वर्तमान में "RoboGuice 1.1 से 2.0 में अपग्रेड करना" पृष्ठ, निम्नलिखित का उल्लेख किया गया है:

दृश्यों में @InjectView का उपयोग करने की क्षमता (हालांकि आपको RoboGuice.injectMembers() को स्वयं कॉल करना होगा, क्योंकि कोई RoboView बेस क्लास नहीं है और शायद कभी नहीं होगा)।

ऐसा लगता है कि यह आपको व्यू से प्राप्त होने वाली अपनी सहायक कक्षाओं को लागू करने और उनमें @InjectView को बेहतर काम करने की अनुमति देगा (उम्मीद है कि उन्हें @Nullable होने की कोई आवश्यकता नहीं है क्योंकि वे गतिविधि से कम बंधे हुए हैं) . हालाँकि, वर्तमान कोड को देखते हुए, यह सुविधा अभी तक लागू नहीं हुई है (हालाँकि मैं गलत जगह देख सकता था)।

4
Joe 9 नवम्बर 2011, 02:01