İki sütun ve otomatik olarak yeniden boyutlandırılan resimlerle birlikte ızgara görünümü


179

İki sütunlu bir gridview yapmaya çalışıyorum. Yani bu resimdeki gibi satır başına iki fotoğraf yan yana.

resim açıklamasını buraya girin

Ancak resimlerimin aynı boyutta olmaması nedeniyle aralarında boşluklar var. İşte aldığım şey.

resim açıklamasını buraya girin

Gördüğünüz gibi ilk resim kişi adını ve telefon numarasını gösteren göstergeyi gizler. ve diğer resimler doğru şekilde uzatılmamış.

İşte GridView xml dosyam . Gördüğünüz gibi 200dpcolumnWidth olarak ayarlanmış . Otomatik olmasını istiyorum , böylece resimler her ekran boyutu için otomatik olarak yeniden boyutlandırılacaktır.

<?xml version="1.0" encoding="utf-8"?>
<GridView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/gridViewContacts"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:numColumns="2"
    android:columnWidth="200dp"
    android:stretchMode="columnWidth"    
    android:gravity="center" />

ve her öğenin kendisini temsil eden xml dosyası.

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

    <ImageView
        android:id="@+id/imageViewContactIcon"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitXY" />

    <LinearLayout
        android:id="@+id/linearlayoutContactName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:paddingLeft="5dp"
        android:paddingTop="5dp"
        android:paddingBottom="5dp"
        android:background="#99000000"
        android:layout_alignBottom="@+id/imageViewContactIcon">

        <TextView
            android:id="@+id/textViewContactName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#FFFFFF"
            android:textStyle="bold"
            android:textSize="15sp"
            android:text="Lorem Ipsum" />       

        <TextView
            android:id="@+id/textViewContactNumber"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#FFFFFF"
            android:layout_marginLeft="5dp"
            android:focusable="true"
            android:ellipsize="marquee"
            android:marqueeRepeatLimit="marquee_forever"
            android:textSize="10sp"
            android:text="123456789" />

    </LinearLayout>

</RelativeLayout>

Yani istediğim, satır başına iki görüntü göstermektir ve ekran boyutu ne olursa olsun görüntüler otomatik olarak yeniden boyutlandırılır. Düzenimde ne yanlış yapıyorum?

Teşekkürler.


1
Belki de ImageView'i kendi LinearLayout'unda kapsüllemeyi denemelisiniz. Bu şekilde LinearLayout etiketini tam olarak istediğiniz gibi yapılandırabilir ve ardından ImageView'in doldurmasını sağlayabilirsiniz.
dani

@dani ne demek istiyorsun? ImageView'i tam olarak istediğim gibi yapılandırabilirim. Bana biraz örnek verebilir misin?
rogcg

Ben hepsi aynı, eski 100x100 veya onlara ihtiyacınız ne olursa olsun resimlerden başparmak oluşturmak gerektiğini düşünüyorum. Örnek görüntünüzde u görebiliyorsanız, aradığınız efekt görüntünün yalnızca bir bölümünü gösterir. Ve projenizde sadece galeri yapmanız gerekiyorsa yanlış olan orijinal resmi görüntüler. Android dev web sitesinde başparmak aramaya çalışın :)
Vasil Valchev

@VasilValchev ama sorun, başparmak oluştursam bile (örneğin 100x100) farklı ekran boyutları için yeniden boyutlandırmam gerekecek. Alredy scaleTypeImageView üzerinde centerCrop özelliğini kullanın . Yapmam gereken şey, resimleri yan yana yapmanın ve farklı ekran boyutları için otomatik olarak yeniden boyutlandırmanın bir yoludur.
rogcg

Ekran boyutunu her zaman yatay beyaz kodda alabilir ve / 2'ye bölebilirsiniz. Eğer projenizde görebiliyorsanız problemin yüksekliği, u tam olarak kilonuzun ne olduğunu biliyorsanız, her zaman mükemmel bir dikdörtgen yapabilirsiniz. Sorunun nerede olduğunu görmüyorum?
Vasil Valchev

Yanıtlar:


402

İşte bunu yapmak için nispeten kolay bir yöntem. Düzeninize bir GridView atın, sütun genişliklerini uzatmak için streç modunu ayarlayın, aralığı 0 (veya istediğinizi) olarak ayarlayın ve sütun sayısını 2'ye ayarlayın:

res / düzeni / main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <GridView
        android:id="@+id/gridview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:verticalSpacing="0dp"
        android:horizontalSpacing="0dp"
        android:stretchMode="columnWidth"
        android:numColumns="2"/>

</FrameLayout>

En ImageViewboy oranını koruyan bir özel yapın :

src / com / example / graphicstest / SquareImageView.java

public class SquareImageView extends ImageView {
    public SquareImageView(Context context) {
        super(context);
    }

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

    public SquareImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth()); //Snap to width
    }
}

Bu SquareImageView öğesini kullanarak bir ızgara öğesi için düzen oluşturun ve scaleType öğesini centerCrop olarak ayarlayın:

res / düzeni / grid_item.xml

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="match_parent"
             android:layout_height="match_parent">

    <com.example.graphicstest.SquareImageView
        android:id="@+id/picture"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"/>

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:paddingTop="15dp"
        android:paddingBottom="15dp"
        android:layout_gravity="bottom"
        android:textColor="@android:color/white"
        android:background="#55000000"/>

</FrameLayout>

Şimdi aşağıdakiler için bir çeşit adaptör yapın GridView:

src / com / example / graphicstest / MyAdapter.java

