Fixed aspect ratio View

后端 未结 9 1797
后悔当初
后悔当初 2020-12-04 10:50

How would I go implementing a fixed aspect ratio View? I\'d like to have items with 1:1 aspect ratio in a GridView. I think it\'s better to subclas

相关标签:
9条回答
  • 2020-12-04 11:44

    To not use third-party solution and considering the fact that both PercentFrameLayout and PercentRelativeLayout were deprecated in 26.0.0, I'd suggest you to consider using ConstraintLayout as a root layout for your grid items.

    Your item_grid.xml might look like:

    <android.support.constraint.ConstraintLayout
        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="wrap_content">
    
        <ImageView
            android:id="@+id/imageview_item"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:scaleType="centerCrop"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintDimensionRatio="H,1:1" />
    
    </android.support.constraint.ConstraintLayout>
    

    As a result you get something like this:

    0 讨论(0)
  • 2020-12-04 11:45

    I created a layout library using TalL's answer. Feel free to use it.

    RatioLayouts

    Installation

    Add this to the top of the file

    repositories {
        maven {
            url  "http://dl.bintray.com/riteshakya037/maven" 
        }
    }
    
    
    dependencies {
        compile 'com.ritesh:ratiolayout:1.0.0'
    }
    

    Usage

    Define 'app' namespace on root view in your layout

    xmlns:app="http://schemas.android.com/apk/res-auto"
    

    Include this library in your layout

    <com.ritesh.ratiolayout.RatioRelativeLayout
            android:id="@+id/activity_main_ratio_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:fixed_attribute="WIDTH" // Fix one side of the layout 
            app:horizontal_ratio="2" // ratio of 2:3
            app:vertical_ratio="3">
    

    Update

    With introduction of ConstraintLayout you don't have to write either a single line of code or use third-parties or rely on PercentFrameLayout which were deprecated in 26.0.0.

    Here's the example of how to keep 1:1 aspect ratio for your layout using ConstraintLayout:

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginEnd="0dp"
            android:layout_marginStart="0dp"
            android:layout_marginTop="0dp"
            android:background="@android:color/black"
            app:layout_constraintDimensionRatio="H,1:1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">
    
        </LinearLayout>
    
    </android.support.constraint.ConstraintLayout>
    
    0 讨论(0)
  • 2020-12-04 11:45

    The ExoPlayer from Google comes with an AspectRatioFrameLayout that you use like this:

    <com.google.android.exoplayer2.ui.AspectRatioFrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:resize_mode="fixed_width">
        <!-- https://exoplayer.dev/doc/reference/com/google/android/exoplayer2/ui/AspectRatioFrameLayout.html#RESIZE_MODE_FIXED_WIDTH -->
    
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
    </com.google.android.exoplayer2.ui.AspectRatioFrameLayout>
    

    Then you must set the aspect ratio programmatically:

    aspectRatioFrameLayout.setAspectRatio(16f/9f)
    

    Note that you can also set the resize mode programmatically with setResizeMode.


    Since you are obviously not going to grab the whole ExoPlayer library for this single class, you can simply copy-paste the file from GitHub to your project (it's open source):

    https://github.com/google/ExoPlayer/blob/release-v2/library/ui/src/main/java/com/google/android/exoplayer2/ui/AspectRatioFrameLayout.java

    Don't forget to grab the attribute resize_mode too:

    https://github.com/google/ExoPlayer/blob/release-v2/library/ui/src/main/res/values/attrs.xml#L18-L25

    <attr name="resize_mode" format="enum">
      <enum name="fit" value="0"/>
      <enum name="fixed_width" value="1"/>
      <enum name="fixed_height" value="2"/>
      <enum name="fill" value="3"/>
      <enum name="zoom" value="4"/>
    </attr>
    
    0 讨论(0)
提交回复
热议问题