Search code examples
androidimageviewscale

Scale ImageView based on properties of another ImageView


I am trying to place an Imageview on top of another Imageview as follows:

Desired Outcome

This is the layout I use to achieve this:

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

    <ImageView
        android:id="@+id/list_item_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:adjustViewBounds="true"
        android:scaleType="fitXY"
        android:layout_gravity="center" />

    <ImageView
        android:id="@+id/list_item_logo"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:adjustViewBounds="true"
        android:scaleType="fitCenter"
        android:paddingLeft="10dp"
        android:paddingTop="10dp"
        android:layout_gravity="top|start" />
</FrameLayout>

This does the job of placing the logo on top of the image, but the catch here is that I should also scale the logo (the original size is around the same as the image) based on the properties of the image. More specifically, I want to render the logo at a quarter of the width of the image, have an aspect ratio of 1:1, and add 10% padding of the images' width.

At the moment, I'm just playing around with the values of layoutwidth, layoutheight, paddingLeft and paddingTop of the logo until I get the desired outcome. Is there a way to dynamically change the properties of the logo based on the properties of the image?

Any help is greatly appreciated.


Solution

  • Consider using a PercentRelativeLayout to achieve your desired layout, where your logo has 10% top and start margins, and 10% width (or whatever width percent you need). Note that the SquareImageView is a custom view currently at package com.example, and that it will ignore any height value given and will reset to the calculated width (Which is 10% of the image's width).

    Example XML:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <android.support.percent.PercentRelativeLayout
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_centerInParent="true">
    
    
            <ImageView
                android:id="@+id/image"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="#ff0000" />
    
            <com.example.SquareImageView
                android:id="@+id/logo"
                android:layout_alignParentLeft="true"
                android:layout_alignParentStart="true"
                android:layout_alignParentTop="true"
                android:background="#0000ff"
                app:layout_heightPercent="10%"
                app:layout_marginStartPercent="10%"
                app:layout_marginTopPercent="10%"
                app:layout_widthPercent="10%" />
    
    
        </android.support.percent.PercentRelativeLayout>
    </RelativeLayout>
    

    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);
        }
    
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth()); // Snap to width
        }
    }