6

मैं एक्सएमएल के माध्यम से एक भाई नियंत्रण का संदर्भ देने की कोशिश कर रहा हूं।मुद्रास्फीति के दौरान किसी दूसरे से एक नियंत्रण का संदर्भ कैसे लें?

MyTextView से एक आईडी संदर्भ के लिए एक विशेषता की घोषणा करने के लिए:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <declare-styleable name="MyTextView"> 
     <attr name="valueTextViewId" format="reference" /> 
    </declare-styleable> 
</resources> 

fragment_example.xml - कस्टम विशेषता का उपयोग कैसे करें:

<!-- Declare a "Title" text view that references a "Value" --> 
<com.example.MyTextView 
    android:id="@+id/foo" 
    example:valueTextViewId="@id/bar" 
    ... /> 

<!-- Depending on the "text" attribute of this "Value" textview --> 
<!-- Do something within "Title" textview --> 
<com.example.MyTextView android:id="@+id/bar" /> 

MyFragment.java - बढ़ाना नियंत्रण

इस उदाहरण में

public TextView(Context context, AttributeSet attrs) { 
    super(context, attrs); 

    TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.MyTextView); 
    int refId = a.getResourceId(R.styleable.MyTextView_valueTextViewId); 

    // Updated to use context 
    if (refId > -1 && context instanceof Activity) { 
     Activity a = (Activity)context; 
     View v = a.findViewById(refId); 

     // THE PROBLEM: v is null 
     if (v != null) { 
      // In my case, I want to check if the "Value" textview 
      // is empty. If so I will set "this" textColor to gray 
     } 
    } 
} 

v हमेशा null है: -

MyTextView वर्ग निर्माता मुद्रास्फीति के दौरान संदर्भित TextView के साथ कुछ करना। मुझे लगता है क्योंकि लेआउट मुद्रास्फीति के दौरान, नियंत्रण अभी तक जोड़े नहीं गए हैं। ध्यान देने योग्य एक और बात यह है कि यह Fragment में है, इसलिए हो सकता है कि मैं मूल गतिविधि में दृश्य नहीं ढूंढ सकूं।

क्या इस तरह से किसी अन्य से नियंत्रण का संदर्भ देना संभव है?

उत्तर

2

क्या इस तरह से किसी अन्य से नियंत्रण का संदर्भ देना संभव है?

View से View से संदर्भित करना संभव है।

लेकिन के कन्स्ट्रक्टर में संपत्ति जांच करने के लिए सलाह नहीं दी जाती है।
कोई गारंटी नहीं है कि किसी विशेष View को View inflation के दौरान किसी भी अन्य से पहले तुरंत चालू किया गया है।

इन दो लेआउट की तुलना करें:
first_layout.xml

<com.example.MyTextView 
    ... 
    android:id="@+id/foo" 
    example:valueTextViewId="@+id/bar" /> 

<com.example.MyTextView 
    ... 
    android:id="@+id/bar" /> 

second_layout.xml

<com.example.MyTextView 
    ... 
    android:id="@+id/bar" /> 

<com.example.MyTextView 
    ... 
    android:id="@+id/foo" 
    example:valueTextViewId="@+id/bar" /> 

इस उदाहरण में, यह स्पष्ट है कि संपत्ति निर्माता से जाँच इन लेआउट में से एक में काम नहीं करेगा।

मैं मानता हूँ कि यह एक View भीतर एक और View के संदर्भ में स्टोर करने के लिए संभव है:

public MyTextView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyTextView); 
    mReferenceId = a.getResourceId(R.styleable.MyTextView_valueTextViewId); 
    ... 
} 

private int mReferenceId; 

