विलय के साथ काम करने वाले RelativeLayout कैसे प्राप्त करें और शामिल करें?


114

मैं कुछ दिनों से कोशिश कर रहा हूं कि अपने स्तर को और अधिक कुशल बनाने के लिए नेस्टेड के कई स्तरों का उपयोग करके परिवर्तित कर दिया LinearLayoutsगया है RelativeLayoutऔर कुछ समस्याओं का सामना करना पड़ा है, जिनके लिए मुझे वर्कअराउंड नहीं मिल रहा है ...

मैंने एंड्रॉइड शुरुआती समूह और इस साइट को खोजा है और मुझे ऐसा कुछ भी नहीं मिला है जो समस्या को हल करने में मेरी मदद करे।

मैंने एक ब्लॉग पर पढ़ा है कि आप मर्ज के साथ लेआउट को जोड़ सकते हैं और टैग शामिल कर सकते हैं। तो मेरे पास जो है वह एक मुख्य RelativeLayoutतत्व के साथ एक मुख्य लेआउट फ़ाइल है। उसके अंदर मेरे पास 5 टैग शामिल हैं जो 5 अलग-अलग xml लेआउट फ़ाइलों को संदर्भित करते हैं, जिनमें से प्रत्येक में रूट के लिए एक मर्ज तत्व है (मेरी मर्ज फ़ाइलों में से सभी में आईडी के अलावा समान हैं)।

मैं दो समस्याओं में भाग रहा हूं, जिन्हें मैं अपने लेआउट कोड के सरलीकृत संस्करण को पोस्ट करने के बाद समझाऊंगा:

नमूना मुख्य लेआउट फ़ाइल:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/translucent_gray" >

    <include 
        android:id="@+id/running_gallery_layout_id"
        layout="@layout/running_gallery_layout" />

    <include 
        android:id="@+id/recent_gallery_layout_id" 
        layout="@layout/recent_gallery_layout"
        android:layout_below="@id/running_gallery_layout_id" />

    <include
        android:id="@+id/service_gallery_layout_id"
        layout="@layout/service_gallery_layout"
        android:layout_below="@id/recent_gallery_layout_id" />

    <include
        android:id="@+id/process_gallery_layout_id"
        layout="@layout/process_gallery_layout"
        android:layout_below="@id/service_gallery_layout_id" />

</RelativeLayout>

नमूना में मर्ज फ़ाइल शामिल है:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <TextView 
        style="@style/TitleText"
        android:id="@+id/service_gallery_title_text_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="left"
        android:text="@string/service_title" />

    <Gallery
        android:id="@+id/service_gallery_id"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_below="@id/service_gallery_title_text_id" />

    <TextView 
        style="@style/SubTitleText"
        android:id="@+id/service_gallery_current_text_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/service_gallery_title_text_id"
        android:layout_above="@id/service_gallery_id" />
</merge>

मैं दो समस्याओं में भाग रहा हूं:

1) android:layout_*शामिल टैग में उपयोग किए जाने पर विशेषताओं को अनदेखा किया जाता है और सभी मर्ज किए गए लेआउट एक दूसरे के शीर्ष पर प्रदर्शित होते हैं। इस पोस्ट के अनुसार ( http://developer.android.com/resources/articles/layout-tricks-reuse.html ) "किसी भी android:layout_*विशेषता का उपयोग <include />टैग के साथ किया जा सकता है "

2) चूंकि मुझे यह काम नहीं मिला, इसलिए मैंने प्रत्येक मर्ज लेआउट फ़ाइल में android:layout_belowपहले TextViewआइटम में एक विशेषता जोड़ने की कोशिश करने का फैसला किया , जिसका अर्थ है कि प्रत्येक मर्ज फ़ाइल किसी अन्य मर्ज लेआउट फ़ाइल से एक आईडी संदर्भित कर रही होगी ... अधिकांश भाग के लिए वास्तव में काम किया और मेरा लेआउट ठीक लग रहा है। हालाँकि, मुझे एक android:layout_belowविशेषता पर यह कहते हुए एक त्रुटि मिलती है कि यह मेरे द्वारा निर्दिष्ट आईडी को नहीं ढूंढ सकती है ... मेरे पास यह सुनिश्चित करने के लिए आईडी को डबल और ट्रिपल चेक किया गया है कि वे सही थे। सबसे अजीब हिस्सा यह है कि मैंने AutoFillपहली बार में विशेषता में आईडी डालने के लिए सुविधा का उपयोग किया ।

