अपने माता-पिता के आयामों के आधार पर Android दृश्य कैसे आकार दें


104

मैं इसके मूल लेआउट के आकार के आधार पर किसी दृश्य को कैसे आकार दे सकता हूं। उदाहरण के लिए मेरे पास एक RelativeLayoutपूर्ण स्क्रीन भरता है, और मुझे एक बच्चा दृश्य चाहिए, एक कहो ImageView, पूरी ऊंचाई लेने के लिए, और 1/2 चौड़ाई?

मैं पर सभी अधिभावी की कोशिश की है onMeasure, onLayout, onSizeChanged, आदि और मैं इसे काम करने के लिए नहीं मिल सका ....


ऐसा करना संभव है कि कांस्ट्रेन्थलैयूट का उपयोग करते हुए, इसे देखें: stackoverflow.com/questions/37318228/…
अली नेम

जवाबों:


124

मुझे नहीं पता कि कोई अभी भी इस धागे को पढ़ रहा है या नहीं, लेकिन जेफ का समाधान आपको केवल आधा ही मिलेगा (थोरा सचमुच)। उसकी ऑनमार्ट क्या करेगी, आधे माता-पिता में आधी छवि प्रदर्शित करती है। समस्या यह है कि कॉल करने से पहले Super.onMeasure setMeasuredDimensionको मूल आकार के आधार पर दृश्य में सभी बच्चों को मापना होगा, फिर setMeasuredDimensionआकार बदलने पर इसे केवल आधे में काटें ।

इसके बजाय, आपको कॉल करने की आवश्यकता है setMeasuredDimension(जैसा कि एक ऑनराइड ओवरराइड के लिए आवश्यक है) औरLayoutParams अपने दृश्य के लिए एक नया प्रदान करें , फिर कॉल करें super.onMeasure। याद रखें, आपके LayoutParamsविचार आपके माता-पिता के प्रकार से प्राप्त होते हैं, आपके विचार के प्रकार से नहीं।

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
   int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
   int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
   this.setMeasuredDimension(parentWidth/2, parentHeight);
   this.setLayoutParams(new *ParentLayoutType*.LayoutParams(parentWidth/2,parentHeight));
   super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

मेरा मानना ​​है कि माता-पिता के साथ समस्या होने पर एकमात्र समय LayoutParamsहै यदि माता-पिता एक हैं AbsoluteLayout(जो कि पदावनत है, लेकिन फिर भी कभी-कभी उपयोगी है)।


12
मेरे अनुभव में, यह शायद ही कभी काम करता है, esp। जब भर / मैच_परेंट या वेट लागू होते हैं। SetMeasuredDimension के बाद बेहतर उपाय करें। बच्चों को (उदाहरण के लिए, मापने के लिए)।
एम। शेंक

1
क्या MeasureSpec.getSize(widthMeasureSpec)वास्तव में सही माता-पिता को चौड़ाई मिलती है? मेरे लिए यह सिर्फ यादृच्छिक चौड़ाई देता है जो वास्तविक चौड़ाई के काफी करीब है, लेकिन सटीक नहीं है।
कोंसुमियर

1
@ M.Schenk के पास है। मेरे पास भारित लेआउट के अंदर एक VideoView है। मुझे स्क्रीन के आकार का प्रतिशत होने के लिए चौड़ाई की आवश्यकता है, और मुझे पहलू अनुपात बनाए रखने की आवश्यकता है। यह वीडियो को बढ़ाता है, इसलिए wrap_contentऐसा नहीं करेगा। विक का जवाब इस परिदृश्य के लिए काम नहीं करता है, लेकिन @ M.Schenk की टिप्पणी करता है। यह एक अतिरिक्त लेआउट पास भी बचाता है। आपको इसे दृश्यता के लिए एक उत्तर के रूप में भी पोस्ट करना चाहिए।
dokkaebi

7
super.onMeasure()केवल ओवरराइड करने और पहले की कॉल के प्रभावों को कम करने के लिए कॉल नहीं करेंगे this.setMeasuredDimension()?
स्पिनर

1
मैं भी उत्सुक हूं, जैसा कि @ स्पिनर ने उल्लेख किया है, क्यों कॉल super.onMeasure()पहले की गणना को ओवरराइड नहीं करता है।
jwir3