public View getReferenceViewFromActivity() { 
    if (getContext() instanceof Activity) { 
     return ((Activity)getContext()).findViewById(mReferenceId); 
    return null; 
} 

public View getReferenceView(View view) { 
    return view.findViewById(mReferenceId); 
} 

लेकिन आप के भीतर जाँच किसी भी और सभी संपत्ति निश्चित रूप से करना चाहिए Activity या Fragment:

@Override 
public void onViewCreated(View view, Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 
    MyTextView myTextView = (MyTextView)view.findViewById(R.id.foo); 
    MyReferenceView refView = (MyReferenceView)myTextView.getReferenceView(view); 
    // 
    // do property checking 
    // 
} 
1

यदि बार की आईडी के साथ एक बार बार बार आईडी के साथ एक टेक्स्टव्यू उपलब्ध है, तो आप ऐसा कुछ कर सकते हैं।

<com.example.MyTextView 
    android:id="@+id/foo" 
    ... 
    android:tag="bar" /> 

<com.example.MyTextView android:id="@+id/bar" /> 

और

public TextView(Context context, AttributeSet attrs) { 
    super(context, attrs); 

     int barId = getResources().getIdentifier(getTag(), "id", packageName); 
     TextView bar = mActivity.findViewById(barId); 

    if (bar.getText() == "") { 
     // Gray out this "title" textview 
     setColor(android.R.color.gray); 
    } 

    // maybe set a text change listener to bar to make it future-proof 
} 

मैं सिर्फ ताकि आप न एक नई विशेषता बनाने की जरूरत अपने MyTextView पर एक टैग के रूप में आईडी से होकर गुजरेगा।

+0

यह दिलचस्प और शुरुआत है। हालांकि जब मैं 'लेआउट इन्फ्लूटर' का उपयोग कर रहा हूं, तो मेरे पास 'mactivity' को पार करने की क्षमता नहीं है। यह मुझे आश्चर्यचकित करता है कि क्या सीटीआर में संदर्भ विशेषता गतिविधि है ... –

+1

यह हो सकता है। 'if (संदर्भ उदाहरण गतिविधि) के माध्यम से जांचें और फिर इसे '((गतिविधि) संदर्भ डालें)' – r2DoesInc

+0

शायद निर्माता में उस तर्क को न करें। 'SetActivityValue (mActivity)' के लिए MyTextView में एक विधि जोड़ें और फिर गतिविधि को स्पष्ट रूप से सेट करने के बाद, फिर अन्य टेक्स्टव्यू को छिपाने या छेड़छाड़ करने का अपना तर्क करें, हालांकि आप कर सकते हैं। – r2DoesInc

1

कन्स्ट्रक्टर में अपने निजी क्षेत्रों में संदर्भों को सहेजें। अपने मामले में, एक निजी क्षेत्र में refId बचाओ। फिर उन्हें onMeasure फ़ंक्शन में उपयोग करें।


मैं आपको सलाह दूंगा कि संदर्भित दृश्य प्राप्त करने के आपके दृष्टिकोण का उपयोग न करें। यदि आप सामान्य मामलों को देखते हैं, जैसे रिलेटिव व्यू के बच्चों के layout_toLeftOf, तो आप देखेंगे कि आईडी हमेशा सापेक्ष दृश्य के बच्चों में से एक है और इसलिए, वर्तमान दृश्य का भाई है। उस स्थिति में, getParent() का उपयोग करके, माता-पिता को प्राप्त करके दृश्य प्राप्त करना आसान है, इसे 0Gका उपयोग करके, ViewGroup (आवश्यक नहीं) पर कास्टिंग, और संदर्भ के साथ दृश्य ढूंढना। यदि आप इस तरह की सीमा (आईडी एक भाई होना चाहिए) कर सकते हैं, तो आप शायद इस निर्भरता से इस निर्भरता से छुटकारा पा सकते हैं, जो अंततः आपके विचार को अनुपयोगी बना देगा। आप शायद अपनी खुद की विशेषता का उपयोग करने के बजाय setBla() का उपयोग करके दृश्य को सेट करना बेहतर कर सकते हैं (यदि इस सेटर को नहीं कहा गया था तो शायद अपने ऑनमेजर में रनटाइम त्रुटि फेंक दें)।

1

जहां तक ​​मुझे पता है कि Activity's लेआउट onCreateView() विधि में बनाया गया है, तो कोई गारंटी नहीं है।

इसके बजाय आप इस तरीके का प्रयास कर सकते हैं: जब गतिविधि निर्माण समाप्त हो गया है

@Override 
public void onActivityCreated(Bundle savedInstanceState){ 
    mView.customMethodToSetTextColor(...) 
} 

onActivityCreated() कहा जाता है, और Fragmentlifecycle में onCreateView() के बाद।

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

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