2011-02-06 8 views
15

मैं एक कस्टम दृश्य लिख रहा हूं जो सीधे android.view.View बढ़ाता है। यदि मैं फ़ील्ड mScrollX या mScrollY तक पहुंचने का प्रयास करता हूं, तो मुझे एक त्रुटि दिखाई देती है कि फ़ील्ड "हल नहीं किया जा सकता है या कोई फ़ील्ड नहीं है।" source code for android.view.View में mScrollX, mScrollY, और समान चर घोषित protected है। यह कैसे है कि मेरा सीधा उप-वर्ग अपने मूल वर्ग के संरक्षित क्षेत्रों तक नहीं पहुंच सकता है? (ScrollView जैसी कक्षाएं स्पष्ट रूप से कर सकती हैं।)संरक्षित फ़ील्ड उपclasses के लिए दृश्यमान नहीं हैं

पीएस मुझे एहसास है कि मैं getScrollX() पर कॉल कर सकता हूं, लेकिन मैं इन क्षेत्रों को अपडेट करना चाहता हूं; कॉलिंग setScroll() पर साइड इफेक्ट्स हैं जो मैं नहीं चाहता हूं।

+0

अजीब, उप-वर्ग, यहां तक ​​कि अन्य पैकेजों में भी, अपने सुपरक्लास के संरक्षित चर का उपयोग कर सकते हैं। मुझे लगता है कि आप गलत संस्करण का उपयोग कर रहे हैं। क्या आप अपना कुछ कोड दिखा सकते हैं? –

+0

व्यवहार की पुष्टि की। –

उत्तर

20

ऐसा इसलिए है क्योंकि वे एंड्रॉइड एसडीके का हिस्सा नहीं हैं।

/** 
* The offset, in pixels, by which the content of this view is scrolled 
* horizontally. 
* {@hide} 
*/ 
@ViewDebug.ExportedProperty(category = "scrolling") 
protected int mScrollX; 

आप @hide एनोटेशन देखेंगे:

यहाँ mScrollX के लिए स्रोत कोड है। इसका मतलब है कि यह एंड्रॉइड एसडीके का हिस्सा नहीं है। एंड्रॉइड एसडीके बनाने वाली बिल्ड प्रक्रिया का हिस्सा android.view.View के स्टब संस्करण में इस डेटा सदस्य को शामिल नहीं करेगा जो android.jar फ़ाइल में है जिसे आप संकलित कर रहे हैं।

@hide एनोटेशन उन चीजों के लिए उपयोग किया जाता है जो आंतरिक उद्देश्यों के लिए सार्वजनिक या संरक्षित होने की आवश्यकता होती है लेकिन कुछ नहीं माना जाता है कि एसडीके डेवलपर्स का उपयोग किया जाना चाहिए।

कृपया जो भी समस्या आप अनुभव कर रहे हैं उसके लिए अन्य समाधान ढूंढें।

+9

हम्म, दिलचस्प! तो तर्क को स्पष्ट करने के लिए: "उचित encapsulation को हल करने के लिए हमें परेशान नहीं किया जा सका, इसलिए हमने भाषा को तोड़ दिया।" ... –

+0

मैंने '{@hide} 'टैग देखा था। मुझे लगता है कि यही कारण था कि 'mScrollX' जावा डॉक्स में दिखाई नहीं दे रहा था (जैसे [प्रस्तावित' @ बहिष्कृत 'टैग] (http://java.sun.com/j2se/javadoc/proposed-tags.html), जो' @ hide')। मुझे एहसास नहीं हुआ कि एसडीके एपीआई का एक स्टब संस्करण था। –

+0

एक बात जिसे मैं समझ नहीं पा रहा हूं ** ** ** ** की संरक्षित चर ** स्क्रॉलव्यू ** कक्षा में एक्सेस की गई है। यह कैसे संभव है ? पदानुक्रम है - स्क्रॉलव्यू विस्तारित करता है FramLayout व्यूग्रुप व्यू व्यय बढ़ाता है। तो, व्यू क्लास के संरक्षित चर को केवल ViewGroup में ही पहुंचा जाना चाहिए। –

5

यह बहुत सीधी आगे है: इन चर के ऊपर @ हाइड एनोटेशन देखें। यह एक एंड्रॉइड-विशिष्ट एनोटेशन है जो सार्वजनिक एसडीके से फ़ील्ड/विधियों को छुपाता है। यही कारण है कि आप उन्हें सीधे नहीं पहुंच सकते हैं।

Romain Guy mentioned it in इस पोस्ट को।

+0

जो परेशान है। ओपन सोर्स का क्या मतलब है? इसलिए लोग स्रोत पढ़ सकते हैं और समझ सकते हैं कि क्या हो रहा है। लेकिन यहां जारी स्रोत एक नकली है? उत्पादन में इस्तेमाल नहीं किया जाता है? यह भी स्वीकार्य है, * यदि यह पारदर्शी है *।मुझे परवाह नहीं है कि जेडीके स्रोत * वास्तविक * एक है, लेकिन मुझे पढ़ने वाली कोई भी जानकारी वास्तविक प्रणाली में सच होनी चाहिए। – irreputable

+0

आपको ओपन-सोर्स के अर्थ को समझना होगा। सबसे पहले, आप सीधे स्रोत से अपना खुद का एंड्रॉइड संस्करण बना सकते हैं, आप जो भी संशोधन चाहते हैं उसे करें, और छुपाएं या नहीं, हर विधि या फ़ील्ड का उपयोग करें। यही फोन निर्माता करते हैं और कुछ कस्टम रोम समुदाय में पकाते हैं। डेवलपर्स एंड्रॉइड के एक और पहलू से ओपन-सोर्स होने का लाभ उठा सकते हैं, और यह स्रोत के माध्यम से जा रहा है और समझता है कि दृश्यों के पीछे चीजें कैसे काम करती हैं, मेरे लिए यह दस्तावेज के रूप में भी महत्वपूर्ण है। – Lior

+2

तथ्य यह है कि कुछ फ़ील्ड या विधियां छिपी हुई हैं आमतौर पर निम्नलिखित में से एक है: 1. वे एसडीके की भावी रिलीज में बदल सकते हैं, इसलिए वे ऐप-असंगतता का मौका कम करना चाहते हैं, आपको बचा सकते हैं, डेवलपर बहुत सारे अपने ऐप्स को बनाए रखने का काम, और 2. इन क्षेत्रों का उपयोग सीधे आपके मामले में करना उचित तरीके से हस्तक्षेप कर सकता है कि एपीआई के आंतरिक रूप से कैसे काम करता है। – Lior

4

आप प्रतिबिंब के साथ क्षेत्रों को सेट कर सकें:

import java.lang.reflect.Field; 

// ... 

try { 
    Field scrollXField = View.class.getDeclaredField("mScrollX"); 
    scrollXField.setAccessible(true); 
    scrollXField.set(this, myNewValue); 
} catch (Exception ex) { 
    // oops, android changed the implementation. sucks to be you. 
} 

हालांकि, ध्यान दें कि आप गैर-दस्तावेजी और असमर्थित व्यवहार पर भरोसा कर रहे हैं जब आप ऐसा करते हैं, और इसलिए आप चीजों को तोड़ने के लिए तैयार किया जाना चाहिए कुछ उपकरणों या भविष्य के संस्करणों में।

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