ImageView - yükseklik eşleme genişliği var mı?


166

Bir hayalim var. Genişliğinin fill_parent olmasını istiyorum. Yüksekliğinin, genişliği ne olursa olsun olmasını istiyorum. Örneğin:

<ImageView
  android:layout_width="fill_parent"
  android:layout_height="whatever the width ends up being" />

Kendi görünüm sınıfımı oluşturmak zorunda kalmadan bir düzen dosyasında böyle bir şey mümkün mü?

Teşekkürler


Bunu nasıl yapacağınızı anladınız mı? En boy oranının aynı kalmasını istediğinizi varsayalım. Bu yanıtların çoğu, görüntünün kare olmasını istediğinizi varsayar.
Adam

@Joe Blow bunu yapmak için ÇOK kötü bir yol
Aggressor

Yanıtlar:


171

Güncelleme: 14 Eylül 2017

Aşağıdaki bir açıklamaya göre, destek kitaplığı yüzdesi Android Destek Kitaplığı 26.0.0'dan itibaren kullanımdan kaldırılmıştır. Bunu yapmanın yeni yolu:

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintDimensionRatio="1:1" />

</android.support.constraint.ConstraintLayout>

Buraya bakın

Kullanımdan kaldırılan:

Android Geliştiricilerinin bu yazısına göre , şimdi tek yapmanız gereken bir PercentRelativeLayout veya PercentFrameLayout içine istediğinizi sarmak ve ardından oranlarını belirtmektir.

<android.support.percent.PercentRelativeLayout 
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        app:layout_widthPercent="100%"
        app:layout_aspectRatio="100%"/>

</android.support.percent.PercentRelativeLayout>

8
Bu cevabın bağlantısı, Google'ın sağladığı en şık çözüme sahiptir. Benim durumumda, orijinal görüntü en boy oranı ne olursa olsun, görüntünün 16: 9 oranında görüntülenmesini istedim. Harika çalışıyor. Teşekkürler!
Lets

Davamı Im, gibi çözümler bu bir işe yaramadı, bu bir mi!
Gooey

5
Bağımlılıklarınıza '
compile.android.support:percent:23.3.0

Bu yaklaşım, çocuk içeriğine göre yüksekliği hesaplayan WrappedViewPager ile ilgili sorunlar yaşıyor gibi görünüyor. Benzer WrappedViewPager Kaynak gist.github.com/egslava/589b82a6add9c816a007
Şekilli

1
Android Destek Kütüphanesi 26.0.0'dan bu yana Yüzde Destek modülü kullanımdan kaldırıldı. Kaynak: developer.android.com/topic/libraries/support-library/…
MHogge

97

Belki bu soruya cevap verecektir:

<ImageView
    android:id="@+id/cover_image"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:scaleType="fitCenter"
    android:adjustViewBounds="true" />

scaleTypeBu özel duruma ilişkin özniteliği yoksayabilirsiniz .


12
Evet, bu işe yaramaz
Fattie

4
Gereksiz olarak işe yaramaz değil. Bu benim kullanımım için iyi çalışıyor, bir başlık çubuğunda bir simge var ben kalan kare iken yüksekliği doldurmak için ölçeklemek istiyorum.
Anubian Noob

3
Sorunumu da çözdüm.
Dielson Sales

En kolay yol! Bu En İyi Yanıt olarak işaretlenmelidir.
H. Farid

30

Bu, çalışma zamanında Görünüm genişliğini bildiğinizde Görünüm yüksekliğini dinamik olarak ayarlamak için LayoutParams kullanılarak yapılabilir. Görünümler genişliğini çalışma zamanında almak için bir Runnable iş parçacığı kullanmanız gerekir, aksi takdirde görünüm henüz çizilmediğinden, Görünümün genişliğini bilmeden önce Yüksekliği ayarlamaya çalışırsınız.

Sorunumu nasıl çözdüğüme örnek:

final FrameLayout mFrame = (FrameLayout) findViewById(R.id.frame_id);

    mFrame.post(new Runnable() {

        @Override
        public void run() {
            RelativeLayout.LayoutParams mParams;
            mParams = (RelativeLayout.LayoutParams) mFrame.getLayoutParams();
            mParams.height = mFrame.getWidth();
            mFrame.setLayoutParams(mParams);
            mFrame.postInvalidate();
        }
    });

