2011-09-20 14 views
18

को बनाए रखने के दौरान जितनी बड़ी हो सके छवि को बनाने के लिए मेरे पास एक ऐसी छवि है जो कंटेनर से छोटी है जिसे मैं अंदर फिट करना चाहता हूं। मैं छवि को अपने पहलू अनुपात को बनाए रखने के लिए, इसे सबसे बड़ा संभव आकार तक खींचना चाहता हूं।पहलू अनुपात

इस समस्या को समझने के लिए:

<ImageView android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:src="@drawable/thumbnail" 
      android:scaleType="fitXY" 
      android:adjustViewBounds="true"/> 

ImageView ऊपर कंटेनर की चौड़ाई को भरने के लिए बढ़ाया जाना होगा। @drawable यह ImageView की चौड़ाई फिट करने के लिए एक्स अक्ष के साथ भी फैला होगा जो सही है। समस्या यह है कि इस मामले की ऊंचाई में wrap_content लेबल आयाम, @drawable की आरंभिक ऊंचाई के समान आकार बना हुआ है।

मैंने स्केल टाइप here के बारे में प्रलेखन पढ़ा है और वहां जवाब नहीं मिल रहा है।

निम्न छवि उपरोक्त कोड में बताता है:

enter image description hereenter image description here

Current behaviour    Desired Behaviour 

संपादित

एक ImageViewscaleType="fitCenter" सही ढंग से विस्तार/विकसित करने के लिए इसके अंदर @drawable हटना होगा दिया बनाए रखने के दौरान जितना संभव हो उतना बड़ा इसके पहलू अनुपात में आईएनजी।

ImageView के आयामों को परिभाषित किया गया है @drawable किसी भी तरह से स्केल किया गया है। ImageView आयाम इसके @drawable के स्केलिंग से प्रभावित नहीं होते हैं।

+2

, यह है एक आम समस्या, एक जिसे मैंने कभी साफ समाधान नहीं मिला है। एक फ्रेम के लिए पृष्ठभूमि 9-पैच में जोड़ें, और यह कोशिश करने और ठीक करने के लिए भी बदतर है। मुझे पूरा यकीन है कि यह कुछ ऐसा है जो आपको प्रोग्रामेटिक रूप से करना होगा, लेकिन अगर किसी के पास इसका समाधान हो तो यह अच्छा होगा। – kcoppock

+2

+1 पूरी तरह से वर्णित प्रश्न – Merlin

उत्तर

7

एक्सएमएल

एक्सएमएल में इस का एकमात्र समाधान जहां संभव "match_parent" या एक असतत अधिकतम मूल्य के बजाय "wrap_content" उपयोग करने के लिए है। यह सुनिश्चित करेगा कि ImageView सही आकार है, जिसका अर्थ है scaleType="fitCenter" जोड़ने से @drawable सही ढंग से स्केल करेगा।

प्रोग्राम के

यह बदसूरत है, लेकिन आप imageView आकार बदल सकते हैं के बाद यह आयाम असतत मूल्यों दिया गया है है:

final ImageView thumbnailView = (ImageView) toReturn.findViewById(R.id.thumbnail); 

    ViewTreeObserver thumbnailViewVto = thumbnailView.getViewTreeObserver(); 
    thumbnailViewVto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
     private boolean changed = false; 
     @Override 
     public void onGlobalLayout() { 
      if(!changed) { 
       Drawable image = getResources().getDrawable(R.drawable.thumbnail); 
       float heighToWidthRatio = image.getIntrinsicWidth()/image.getIntrinsicHeight(); 
       int height = thumbnailView.getHeight(); 

       thumbnailView.setLayoutParams(
         new LayoutParams(
           (int) (height * heighToWidthRatio), height)); 
       changed = true; 
      } 
     } 
    }); 

संपादित

final ImageView thumbnailView = (ImageView) toReturn.findViewById(R.id.thumbnail); 

    thumbnailView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 

     @Override 
     public void onGlobalLayout() { 
      // Remove the GlobalOnLayout Listener so it only fires once. 
      thumbnailView.getViewTreeObserver().removeGlobalOnLayoutListener(this) 

      // Find the images Height to Width ratio 
      Drawable image = getResources().getDrawable(R.drawable.thumbnail); 
      float heighToWidthRatio = image.getIntrinsicWidth()/image.getIntrinsicHeight(); 

      // Use this ratio to discover the ratio of the ImageView to allow it to perfectly contain the image. 
      int height = thumbnailView.getHeight(); 
      thumbnailView.setLayoutParams(new LayoutParams(
           (int) (height * heighToWidthRatio), height)); 
     } 
    }); 
मेरे लिए
+1

+1 एक सामान्य समस्या को हल करने के लिए – Merlin

+0

बूलियन 'बदले' के लिए क्या है? – BornToCode

+0

ऐसा इसलिए है कि ग्लोबललायआउट श्रोता बार-बार आग नहीं लगाता है। बूढ़े और बुद्धिमान, मैं अब 'OnGlobalLayoutListener' को' ViewTreeObserver' से 'onGlobalLayout()' विधि में पहली क्रिया के रूप में हटा दूंगा। (विवरण के लिए मेरा संपादन देखें) – Graeme

1

ऐसा लगता है कि आप फिट सेंटर चाहते हैं, जो Matrix.ScaleToFit CENTER का उपयोग करता है।

+0

के लिए +1 यह पहलू अनुपात रखता है लेकिन छवि अब और नहीं भरती है।यह काम करेगा यदि ImageView की ऊंचाई सही थी जिसे प्रोग्रामेटिक रूप से किया जा सकता है लेकिन मैं इसे एक्सएमएल के माध्यम से करना चाहता हूं। – Graeme

+0

@Graeme - लिंक से: "एक ऐसे पैमाने की गणना करें जो मूल स्रोत पहलू अनुपात को बनाए रखे, लेकिन यह भी सुनिश्चित करेगा कि src पूरी तरह से dst के अंदर फिट बैठता है। * कम से कम एक धुरी (एक्स या वाई) ठीक से फिट होगा। * परिणाम है डीएसटी के अंदर केंद्रित। " - उनका वर्णन यह इंगित करता है कि छवि चौड़ाई या ऊंचाई को भरने के लिए बढ़ाया जाएगा। शायद यह केवल फिट करने के लिए shrinks, लेकिन फिट करने के लिए खिंचाव नहीं है? – mbeckish

+0

यह विवरण बिल्कुल सही है - चूंकि आयामों में से एक को "wrap_content" पर सेट किया गया है, हालांकि छवि दृश्य का आकार प्रारंभिक स्केलिंग से पहले होता है, इसलिए दृश्य की ऊंचाई पहले ही सेट हो चुकी है और यह फिट करने के लिए सबसे छोटी अक्ष का उपयोग कर रही है इसे बढ़ाए बिना। – Graeme

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