अगर किसी के पास कोई सुझाव या वर्कअराउंड है तो मैं उन्हें आज़माने से ज्यादा खुश रहूंगा। इसके अलावा, अगर कोई भी मेरे लिए 5 के बजाय सिर्फ एक मर्ज xml लेआउट फाइल करने के लिए एक तरीका सोच सकता है जो बहुत सराहना की जाएगी। मुझे ऐसा करने का कोई तरीका नहीं मिला क्योंकि मुझे रन-वे पर मर्ज लेआउट फ़ाइलों में प्रत्येक आइटम तक पहुंचने की आवश्यकता है ...

जवाबों:


214

इसमें शामिल टैग के साथ एक समस्या है। जाँच करें: https://issuetracker.google.com/issues/36908001

इसे ठीक करने के लिए, सुनिश्चित करें कि आप BOTH को अधिलेखित कर दें layout_widthऔर layout_heightजब शामिल हों, अन्यथा सबकुछ अनदेखा कर दिया जाएगा।


15
यह स्वीकार किए जाते हैं की तुलना में एक बेहतर समाधान है, क्योंकि यह अन्यथा अति सुंदर लेआउट ऑब्जेक्ट बनाने से बचता है। इसके अलावा, यह बेकार है कि कैसे Android देवों के अनुसार यह एक ठीक है।
mikołak

4
यह वास्तव में आसान है, कम हार्डकोड, और पैकिंग की तुलना में अधिक अनुकूलित समाधान <शामिल /> दूसरे लेआउट में। सोचिये अगर आप सूचियों के साथ काम करेंगे तो आप क्या करेंगे।
टेओरीटिक

2
यह स्वीकृत उत्तर की तुलना में बहुत बेहतर है। बहुत धन्यवाद! और ... c'mon google, इस मुद्दे को पहले से ही ठीक कर लें, यह बी.एस. :)
फेलिप कैलदास

2
@JeffAxelrod, LayoutInflater स्रोत कोड दिखाता है कि रूट तत्व मर्ज होने पर दुर्भाग्य से आईडी, दृश्यता और लेआउट_ * ओवरराइडिंग टैग लागू नहीं होते हैं। जैसा कि आपके पास xml रूट के रूप में एक दृश्य नहीं हो सकता है, हमारे पास वहां एक अतिरिक्त व्यूग्रुप होना चाहिए ...
राफेल नोब्रे

13
यह सिर्फ मेरे लिए काम नहीं किया। मेरे पास दोनों हैं layout_widthऔर मैं layout_heightअपने घर पर बस गया हूं <include>। मैंने भी कोशिश की layout_widthऔर layout_heightअपनी <merge>सफलता के बिना। मैं क्या खो रहा हूँ ?
dum4ll3

33

नीचे दिए गए अत्यधिक मत वाले उत्तर को देखें। मेरा बहुत पुराना है


मैं जस्टिन द्वारा उठाए गए एक मुद्दे को संबोधित कर सकता हूं : किसी सूची की स्थिति का प्रबंधन करने के लिए RelativeLayout की अक्षमता (कम से कम इस साधारण मामले में, 1.6 एमुलेटर पर)

CommonsWare सुझाव देता है कि इसमें एक अनोखे माता-पिता के कंटेनर को शामिल करना शामिल है, लेकिन जस्टिन के शामिल किए गए दृश्यों के लिए अलग-अलग नाम से संबोधित करने और स्कूप करने में सहायता करने के लिए ऐसा करता है।

प्रत्येक के पास एक अद्वितीय मूल कंटेनर होना चाहिए, और आप गतिविधि पर देखने के बजाय उस कंटेनर (ViewGroup) पर findViewById () कहेंगे।

वास्तव में, आप भी इसे करने के लिए RelativeLayout पाने के लिए उम्मीद के मुताबिक व्यवहार करना चाहिए :