LayoutParams, görünümünüzün Ana Görünüm türünde olmalıdır. FrameLayout'um, xml dosyasındaki bir RelativeLayout içinde.

    mFrame.postInvalidate();

UI iş parçacığından farklı bir iş parçacığında görünümü yeniden çizmeye zorlamak için çağrılır


4
harika cevap, özellikle Runnable ile, teşekkürler!
jesses.co.tt

1
Bu çalışırken, ideal değildir. Gönderi üzerinde çalışmak, görünümün düzen değişmeden önce bir kez oluşturulduğu anlamına gelir. Doğru çizmeden önce bir içeriğin yanlış yükseklikte yanıp sönmesine izin verilebilir. Daha önce çözmek daha iyidir. Çözülmesi mümkün olan en erken an onMeasure, Regis'in cevabında gösterildiği gibi, bir gelenek sırasındadır . Bir alternatif, ancak sadece bir adaptör aracılığıyla oluşturulan görünümler için, örneğin içeride GridView, Matt'in cevabıdır .
ToolmakerSteve

1
iyi sadece requestLayout()parametreleri ayarladıktan sonra aradıktan sonra benim için çalıştı . neden böyle olsun?
Divins Mathew

mFrame.postInvalidate (); Ne yaptıysa, onsuz görüntüyü konum dışına alıyordum.
Jacolack

17

David Chu'nun RecyclerView öğesi için çalışmasına yanıt alamadım ve ImageView'i üst öğeyle sınırlandırmam gerektiğini anladım. ImageView genişliğini 0dpbaşlangıç ​​ve bitiş öğelerini üst öğe olarak ayarlayın ve sınırlandırın. Genişliğini ayarlamak wrap_contentveya match_parentbazı durumlarda çalışıyor emin değilim , ama bu bir ConstraintLayout alt öğe üst doldurmak için almak için daha iyi bir yol olduğunu düşünüyorum.

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintDimensionRatio="1:1"/>

</android.support.constraint.ConstraintLayout>

13

Burada her zaman genişliğine eşit bir genişliğe sahip bir ImageButton için ne yaptım (ve bir yönde aptal boş kenar boşlukları önlemek ... ki ben bir SDK hata olarak kabul ...):

ImageButton uzanan bir SquareImageButton sınıfı tanımladı:

package com.myproject;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageButton;

    public class SquareImageButton extends ImageButton {

        public SquareImageButton(Context context) {
        super(context);


        // TODO Auto-generated constructor stub
    }

    public SquareImageButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub

    }

    public SquareImageButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub

    }

    int squareDim = 1000000000;

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


        int h = this.getMeasuredHeight();
        int w = this.getMeasuredWidth();
        int curSquareDim = Math.min(w, h);
        // Inside a viewholder or other grid element,
        // with dynamically added content that is not in the XML,
        // height may be 0.
        // In that case, use the other dimension.
        if (curSquareDim == 0)
            curSquareDim = Math.max(w, h);

        if(curSquareDim < squareDim)
        {
            squareDim = curSquareDim;
        }

        Log.d("MyApp", "h "+h+"w "+w+"squareDim "+squareDim);


        setMeasuredDimension(squareDim, squareDim);

    }

}

İşte benim xml:

<com.myproject.SquareImageButton
            android:id="@+id/speakButton"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:scaleType="centerInside"
            android:src="@drawable/icon_rounded_no_shadow_144px"
            android:background="#00ff00"
            android:layout_alignTop="@+id/searchEditText"
            android:layout_alignBottom="@+id/searchEditText"
            android:layout_alignParentLeft="true"
           />

Tıkır tıkır çalışıyor !


Evet, bu en iyi cevap. (ve OP sorusuna gerçekten uyan tek kişi)
Twometer

7

Görüntü görünümünüz bir kısıtlama düzeninin içindeyse, kare görüntü görünümü oluşturmak için aşağıdaki kısıtlamaları kullanabilirsiniz

<ImageView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:id="@+id/ivImageView"
    app:layout_constraintDimensionRatio="W,1:1"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"/>

6

Android'de 26.0.0'da PercentRelativeLayout kullanımdan kaldırıldı .

Bunu çözmenin en iyi yolu şu şekilde ConstraintLayout:

