Gridview với hai cột và hình ảnh tự động thay đổi kích thước


179

Tôi đang cố gắng tạo ra một khung nhìn với hai cột. Ý tôi là hai bức ảnh mỗi hàng cạnh nhau giống như hình ảnh này.

nhập mô tả hình ảnh ở đây

Nhưng những bức ảnh của tôi có khoảng cách giữa chúng, do thực tế là nó không cùng kích cỡ. Đây là những gì tôi nhận được.

nhập mô tả hình ảnh ở đây

như bạn có thể thấy hình ảnh đầu tiên ẩn truyền thuyết hiển thị tên liên lạc và số điện thoại. và các hình ảnh khác không được kéo dài chính xác.

Đây là tập tin GridView xml của tôi . Như bạn có thể thấy columnWidthđược đặt thành 200dp . Tôi muốn nó tự động , vì vậy hình ảnh sẽ tự động thay đổi kích thước cho từng kích thước màn hình.

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

và đây là tệp xml mục, đại diện cho chính từng mục.

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

Vì vậy, những gì tôi muốn, là hiển thị hai hình ảnh mỗi hàng và hình ảnh tự động thay đổi kích thước, bất kể kích thước màn hình. Tôi đang làm gì sai trên bố cục của tôi?

Cảm ơn.


1
Có lẽ bạn nên thử đóng gói ImageView trong linearLayout của riêng nó. Bằng cách này, bạn có thể định cấu hình thẻ linearLayout chính xác như bạn muốn và sau đó chỉ cần có ImageView điền vào nó.
dani

@dani ý bạn là gì? tôi vẫn có thể cấu hình ImageView chính xác như tôi muốn. bạn có thể cho tôi một vài ví dụ?
rogcg

Tôi nghĩ rằng bạn cần phải tạo ngón tay cái từ hình ảnh, tất cả đều giống nhau, ví dụ 100x100 hoặc bất cứ điều gì bạn cần chúng. Nếu bạn có thể nhìn thấy trên hình ảnh ví dụ của bạn, hiệu ứng bạn đang tìm kiếm chỉ hiển thị một phần của hình ảnh. Và trong dự án của bạn, bạn chỉ hiển thị hình ảnh gốc, điều đó là sai nếu bạn cần tạo thư viện. Hãy thử tìm kiếm ngón tay cái trong trang web dành cho nhà phát triển Android :)
Vasil Valchev

@VasilValchev nhưng vấn đề là, ngay cả khi tôi tạo ngón tay cái (ví dụ 100x100) tôi sẽ cần thay đổi kích thước cho các kích thước màn hình khác nhau. Tôi đã sử dụng thuộc tính centreCrop scaleTypetrên ImageView. Những gì tôi cần đạt được là một cách để làm cho hình ảnh cạnh nhau và tự động thay đổi kích thước cho các kích thước màn hình khác nhau.
rogcg

Bạn luôn có thể lấy kích thước màn hình theo mã trắng ngang và chỉ cần chia nó cho / 2. Nếu bạn có thể thấy trong dự án của bạn thì vấn đề là về chiều cao, nếu bạn biết chính xác cân nặng của bạn thì bạn luôn có thể tạo ra một hình chữ nhật hoàn hảo. Tôi không thấy vấn đề ở đâu?
Vasil Valchev

Câu trả lời:


402

Đây là một phương pháp tương đối dễ dàng để làm điều này. Ném GridView vào bố cục của bạn, đặt chế độ kéo dài để kéo dài độ rộng cột, đặt khoảng cách thành 0 (hoặc bất cứ điều gì bạn muốn) và đặt số lượng cột thành 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>

Tạo một tùy chỉnh ImageViewduy trì tỷ lệ khung hình của nó:

src / com / example / Graphicsstest / 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
    }
}

Tạo bố cục cho một mục lưới bằng SquareImageView này và đặt scaleType thành centreCrop:

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>

Bây giờ thực hiện một số loại bộ chuyển đổi cho của bạn GridView:

src / com / example / Graphicsstest / MyAd Module.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;
        }
    }
}

Đặt bộ chuyển đổi đó thành của bạ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));
}

Và tận hưởng kết quả:

Ví dụ GridView


3
nó đã làm việc! nhưng tôi muốn bạn giải thích cho tôi về nhu cầu tạo một lớp cho ImageViewvà tại sao sử dụng một cái gì đó như thế này <com.example.graphicstest.SquareImageView>thay vì một <ImageView>thẻ đơn giản trong tệp xml . Bạn có thể giải thích cho tôi thêm về tỷ lệ khung hình này và cách không tạo lớp này, ảnh hưởng đến các mục. Có cách nào để tối ưu hóa điều này, mà không cần đến ImageViewlớp tùy chỉnh không? cảm ơn vì sự giúp đỡ của bạn
rogcg

10
Về cơ bản, trong lớp ImageView của Android, không có cách nào chỉ định đơn giản "hey, giữ tỷ lệ khung hình vuông (chiều rộng / chiều cao) cho chế độ xem này" trừ khi bạn cứng chiều rộng và chiều cao mã. Bạn có thể thực hiện một số điều chỉnh thủ công của LayoutParams trong getView của bộ điều hợp, nhưng thật lòng mà nói, đơn giản hơn nhiều khi để ImageView xử lý tất cả các phép đo và chỉ ghi đè lên kết quả để nói "Dù chiều rộng kết thúc như thế nào, hãy làm cho chiều cao của tôi giữ nguyên". Bạn không bao giờ phải suy nghĩ về nó, nó luôn luôn vuông và nó chỉ hoạt động như mong đợi. Về cơ bản đây là cách dễ nhất để giữ cho hình vuông.
Kevin Coppock

8
Tôi không thể nghĩ ra lý do để tránh tạo lớp ImageView tùy chỉnh, vì bạn có thể làm mọi thứ với nó bằng một ImageView thông thường, nhưng điều này giúp bạn không phải thực hiện các phép đo và khởi tạo LayoutParams và kiểm tra mọi nơi .
Kevin Coppock

1
Cảm ơn đã chỉnh sửa, nghĩ rằng nó có thể là như vậy, làm việc như một cơ duyên!
Zander

1
@kcoppock: Cảm ơn rất nhiều vì đã chia sẻ mã này. Điều tôi thích nhất là bạn có thể thay thế màu sắc cho hình ảnh bằng hình ảnh "thực" và được thay đổi kích thước đúng cách! Điều tôi muốn hiểu là nếu có thể thay đổi kích thước các khung nhìn để một số lượt xem nhất định lấp đầy toàn màn hình.
AntonSack

14

một cách tiếp cận đơn giản khác với các công cụ tích hợp hiện đại như PercentRelativeLayout hiện có sẵn cho những người dùng mới gặp phải vấn đề này. cảm ơn đội ngũ android đã phát hành mặt hàng này

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

và để có hiệu suất tốt hơn, bạn có thể sử dụng một số nội dung như trình tải hình ảnh picasso giúp bạn lấp đầy toàn bộ chiều rộng của mỗi phụ huynh hình ảnh. ví dụ trong bộ chuyển đổi của bạn, bạn nên sử dụng điều này:

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

bây giờ bạn không cần CustomImageView Class nữa.

PS tôi khuyên bạn nên sử dụng ImageView thay cho Type Int trong lớp Item.

hy vọng điều này giúp đỡ..


Với API 26.1, điều này đã bị lỗi. Xem liên kết
Dominikus K.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.