यह काम करता है ( पाद अच्छी तरह से तैनात है):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent">
    <include android:id="@+id/header" layout="@layout/header"
        android:layout_alignParentTop="true" />
    <WebView android:id="@+id/webView" android:layout_below="@id/header"
        android:background="#77CC0000" android:layout_height="wrap_content"
        android:layout_width="fill_parent" android:focusable="false" />
    <LinearLayout android:layout_alignParentBottom="true"
        android:layout_height="wrap_content" android:layout_width="fill_parent">
        <include android:id="@+id/footer" layout="@layout/footer" />
    </LinearLayout>
</RelativeLayout>

ऐसा नहीं होता ( पाद स्क्रीन के ऊपर तैर रहा है):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent">
    <include android:id="@+id/header" layout="@layout/header"
        android:layout_alignParentTop="true" />
    <WebView android:id="@+id/webView" android:layout_below="@id/header"
        android:background="#77CC0000" android:layout_height="wrap_content"
        android:layout_width="fill_parent" android:focusable="false" />
    <include android:id="@+id/footer" layout="@layout/footer"
        android:layout_alignParentBottom="true" />
</RelativeLayout>

नंगे पाद लेख में माता-पिता के निचले हिस्से को संरेखित नहीं किया जाएगा, आसपास के रैखिकलेआउट के बिना .. मैं इस अपेक्षित व्यवहार को नहीं कहूंगा।

इसके अतिरिक्त, WebView खुद को आईडी द्वारा हेडर के साथ अच्छी तरह से संलग्न करने के लिए प्रकट होता है , लेकिन मेरा मानना ​​है कि यह भ्रम है, क्योंकि यह केवल हेडर के लंबवत से नीचे बह रहा है। मैंने पाद लेख के ठीक ऊपर एक बटन सेट करने का भी प्रयास किया है, लेकिन यह सभी फ्लोटी और गलत है, भी

RelativeLayout में 1.5 में अधिक समस्याएं थीं, लेकिन मुझे अभी भी यह पसंद है :)


2
मैंने इसे 1 से बढ़ा दिया और फिर @Macarse द्वारा टिप्पणी को देखते हुए कम किया, इसे करने का सही तरीका।
जयशिल दवे