private final class MyAdapter extends BaseAdapter {
    private final List<Item> mItems = new ArrayList<Item>();
    private final LayoutInflater mInflater;

    public MyAdapter(Context context) {
        mInflater = LayoutInflater.from(context);

        mItems.add(new Item("Red",       R.drawable.red));
        mItems.add(new Item("Magenta",   R.drawable.magenta));
        mItems.add(new Item("Dark Gray", R.drawable.dark_gray));
        mItems.add(new Item("Gray",      R.drawable.gray));
        mItems.add(new Item("Green",     R.drawable.green));
        mItems.add(new Item("Cyan",      R.drawable.cyan));
    }

    @Override
    public int getCount() {
        return mItems.size();
    }

    @Override
    public Item getItem(int i) {
        return mItems.get(i);
    }

    @Override
    public long getItemId(int i) {
        return mItems.get(i).drawableId;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        View v = view;
        ImageView picture;
        TextView name;

        if (v == null) {
            v = mInflater.inflate(R.layout.grid_item, viewGroup, false);
            v.setTag(R.id.picture, v.findViewById(R.id.picture));
            v.setTag(R.id.text, v.findViewById(R.id.text));
        }

        picture = (ImageView) v.getTag(R.id.picture);
        name = (TextView) v.getTag(R.id.text);

        Item item = getItem(i);

        picture.setImageResource(item.drawableId);
        name.setText(item.name);

        return v;
    }

    private static class Item {
        public final String name;
        public final int drawableId;

        Item(String name, int drawableId) {
            this.name = name;
            this.drawableId = drawableId;
        }
    }
}

Bu adaptörü kendinize göre ayarlayın GridView:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    GridView gridView = (GridView)findViewById(R.id.gridview);
    gridView.setAdapter(new MyAdapter(this));
}

Ve sonuçların tadını çıkarın:

Örnek GridView


3
işe yaradı! ama bana bir sınıf oluşturma ihtiyacını ImageViewve neden xml'de<com.example.graphicstest.SquareImageView> basit bir <ImageView>etiket yerine böyle bir şey kullandığınızı açıklamanızı istiyorum dosyasındaki . Bana bu en-boy oranı ve bu sınıfın nasıl oluşturulmadığı hakkında daha fazla bilgi verebilir misiniz? özel ImageViewsınıfa ihtiyaç duymadan bunu optimize etmenin bir yolu var mı? yine de yardımlarınız için teşekkürler.
rogcg

10
Temel olarak, Android'in ImageView sınıfında, sabit kod genişliği ve yüksekliği sürece "hey, bu görünüm için kare en boy oranını (genişlik / yükseklik) tut" belirtmenin bir yolu yoktur. Adaptörün getView'inde LayoutParams'ın manuel ayarlamasını yapabilirsiniz, ancak açıkçası, ImageView'in tüm ölçümleri işlemesine izin vermek ve "Genişlik ne olursa olsun, boyumu aynı kalmasını sağlamak" için sonuçları geçersiz kılmak çok daha basittir. Bunu asla düşünmenize gerek yok, her zaman kare ve sadece beklendiği gibi çalışıyor. Temelde bu görünüm karesini korumanın en kolay yoludur.
Kevin Coppock

8
İçin bir sebep düşünemiyorum Düzenli bir ImageView ile yapabileceğiniz her şeyi yapabileceğiniz gibi, özel ImageView sınıfını yapmaktan kaçınmak , ancak bu sadece ölçümler ve LayoutParams örnekleme yapmak ve her yerde kontrol etmek zorunda kalmamanızı sağlıyor .
Kevin Coppock

1
Düzenlediğiniz için teşekkürler, bunun bir cazibe gibi çalıştığını düşündüm!
Zander

1
@kcoppock: Bu kodu paylaştığınız için çok teşekkürler. En çok sevdiğim şey, görüntüleme görüntüsü renklerini "gerçek" resimlerle değiştirebilmeniz ve düzgün bir şekilde yeniden boyutlandırılmasıdır! Anlamak istediğim, belirli bir sayıda görünümün tüm ekranı doldurması için görünümleri yeniden boyutlandırmanın mümkün olup olmadığıdır.
AntonSack

14

PercentRelativeLayout gibi modern yerleşik şeylerle başka bir basit yaklaşım artık bu sorunu yaşayan yeni kullanıcılar için kullanılabilir. Bu öğeyi yayınlamak için android ekibine teşekkürler.

<android.support.percent.PercentRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
app:layout_widthPercent="50%">

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/picture"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop" />

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:background="#55000000"
        android:paddingBottom="15dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:paddingTop="15dp"
        android:textColor="@android:color/white" />

</FrameLayout>

ve daha iyi performans için picasso görüntü yükleyici gibi her görüntü ebeveyinizin tüm genişliğini doldurmanıza yardımcı olan bazı şeyler kullanabilirsiniz. örneğin adaptörünüzde bunu kullanmalısınız:

int width= context.getResources().getDisplayMetrics().widthPixels;
    com.squareup.picasso.Picasso
            .with(context)
            .load("some url")
            .centerCrop().resize(width/2,width/2)
            .error(R.drawable.placeholder)
            .placeholder(R.drawable.placeholder)
            .into(item.drawableId);

Artık CustomImageView Sınıfına ihtiyacınız yok.

PS i Image Item sınıf Int yerine yerine ViewView kullanmanızı öneririz.

umarım bu yardım ..


API 26.1 ile bu sınır dışı edildi. Bkz. Bağlantı
Dominikus K.10
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.