【问题标题】:Landscape and Vertical images in GridView (how to auto crop/scale)GridView 中的横向和纵向图像(如何自动裁剪/缩放)
【发布时间】:2015-05-06 12:38:55
【问题描述】:

我想在每个“单元格”都是一个 ImageView 的 GridView 中向用户展示设备上的所有缩略图。如果所有照片都是横向方向,这看起来不错:每个缩略图都是矩形并被裁剪成相同的大小(我假设这就是缩略图在设备上生成/存储的方式)。

但是,垂直 方向的照片(和缩略图)会导致问题。高大的缩略图拉伸了单元格,使 UI 看起来很糟糕:

凌乱的用户界面

简洁的用户界面

什么是处理这个问题的好方法?也许我应该简单地在 ImageViews 上设置一些最大高度,手动裁剪(或缩放)垂直拇指?这样的事情应该用 XML 还是 Java 代码来完成?

更新:另一个奇怪的事情是设备依赖性(一如既往)。上面的图片来自模拟器 (Nexus 7),而下面是同一个应用在我的(物理)Sony Xperia Z1 紧凑型上的外观。请注意,所有垂直缩略图(和图像)都自动旋转,因此所有缩略图都具有相同的高尺寸...

以下是相关文件:

布局/fragment_main.xml

<FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    tools:context=".MainActivity$PhotoFragment">

    <GridView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:numColumns="4"
        android:id="@+id/listview_photo"
        style="@style/ForecastListStyle"
        />

</FrameLayout>

布局/grid_item_gallery.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:padding="1dp"
    android:layout_height="match_parent">

    <ImageView
        android:layout_height="wrap_content"
        android:scaleType="center"
        android:layout_width="fill_parent"
        android:id="@+id/grid_item_photo" />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:textAppearanceSmall"
        android:fontFamily="sans-serif-light"
        android:id="@+id/grid_item_label" />

</LinearLayout>

PhotoFragment.java

public class PhotoFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {

    private final static int LOADER_ID = 87;
    private PhotoAdapter mPhotoAdapter;
    private GridView mGridView;

    // these are the data we want from MediaStore
    private final static String[] THUMBNAIL_COLUMNS = {
            PhotoContract.ThumbEntry.COLUMN_THUMB_ID,
            PhotoContract.ThumbEntry.COLUMN_DATA,
            PhotoContract.ThumbEntry.COLUMN_IMAGE_ID
    };

    static final int COL_THUMB_ID = 0;
    static final int COL_THUMB_DATA = 1;
    static final int COL_THUMB_IMAGE_ID = 2;

    public PhotoFragment() {
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        getLoaderManager().initLoader(LOADER_ID, null, this);
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);

        mPhotoAdapter = new PhotoAdapter(getActivity(), null, 0);
        GridView gridView = (GridView) rootView.findViewById(R.id.listview_photo);
        gridView.setAdapter(mPhotoAdapter);

        mEmptyView = (TextView) rootView.findViewById(R.id.list_empty);
        mGridView = gridView;

        return rootView;
    }

    @Override
    public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
        Uri thumbs_uri = MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI;
        return new CursorLoader(getActivity(), thumbs_uri, THUMBNAIL_COLUMNS,
                null,null,  // read everything (all thumbnails)
                MediaStore.Images.Thumbnails._ID + " DESC");
    }

    @Override
    public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
        int antall = 0;
        if (cursor != null) 
            mPhotoAdapter.swapCursor(cursor);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> cursorLoader) {
        mPhotoAdapter.swapCursor(null);
    }

}

PhotoAdapter.java

public class PhotoAdapter extends CursorAdapter {

    public PhotoAdapter(Context context, Cursor c, int flags) {
        super(context, c, flags);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        View view = LayoutInflater.from(context).inflate(R.layout.grid_item_gallery, parent, false);
        ViewHolder viewHolder = new ViewHolder(view);
        view.setTag(viewHolder);
        return view;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        ViewHolder viewHolder = (ViewHolder) view.getTag();

        long imgId = cursor.getLong(PhotoFragment.COL_THUMB_ID);

        String thumbData = cursor.getString(PhotoFragment.COL_THUMB_DATA);
        Bitmap thumbBitmap = BitmapFactory.decodeFile(thumbData);
        viewHolder.iconView.setImageBitmap(thumbBitmap);
        viewHolder.lbl.setText("Photo " + imgId);
    }

    public static class ViewHolder {
        public final ImageView iconView;
        public final TextView lbl;

        public ViewHolder(View view) {
            iconView = (ImageView) view.findViewById(R.id.grid_item_photo);
            lbl = (TextView) view.findViewById(R.id.grid_item_label);
        }
    }
}

【问题讨论】:

    标签: android user-interface gridview imageview


    【解决方案1】:

    我认为一个解决方案可能是通过 xml 文件在 ImageView 中设置 android:layout_height="sizeThatYouLike"

    【讨论】:

    • 为什么投反对票?这不是一个正确的解决方案吗?请解释一下原因。我仍在学习,解释会对我有所帮助。谢谢
    • 如果我设置 layout_width="100dp" 和 layout_height="100dp",我会得到方形缩略图,是的。不知道为什么您的建议被否决了...但是这是最好的方法吗?对于numColumns=4,就像我现在所做的那样,这看起来不错,但是如果列数发生变化怎么办?为了根据屏幕大小和方向调整布局,我将实际列数提取为values/integers.xml (4)、values-sw600dp/integers.xml (4) 和values-sw720dp-land/integers.xml (6)。 是否可以将图像大小设置为类似, screenWidth/@integer/number_thumb_columns
    • 设置 layout_width="match_parent" 和 layout_height="100dp"
    • 这似乎可以解决问题,是的 :-) 现在缩略图的宽度与列宽成正比!因此,如果我减少列数,缩略图会更宽,反之亦然。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2019-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-01
    • 1970-01-01
    • 2018-02-22
    相关资源
    最近更新 更多