39

आप एक कस्टम दृश्य बनाकर इसे हल कर सकते हैं और ऑनमार्ट () विधि को ओवरराइड कर सकते हैं। यदि आप अपने xml में लेआउट_अवसरण के लिए हमेशा "fill_parent" का उपयोग करते हैं, तो onMeasusre () पद्धति में दिए गए चौड़ाईमेयरस्पेक पैरामीटर में माता-पिता की चौड़ाई होनी चाहिए।

public class MyCustomView extends TextView {

    public MyCustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
        int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
        this.setMeasuredDimension(parentWidth / 2, parentHeight);
    }
}   

आपका XML कुछ इस तरह दिखाई देगा:

<LinearLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <view
        class="com.company.MyCustomView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

2
@ जफ => माता-पिता क्यों / 2 ??
सईद-आरजे

6
@Leon_SFS: सवाल उस के लिए पूछते हैं: "पूरी ऊंचाई, और 1/2 की चौड़ाई"
एडगर

28

मैंने पाया है कि मापित आयामों को स्वयं स्थापित करने के साथ गड़बड़ न करना सबसे अच्छा है। वास्तव में कुछ बातचीत है जो माता-पिता और बच्चे के विचारों के बीच चलती है और आप उस सभी कोड को फिर से लिखना नहीं चाहते हैं ।

यद्यपि आप क्या कर सकते हैं, फिर भी मापक को संशोधित किया जाता है, फिर उनके साथ सुपर कॉल करें। आपका विचार कभी नहीं जान पाएगा कि उसे अपने माता-पिता से एक संशोधित संदेश मिल रहा है और वह आपके लिए हर चीज़ का ध्यान रखेगा:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
    int myWidth = (int) (parentHeight * 0.5);
    super.onMeasure(MeasureSpec.makeMeasureSpec(myWidth, MeasureSpec.EXACTLY), heightMeasureSpec);
}

16

जब आप एक्सएमएल पर एक लेआउट और दृश्य को परिभाषित करते हैं, तो आप लेआउट की चौड़ाई और ऊंचाई को निर्दिष्ट कर सकते हैं या तो सामग्री लपेटें, या माता-पिता को भरें। क्षेत्र का आधा भाग लेना थोड़ा कठिन है, लेकिन यदि आपके पास कुछ ऐसा है जो आप दूसरे आधे हिस्से पर चाहते हैं तो आप निम्नलिखित की तरह कुछ कर सकते हैं।

   <LinearLayout android:layout_width="fill_parent"
                android:layout_height="fill_parent">
        <ImageView android:layout_height="fill_parent"
                 android:layout_width="0dp"
                 android:layout_weight="1"/>
        <ImageView android:layout_height="fill_parent"
                 android:layout_width="0dp"
                 android:layout_weight="1"/>
   </LinearLayout>

दो चीजों को एक ही वजन देने का मतलब है कि वे स्क्रीन के समान अनुपात को लेने के लिए खिंचाव करेंगे। लेआउट के बारे में अधिक जानकारी के लिए, देव डॉक्स देखें


मैं इसकी अनुशंसा नहीं करता, लेकिन ... एक हैक के रूप में, यदि आप उपरोक्त दृष्टिकोण का उपयोग करते हैं तो आप उन दृश्यों में से एक को "डमी" बना सकते हैं और एंड्रॉइड को आधा क्षेत्र भरने के लिए दृश्यता = "अदृश्य" सेट कर सकते हैं
रिकनॉटफ्रेड

केवल आधे क्षेत्र का उपयोग करने का उद्देश्य क्या है? क्या आप दूसरे आधे हिस्से में कुछ भी प्रदर्शित करने की योजना बना रहे हैं? आप शेष क्षेत्र के साथ क्या करते हैं, सबसे अच्छा तरीका
बताएगा

यह निश्चित रूप से # 1 होना चाहिए - यदि आप इसे अपने xml में कर सकते हैं, तो इसे अपने जावा में क्यों करें?
फंदांग

9

मेरा मानना ​​है कि मायरास एक्सएमएल-एप्रोच नीट में आ सकता है। हालाँकि इसे अधिक सटीक बनाना संभव है, केवल एक दृश्य के साथ वेटसम सेट करके। मैं इसे अब हैक नहीं कहूंगा लेकिन मेरी राय में सबसे सीधा तरीका है:

<LinearLayout android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:weightSum="1">
    <ImageView android:layout_height="fill_parent"
               android:layout_width="0dp"
               android:layout_weight="0.5"/>
</LinearLayout>

इस तरह आप किसी भी वजन का उपयोग कर सकते हैं, उदाहरण के लिए 0.6 (और केंद्र) वह वजन है जिसे मैं बटन के लिए उपयोग करना चाहता हूं।


3

इसे इस्तेमाल करे

int parentWidth = ((parentViewType)childView.getParent()).getWidth();
int parentHeight = ((parentViewType)childView.getParent()).getHeight();

तब आप chileView के मापदंडों को सेट करने के लिए LinearLayout.LayoutParams का उपयोग कर सकते हैं

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(childWidth,childLength);
childView.setLayoutParams(params);

2

अब आप PercentRelativeLayout का उपयोग कर सकते हैं। बूम! समस्या सुलझ गयी।


2
PercentRelativeLayout एपीआई स्तर 26.0.0-beta1 में पदावनत किया गया था।
dzikovskyy

आपका क्या मतलब है "एपीआई स्तर में"? क्या आपका मतलब लाइब्रेरी वर्जन नंबर है? पीआरएल सपोर्ट लाइब्रेरी में है, इसका कोई एपीआई स्तर नहीं है।
androidguy

एपीआई स्तर से मेरा मतलब है कि एंड्रॉइड का संस्करण। यहाँ से जानकारी developer.android.com/reference/android/support/percent/… । एपीआई स्तर के बारे में अधिक जानकारी यहाँ डेवलपर
android.com/guide/topics/manifest/…

आप अभी भी इस वर्ग का उपयोग कर सकते हैं जब तक कि किसी कारण से आपको संस्करण 26.0.0 या उच्चतर की आवश्यकता न हो।
Androidguy

1

रोमन, यदि आप जावा कोड (ViewGroup वंशज) में अपना लेआउट करना चाहते हैं, तो यह संभव है। चाल यह है कि आपको ऑन-ऑन और ऑन-लाइन दोनों तरीकों को लागू करना होगा। OnMeasure को पहले बुलाया जाता है और आपको वहां पर सबव्यू (प्रभावी रूप से वांछित मूल्य पर इसे आकार देने) को "मापने" की आवश्यकता होती है। आपको इसे फिर से चालू कॉल में आकार देने की आवश्यकता है। यदि आप इस क्रम को करने में विफल रहते हैं या अपने ऑन कोड कोड के अंत में setMeasuredDimension () कॉल करने में विफल रहते हैं, तो आपको परिणाम नहीं मिलेंगे। यह इतने जटिल और नाजुक तरीके से क्यों बनाया गया है यह मेरे से परे है।


1

अगर दूसरा पक्ष खाली है। मुझे लगता है कि सबसे आसान तरीका एक खाली दृश्य (जैसे एक रेखीय लेआउट) जोड़ना होगा, फिर दोनों दृश्यों को fill_parent और उनके दोनों वज़न 1 तक की चौड़ाई निर्धारित करें।

यह एक LinearLayout में काम करता है ...


0

यह कुछ इस तरह है:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.company.myapp.ActivityOrFragment"
    android:id="@+id/activity_or_fragment">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/linearLayoutFirst"
    android:weightSum="100">   <!-- Overall weights sum of children elements -->

    <Spinner
        android:layout_width="0dp"   <!-- It's 0dp because is determined by android:layout_weight -->
        android:layout_weight="50"
        android:layout_height="wrap_content"
        android:id="@+id/spinner" />

</LinearLayout>


<LinearLayout
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:layout_below="@+id/linearLayoutFirst"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:id="@+id/linearLayoutSecond">

    <EditText
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:layout_weight="75"
        android:inputType="numberDecimal"
        android:id="@+id/input" />

    <TextView
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:layout_weight="25"
        android:id="@+id/result"/>

</LinearLayout>
</RelativeLayout>

0

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

override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
    super.onLayout(changed, l, t, r, b)
    (getChildAt(1).layoutParams as LayoutParams).width = measuredWidth/2
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.