<android.support.constraint.ConstraintLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

    <ImageView android:layout_width="match_parent"
               android:layout_height="0dp"
               android:scaleType="centerCrop"
               android:src="@drawable/you_image"                       
               app:layout_constraintDimensionRatio="1:1"/>


</android.support.constraint.ConstraintLayout>


Projenize nasıl ekleneceğinize dair bir eğiticiConstraintLayout .


5

Sadece mizanpaj ile yapamazsın, denedim. Bunu halletmek için çok basit bir sınıf yazdım, github'da kontrol edebilirsiniz. SquareImage.java Daha büyük bir projenin parçası ama küçük bir kopyalayıp yapıştıracak hiçbir şey düzeltilemiyor (Apache 2.0 altında lisanslanmıştır)

Temel olarak, yüksekliği / genişliği diğer boyuta eşit olarak ayarlamanız gerekir (ölçeklemek istediğiniz yola bağlı olarak)

Not: scaleTypeÖzniteliği kullanarak özel bir sınıf olmadan kare yapabilirsiniz, ancak görünümün sınırları görünür görüntünün ötesine uzanır, bu da yanına başka görünümler yerleştiriyorsanız bunu bir sorun haline getirir.


3

ImageView'inizi ekranın yarısına eşitlemek için ImageView XML'inize aşağıdakileri eklemeniz gerekir:

<ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerInParent="true"
    android:scaleType="fitXY"
    android:adjustViewBounds="true"/>

Daha sonra yüksekliği bu genişliğe eşit olarak ayarlamak için kodda yapmanız gerekir. Olarak getViewda yöntemine GridViewadaptörü, set ImageViewyüksekliği, ölçülen genişliğine eşit:

mImageView.getLayoutParams().height = mImageView.getMeasuredWidth();

3

Şimdiye kadar geçen insanlar için, 2017'de, istediğinizi elde etmenin yeni en iyi yolu ConstraintLayout'u şu şekilde kullanmaktır :

<ImageView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:scaleType="centerCrop"
    app:layout_constraintDimensionRatio="1:1" />

Ayrıca, düzeninizin gerektirdiği gibi dört yöne de kısıtlama eklemeyi unutmayın.

ConstraintLayout ile Duyarlı bir kullanıcı arayüzü oluşturun

Ayrıca, şimdiye kadar PercentRelativeLayout kullanımdan kaldırıldı (bkz. Android dokümanları ).


1

Bu sorunu şu şekilde çözdüm:

int pHeight =  picture.getHeight();
int pWidth = picture.getWidth();
int vWidth = preview.getWidth();
preview.getLayoutParams().height = (int)(vWidth*((double)pHeight/pWidth));

önizleme - genişlik "match_parent" olarak ayarlanmış ve scaleView ile "cropCenter" yazın

picture - imageView src içinde ayarlanacak bitmap nesnesi.

Bu benim için gayet iyi çalışıyor.


Bu kodun nereye konması gerektiğini açıklamadınız . Daha = vw*ph/pwbasit yerine neden yaptığınızı da açıklamamışsınızdır = vw. (Bunu kare görüntüyü zorlamak yerine kaynak görüntünün en boy oranını korumak için yaptığınızı düşünüyorum.)
ToolmakerSteve

0

XML düzen dosyasında yapabileceğiniz herhangi bir yol olduğunu düşünmüyorum ve android:scaleTypeözniteliğin istediğiniz gibi çalışacağını düşünmüyorum .
Tek yol programlı olarak yapmak olacaktır. Genişliği fill_parent olarak ayarlayabilir ve ekran genişliğini yükseklik olarak alabilir Viewveya View.getWidth()yöntemi kullanabilirsiniz .


0

ImageView "scaleType" işlevi burada size yardımcı olabilir.

Bu kod, en boy oranını koruyacak ve görüntüyü en üste yerleştirecektir:

android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitStart"

ScaleType'ı kullanma olasılıklarını ve görünümlerini gösteren harika bir gönderi.

ImageView ölçeğiTip örnekleri


"scaleType" burada yardımcı olmuyor. Amaç, ImageView'in kendisinin sadece içindeki görüntüyü değil, daima kare olmasını sağlamaktır. ScaleType ile, ImageView görüntüden daha büyük olabilir.
ToolmakerSteve

0

bunu beğendim -

layout.setMinimumHeight(layout.getWidth());
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.