How to Implement Shapeable ImageView in Android? - GeeksforGeeks

20 Dec, 2021
In Android, ShapeableImageView is used to change the shape of your image to circle, diamond, etc. Also, you can set a corner radius to your ImageView. You can do much more by using this ShapeableImageView with minimal code. So in this article, we are going to make a ShapableImageView in android. By implementing this application we will get a basic idea of how editing of photos is done in android applications. Here we will implement two features i.e to cut or round the corners of an image.
Here we will be using two images, one image we will edit with XML code and the other with java code. Using SeekBar the user can round or cut all four corners of the image separately. Note that we are going to implement this application using Java language. A sample video is given below to get an idea about what we are going to do in this article.
Step 1: Creating a new project
Open a new project.
We will be working on Empty Activity with language as Java. Leave all other options unchanged.
You can change the name of the project at your convenience.
There will be two default files named activity_main.xml and MainActivity.java.
If you don’t know how to create a new project in Android Studio then you can refer to How to Create/Start a New Project in Android Studio? 
Step 2: Adding the required dependency
Open Gradle Scripts > build.gradle(module). Go to app > right click > open module settings > dependencies > Add dependency > Library dependency.
Type material in the search bar and click on search. Select the dependency shown in the below image-
Click on sync now to save the changes.
Step 3: Working with the activity_main.xml file
Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Below is the code for the activity_main.xml file. 
XML
<?xml version="1.0" encoding="utf-8"?>  <!-- Linear layout as parent layout--><LinearLayout    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:orientation="vertical"    android:padding="16dp"    android:gravity="center"    tools:context=".MainActivity">        <!-- text view to show the text "using xml"-->    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Using xml"        android:textStyle="bold"        android:textSize="20sp"        android:padding="12dp"        />        <!-- shapable image view-->    <com.google.android.material.imageview.ShapeableImageView        android:layout_width="339dp"        android:layout_height="230dp"        android:adjustViewBounds="true"        android:scaleType="centerCrop"        android:src="@drawable/gfg"        app:shapeAppearance="@style/CornerCut" />          <!-- text view to show the text "using java"-->    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Using Java"        android:textSize="20sp"        android:textStyle="bold"        android:padding="12dp"        />         <!-- shapable image view-->    <com.google.android.material.imageview.ShapeableImageView        android:layout_width="339dp"        android:layout_height="230dp"        android:layout_weight="1"        android:id="@+id/image_View"        android:src="@drawable/gfg"        android:adjustViewBounds="true"        android:scaleType="centerCrop"        />          <!-- spinner to provide options of round and cur-->    <Spinner        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/sp_family"        android:padding="12dp"        android:layout_marginTop="16dp"        />          <!-- seekbar for top left corner-->    <SeekBar        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/sb_top_left"        android:layout_marginTop="16dp"        />          <!-- seekbar for top right corner-->    <SeekBar        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/sb_top_right"        android:layout_marginTop="8dp"        />          <!-- seekbar for bottom left corner-->    <SeekBar        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/sb_bottom_left"        android:layout_marginTop="8dp"        />          <!-- seekbar for bottom right corner-->    <SeekBar        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/sb_bottom_right"        android:layout_marginTop="8dp"        />  </LinearLayout>
Step 4: Working on themes.xml file
Navigate to res > values > themes > themes.xml file and use the below code in it.
XML
<resources xmlns:tools="http://schemas.android.com/tools">    <!-- Base application theme. -->    <style name="Theme.ShapableImageView" parent="Theme.MaterialComponents.DayNight.DarkActionBar">        <!-- Primary brand color. -->        <item name="colorPrimary">@color/purple_500</item>        <item name="colorPrimaryVariant">@color/purple_700</item>        <item name="colorOnPrimary">@color/white</item>        <!-- Secondary brand color. -->        <item name="colorSecondary">@color/teal_200</item>        <item name="colorSecondaryVariant">@color/teal_700</item>        <item name="colorOnSecondary">@color/black</item>        <!-- Status bar color. -->        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>        <!-- Customize your theme here. -->    </style>          <style name="CornerCut" parent="">        <item name="cornerFamilyTopLeft">rounded</item>        <item name="cornerFamilyTopRight">cut</item>        <item name="cornerFamilyBottomLeft">cut</item>        <item name="cornerFamilyBottomRight">rounded</item>        <item name="cornerSizeTopLeft">50%</item>        <item name="cornerSizeTopRight">25%</item>        <item name="cornerSizeBottomLeft">25%</item>        <item name="cornerSizeBottomRight">50%</item>      </style></resources>
After executing the above code design of the activity_main.xml file looks like this.
Step 5: Working with the MainActivity.java file
Go to the MainActivity.java file and refer to the following code. Below is the code for the MainActivity.java file. Comments are added inside the code to understand the code in more detail.
Java
package com.example.shapableimageview;  import androidx.appcompat.app.AppCompatActivity;  import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.ArrayAdapter;import android.widget.SeekBar;import android.widget.Spinner;  import com.google.android.material.imageview.ShapeableImageView;import com.google.android.material.shape.CornerFamily;  import java.util.ArrayList;  public class MainActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener {      // Initialize variable    ShapeableImageView imageView;    Spinner spFamily;    SeekBar sbTopLeft,sbTopRight,sbBottomLeft,sbBottomRight;    int cornerFamily= CornerFamily.CUT,topLeft=0,topRight=0,bottomLeft=0,bottomRight=0;      @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);          // assign variable        imageView=findViewById(R.id.image_View);        spFamily=findViewById(R.id.sp_family);        sbTopLeft=findViewById(R.id.sb_top_left);        sbTopRight=findViewById(R.id.sb_top_right);        sbBottomLeft=findViewById(R.id.sb_bottom_left);        sbBottomRight=findViewById(R.id.sb_bottom_right);          // Initialize array list        ArrayList<String> arrayList=new ArrayList<>();                  // add values in array List        arrayList.add("cut");        arrayList.add("rounded");          // set adapter        spFamily.setAdapter(new ArrayAdapter<>(MainActivity.this,                android.R.layout.simple_spinner_dropdown_item,arrayList));          // Set Listener on spinner        spFamily.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {            @Override            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {                // check condition                if(position==0)                {                    // when cut selected                    cornerFamily=CornerFamily.CUT;                }                else                {                    // when rounded selected                    cornerFamily=CornerFamily.ROUNDED;                }                  // create update method                updateImage();            }              @Override            public void onNothingSelected(AdapterView<?> parent) {              }        });          // set listener on all seekbar        sbTopLeft.setOnSeekBarChangeListener(this);        sbTopRight.setOnSeekBarChangeListener(this);        sbBottomRight.setOnSeekBarChangeListener(this);        sbBottomLeft.setOnSeekBarChangeListener(this);    }      private void updateImage() {        // set appearance        imageView.setShapeAppearanceModel(imageView.getShapeAppearanceModel().toBuilder()                .setTopLeftCorner(cornerFamily,topLeft)                .setTopRightCorner(cornerFamily,topRight)                .setBottomLeftCorner(cornerFamily,bottomLeft)                .setBottomRightCorner(cornerFamily,bottomRight)                .build());    }      @Override    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {        switch (seekBar.getId())        {            case R.id.sb_top_left:                                    topLeft=progress;                                    break;            case R.id.sb_top_right:                                    topRight=progress;                                    break;            case R.id.sb_bottom_left:                                    bottomLeft=progress;                                    break;            case R.id.sb_bottom_right:                                    bottomRight=progress;                                    break;        }        // call update method        updateImage();    }      @Override    public void onStartTrackingTouch(SeekBar seekBar) {      }      @Override    public void onStopTrackingTouch(SeekBar seekBar) {      }}
Here is the final output of our application.
Output:
Android
Java
Java
Android
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Resource Raw Folder in Android Studio
Flutter - Custom Bottom Navigation Bar
How to Read Data from SQLite Database in Android?
How to Post Data to API using Retrofit in Android?
Retrofit with Kotlin Coroutine in Android
Arrays in Java
Split() String method in Java with examples
For-each loop in Java
Object Oriented Programming (OOPs) Concept in Java
Arrays.sort() in Java with examples