두 개의 열과 자동 크기 조정 된 이미지가있는 그리드 뷰


179

두 개의 열로 그리드 뷰를 만들려고합니다. 나는이 이미지와 같이 행 당 두 장의 사진을 나란히 의미합니다.

여기에 이미지 설명을 입력하십시오

그러나 내 사진의 크기가 같지 않기 때문에 사진 사이에 공백이 있습니다. 여기 내가 얻는 것이 있습니다.

여기에 이미지 설명을 입력하십시오

보시다시피 첫 번째 사진은 연락처 이름과 전화 번호를 보여주는 범례를 숨 깁니다. 다른 사진은 올바르게 늘어나지 않습니다.

다음은 GridView xml 파일입니다. 보시다시피 columnWidth200dp 로 설정되어 있습니다 . 자동으로하고 싶습니다 . 그래서 그림은 각 화면 크기에 따라 자동으로 크기가 조정됩니다.

<?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" />

여기에 각 항목 자체를 나타내는 item xml 파일이 있습니다.

<?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>

그래서 내가 원하는 것은 화면 크기에 관계없이 행 당 두 개의 이미지를 표시하고 이미지 크기가 자동으로 조정되는 것입니다. 내 레이아웃에서 내가 뭘 잘못하고 있니?

감사.


1
아마도 자신의 LinearLayout에 ImageView를 캡슐화해야합니다. 이런 식으로 LinearLayout 태그를 원하는대로 정확하게 구성한 다음 ImageView로 채울 수 있습니다.
dani mar

@dani 무슨 뜻이야? 여전히 원하는대로 ImageView를 구성 할 수 있습니다. 예를 들어 주시겠습니까?
rogcg

나는 이미지에서 엄지 손가락을 만들어야한다고 생각합니다.이 이미지는 모두 동일합니다. 예 : 100x100 또는 필요한 것. 예제 이미지에서 u를 볼 수 있다면 u의 효과는 이미지의 일부만 표시하는 것입니다. 그리고 프로젝트에서 u는 원본 이미지를 표시합니다. 갤러리를 만들어야하는 경우 잘못되었습니다. 안드로이드 개발자 웹 사이트에서 엄지 손가락을 찾아보십시오 :)
Vasil Valchev

@ VasilValchev 그러나 문제는 엄지 손가락 (예 : 100x100)을 만들더라도 다른 화면 크기에 맞게 크기를 조정해야한다는 것입니다. scaleTypeImageView 에서 centerCrop 속성을 이미 사용하고 있습니다. 내가 달성해야 할 것은 사진을 나란히 만들고 다른 화면 크기에 맞게 자동으로 크기를 조정하는 방법입니다.
rogcg

화면 크기는 항상 가로 오순절 코드로 가져 와서 / 2로 나눌 수 있습니다. 당신이 당신의 프로젝트에서 볼 수 있다면 문제는 높이에 있습니다. 만약 당신이 정확히 당신의 체중이 무엇인지 안다면 u는 항상 완벽한 직사각형을 만들 수 있습니다. 문제가 어디에 있는지 모르겠습니다.
Vasil Valchev

답변:


402

이 작업을 수행하는 비교적 쉬운 방법이 있습니다. GridView를 레이아웃에 던져서, 늘이기 모드를 설정하여 열 너비를 늘리고 간격을 0 (또는 원하는 것)으로 설정하고 열 수를 2로 설정하십시오.

res / layout / 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>

ImageView가로 세로 비율을 유지 하는 사용자 정의 를 작성하십시오.

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
    }
}

이 SquareImageView를 사용하여 격자 항목의 레이아웃을 만들고 scaleType을 centerCrop으로 설정하십시오.

res / layout / 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>

이제 다음과 같은 종류의 어댑터를 만드십시오 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;
        }
    }
}

해당 어댑터를 다음으로 설정하십시오 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));
}

그리고 결과를 즐기십시오 :

GridView 예


3
효과가 있었다! 하지만 클래스를 만들어야 할 필요성 ImageViewxml 파일 <com.example.graphicstest.SquareImageView>의 간단한 <ImageView>태그 대신 이와 같은 것을 사용하는 이유 를 설명하고 싶습니다 . 이 종횡비 에 대해 더 자세히 설명해 주시고이 클래스를 작성하지 않는 방법이 항목에 영향을 미칩니다. 커스텀 클래스 가 없어도 이것을 최적화하는 방법이 있습니까? 어쨌든 도움을 주셔서 감사합니다. ImageView
rogcg

10
기본적으로 Android의 ImageView 클래스에서는 너비와 높이를 하드 코딩하지 않는 한 "이보기에 대한 가로 세로 비율 (너비 / 높이) 유지"를 간단히 지정할 수있는 방법이 없습니다. 어댑터의 getView에서 LayoutParams를 수동으로 조정할 수 있지만, 솔직히 ImageView가 모든 측정을 처리하도록하고 결과를 재정 의하여 "너비가 넓어지면 높이가 동일하게 유지됩니다"라고 말하는 것이 훨씬 간단합니다. 당신은 그것에 대해 생각할 필요가 없으며 항상 정사각형이며 예상대로 작동합니다. 기본적으로 이것은 뷰 사각형을 유지하는 가장 쉬운 방법입니다.
Kevin Coppock

8
나는 이유 생각할 수 없다 않도록 정기적 이미지 뷰 때와 수있는 당신이 그것으로 모든 것을 할 수있는 사용자 지정 이미지 뷰 클래스를 만들고, 그러나 이것은 단지 여기 저기를 측정과의 LayoutParams 인스턴스화 할 필요 및 체크에서 당신을 유지 .
Kevin Coppock

1
편집 해 주셔서 감사합니다. 매력처럼 작동 할 수도 있습니다.
Zander

1
@kcoppock :이 코드를 공유해 주셔서 감사합니다. 내가 가장 좋아하는 것은 "실제"사진으로 이미지 뷰의 색상을 바꿀 수 있고 크기가 올바르게 조정된다는 것입니다! 내가 이해하고 싶은 것은 특정 수의 뷰가 전체 화면을 채우도록 뷰의 크기를 조정할 수 있는지 여부입니다.
AntonSack

14

PercentRelativeLayout 과 같은 최신 내장 기능을 사용한 또 다른 간단한 접근 방식이 이제이 문제에 부딪친 신규 사용자에게 제공됩니다. 이 항목을 출시 한 안드로이드 팀 덕분에.

<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>

더 나은 성능을 위해 모든 이미지 부모의 전체 너비를 채우는 데 도움이되는 picasso 이미지 로더와 같은 것을 사용할 수 있습니다. 예를 들어, 어댑터에서 다음을 사용해야합니다.

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);

이제 더 이상 CustomImageView 클래스가 필요하지 않습니다.

추신 : 클래스 항목에서 유형 Int 대신 ImageView를 사용하는 것이 좋습니다.

이 도움을 바랍니다 ..


API 26.1에서는 더 이상 사용되지 않습니다. 링크
Dominikus K.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.