कृपया इस भ्रामक उत्तर को दूर करें :(
डैनियल स्मिथ

8

यार, यह पुराना है, लेकिन यह खोजों के शीर्ष पर आता है, इसलिए मैं टिप्पणी करने जा रहा हूं।

मुझे लगता है कि यहाँ ट्रिक यह है कि <merge>टैग के साथ संयुक्त <include>टैग अनिवार्य रूप से उस स्तर पर किसी भी "पैरेंट" व्यू ग्रुप को हटा देता है। तो फिर, आप वास्तव में किसी और को "लेआउट_बेलो" किससे पूछ रहे हैं? कोई नहीं। उस स्तर पर कोई नजरिया नहीं है।

<merge>टैग बच्चे विचारों लेता है और उन्हें सही की मूल में पॉप <include>टैग। इसलिए आपको उन बच्चों से पूछना चाहिए, जिनमें आप अपने अनुसार लंगर डाल रहे हैं।


4

RelativeLayout पर काम करने की स्थिति के लिए आपको शामिल फ़ाइल में लेआउट_ * पैरामीटर सेट करने की आवश्यकता है, मुख्य लेआउट फ़ाइल में नहीं। उस तरफ

main_layout.xml

<RelativeLayout
  android:id="@+id/header"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content">
   ....
</RelativeLayout>

<RelativeLayout 
  android:id="@+id/footer"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:layout_alignParentBottom="true">
    .....
</RelativeLayout>

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

content_layout.xml

<merge xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
    android:id="@+id/content"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_above="@id/footer"
    android:layout_below="@id/header" >

    ....
</RelativeLayout>
</merge>

यह स्पष्ट रूप से नहीं है कि हम डेवलपर्स क्या चाहते हैं, लेकिन यह एकमात्र समाधान है जो मैंने xml को डुप्लिकेट करने से बचने के लिए पाया है


1
कोई उभार क्यों नहीं? इसने मेरे लिए काम किया। मैं एक वस्तु में चिपके हुए मापदंडों के साथ प्यार में नहीं हूं, जिसे एक लेआउट में शामिल किया जा सकता है, जिसकी उन्हें आवश्यकता नहीं है, लेकिन अगर यह एक LinLay है, तो ऐसा लगता है कि RelLay के लेआउट_ * को केवल अनदेखा किया जा रहा है। क्या मैं कुछ भूल रहा हूँ?
QED

1

एंड्रॉइड: लेआउट_ * विशेषताओं को अनदेखा किया जाता है जब शामिल टैग में उपयोग किया जाता है और सभी मर्ज किए गए लेआउट एक-दूसरे के शीर्ष पर प्रदर्शित होते हैं।

मेरा अनुमान है कि आप लेआउट नियमों से, तत्वों android:idपर परिभाषित विशेषताओं को संदर्भित नहीं कर सकते हैं <include>, केवल "वास्तविक" विगेट्स और कंटेनरों पर हैं।

इसके अलावा, अगर कोई भी मेरे लिए 5 के बजाय सिर्फ एक मर्ज xml लेआउट फाइल करने के लिए एक तरीका सोच सकता है जो बहुत सराहना की जाएगी।

सरल: उन सभी को एक फ़ाइल में रखें।

मुझे ऐसा करने का कोई तरीका नहीं मिला क्योंकि मुझे रनटाइम में मर्ज लेआउट फ़ाइलों में प्रत्येक आइटम तक पहुंचने की आवश्यकता है

चाहे आपके पास एक <include>तत्व हो या 1,000, सभी सामग्री रनटाइम पर सुलभ होनी चाहिए। एक अपवाद यह है कि यदि आपके पास डुप्लिकेट android:idविशेषताएँ हैं - तो आपको findViewById()सही कॉल करने के लिए अपने कॉल को ठीक से स्कोप करने की आवश्यकता होगी, ठीक उसी तरह जैसे आपको एक सूची दृश्य पंक्ति से विजेट प्राप्त करना है।

यदि आप एक नमूना परियोजना बना सकते हैं जो 2+ मर्ज फ़ाइलों का उपयोग करती है जहां आप प्रदर्शित कर सकते हैं कि सामग्री रनटाइम पर पहुंच योग्य नहीं है, तो मुझे बताएं।


1
मैं उन सभी को एक बड़े पैमाने पर लेआउट फ़ाइल में नहीं डालना चाहता क्योंकि वह लंबे समय में प्रबंधन करना कठिन है ... यही कारण है कि मैंने एक मर्ज फ़ाइल के साथ एक मुख्य xml होने की संभावना के लिए कहा ... क्योंकि अभी मेरे पास एक मर्ज तत्व के साथ 5 फाइलें हैं जो रूट के समान हैं जिनमें सटीक एक ही लेआउट है सिवाय इसके कि आईडी अलग हैं। मैं इसे इस तरह से करता हूं ताकि मैं उन्हें रनटाइम पर एक्सेस कर सकूं। ऐसा लगता है कि मेरे findViewById () कॉल में वह है जो मैं करना चाहता हूं। आप उस कॉल को कैसे स्कोप करते हैं ताकि आप एक ही लेआउट फ़ाइल को कई बार शामिल कर सकें और फिर भी रनटाइम के सभी घटकों को एक्सेस करने में सक्षम हों?
जस्टिन

1
जवाब देने के लिए धन्यवाद। मैं उस पर गौर करूंगा। इस बीच, (और शायद मैं यहां अपनी अज्ञानता को उजागर कर रहा हूं) प्रत्येक को एक मूल कंटेनर में टैग शामिल नहीं करना होगा जो RelativeLayout का उपयोग करने के उद्देश्य को पराजित करता है? RelativeLayout के सभी प्रचार नेस्टेड लेआउट से बचने के लिए है ...
जस्टिन

3
एकमात्र कारण मैंने इसके बारे में पूछा था कि अंतरिक्ष को बचाने के लिए और एक अच्छे डिजाइन के साथ आने के लिए ... मैंने यहां लेआउट पुन: प्रयोज्य के बारे में पढ़ा: developer.android.com/resources/articles/… और सोचा कि यह अच्छा लग रहा था। जब मैंने इसे लागू करने की कोशिश की तो मैं कुछ समस्याओं में भाग गया। वर्तमान में मेरे पास 5 लेआउट हैं जो अनिवार्य रूप से उनमें आईडी के अलावा दोहराए गए हैं ... इसलिए मुझे लगा कि लेआउट पुन: प्रयोज्यता एक अच्छा उम्मीदवार होगा। शायद मैं यहाँ कुछ याद कर रहा हूँ, लेकिन ऐसा लगता है जैसे RelativeLayout यह सब होने के लिए नहीं है ...
जस्टिन

1
वाह ... बहुत अविश्वसनीय रूप से सहायक होने के लिए धन्यवाद । आम तौर पर आपकी प्रतिक्रियाएँ बहुत मददगार होती हैं, इसलिए मुझे नहीं पता कि आप बस एक बुरा दिन है या क्या कर रहे हैं, लेकिन मैं बस RelativeLayout के पीछे की अवधारणाओं की बेहतर समझ हासिल करने की कोशिश कर रहा था, जिसमें टैग और मर्ज टैग शामिल हैं, जिन लेखों को मैंने पढ़ा है और जिस लेआउट को मैं प्राप्त करना चाहता हूं, उसका उचित समाधान खोजने की कोशिश कर रहा हूं।
जस्टिन

1
"और, सही पुन: उपयोग के लिए, कस्टम व्यू क्लास ट्रम्प बनाने में शामिल हैं" सहमत। मैं बस यह नहीं करना चाहता था कि अगर मूल लेआउट का उपयोग करने का एक आसान तरीका था ... "आपने एक 'टॉड - मैथुन किया - कृपया आश्चर्यचकित न हों जब लोग उस पर प्रतिक्रिया करते हैं। और जबकि मेरी सबसे हालिया टिप्पणी है। स्नार्क पर उच्च, अंक अभी भी मान्य हैं "मैंने एक 'टोड को कॉपी किया क्योंकि मुझे लगा कि आपने अपनी प्रतिक्रियाओं में किया है। "सूची में पंक्तियों पर स्विच करना बेहतर हो सकता है।" Listview मेरे ऐप के लुक के साथ काम नहीं करेगा। बाजार में मेरा ऐप AppSwipe है! अगर आप जानना चाहते हैं कि मैं क्या कर रहा हूँ ...
जस्टिन


0

मेरे मामले में, जिस लेआउट को मैं शामिल करना चाह रहा था, वह <mergeटैग के साथ शुरू होता है । जब मैंने इसे एक लेआउट में बदल दिया, तो कहना<RelativeLayout यह काम किया। नीचे दृष्टांत है।

काम कर रहे

<RelativeLayout xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    tools:showIn="@layout/activity_home">

काम नहीं कर रहा

<merge xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    tools:showIn="@layout/activity_home">

यह एक और नेस्टेड परत बनाएगा जो इष्टतम समाधान नहीं है
सिल्विया एच

0

मुझे भी यही समस्या थी और परिभाषित भी layout_widthऔरlayout_height यह काम नहीं किया। समस्या यह थी कि जिस लेआउट में मैं शामिल था, उसमें टैग थे और उन्हें हटाने के बाद, सब कुछ एक आकर्षण की तरह काम करता था। मुझे लगता है कि मर्ज एक लेआउट टैग नहीं है और इस वजह से, यह स्थिति और आकार के मापदंडों को प्राप्त नहीं कर सकता है। चूंकि आप जो कुछ भी परिभाषित करते हैं, वह आंतरिक मूल लेआउट में स्थानांतरित हो जाता है, सेटिंग्स बस फेंक दी गईं।

TL: DR: बस टैग हटा दें, xmlns परिभाषाओं को एक वास्तविक लेआउट व्यूअर में ले जाएं और आपको अच्छा होना चाहिए।

इससे पहले:

<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <...ui.component.BorderCardView
        android:layout_width="112dp"
        android:layout_height="32dp"
        app:cardCornerRadius="4dp"
        app:cardUseCompatPadding="true">

        <ImageView
            android:layout_width="16dp"
            android:layout_height="16dp"
            android:src="@drawable/ic_logout"
            android:tint="@color/divider" />

    </...ui.component.BorderCardView>
</merge>

काम कर रहे:

<...ui.component.BorderCardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="112dp"
    android:layout_height="32dp"
    app:cardCornerRadius="4dp"
    app:cardUseCompatPadding="true">

    <ImageView
        android:layout_width="16dp"
        android:layout_height="16dp"
        android:src="@drawable/ic_logout"
        android:tint="@color/divider" />

</...ui.component.BorderCardView>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.