안드로이드 이미지버튼 원형 - andeuloideu imijibeoteun wonhyeong

안녕하세요

안드로이드 스튜디오[Android Studio]에서 버튼에 이미지를 넣는 방법에 대해서 알아보겠습니다

안드로이드 스튜디오에서는 버튼에 배경화면에 이미지를 넣는 것 말고도 이미지와 텍스트가 같이 보이도록 설정을 할 수 있습니다

버튼 속성의 drawableLeft / Right / Top / Bottom 속성입니다

이 속성의 사용법에 대해서 알아보겠습니다

사용 방법

1. 디자인 xml에 버튼을 추가합니다

2. 버튼에 추가할 이미지를 가져옵니다

 버튼에 추가할 이미지를 복사해서 res - drawable 폴더에 복사합니다

 png 파일을 복사해서 가져왔습니다

안드로이드 이미지버튼 원형 - andeuloideu imijibeoteun wonhyeong

3. 버튼의 속성(Attributes)에서 drawable속성에 산 모양을 선택합니다

 저는 텍스트의 하단에 이미지를 추가할 것이므로 drawableBottom 속성에 이미지를 추가하겠습니다

안드로이드 이미지버튼 원형 - andeuloideu imijibeoteun wonhyeong

4. 산 모양을 선택하면 이미지 선택 팝업이 나타납니다

 방금 전에 추가한 이미지를 선택합시다!

안드로이드 이미지버튼 원형 - andeuloideu imijibeoteun wonhyeong

5. 결과 화면입니다

 버튼 하단에 이미지가 들어간 것까지는 좋지만... 이미지가 너무 큽니다

 이어서 이미지의 크기를 조정하는 방법에 대해서 알아보겠습니다

안드로이드 이미지버튼 원형 - andeuloideu imijibeoteun wonhyeong

이미지 크기 조정(추가 tip)

1. drawble에 xml파일을 하나 만듭니다

 ※ xml파일은 소문자만 입력이 가능합니다

  저는 coding_dogxml.xml로 만들었습니다

안드로이드 이미지버튼 원형 - andeuloideu imijibeoteun wonhyeong

2. xml에 이미지정보와 크기, 넓이정보를 넣습니다

 하단의 소스를 참고바랍니다

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@drawable/coding_dog"
        android:width="60dp"
        android:height="60dp" />
</layer-list>

3. 메인페이지로 넘어가서 button의 drawable 속성을 변경해줍니다

 변경은 방금 추가한 xml파일로 변경합니다

 저는 coding_dogxml.xml 파일을 불러왔습니다

안드로이드 이미지버튼 원형 - andeuloideu imijibeoteun wonhyeong

4. 결과화면입니다

 위에서부터 차례대로

 drawableBottom, drawableTop, drawableLeft, drawableRight 속성에 이미지를 추가한 것입니다

 실제 안드로이드 화면에서 왼편과 같이 출력되는 것을 확인할 수 있습니다

안드로이드 이미지버튼 원형 - andeuloideu imijibeoteun wonhyeong

여기까지 버튼에 이미지를 추가하는 방법에 대해서 알아봤습니다

이 글이 안드로이드 스튜디오 개발에 있어서 도움이 되셨으면 좋겠습니다!

안드로이드 이미지버튼 원형 - andeuloideu imijibeoteun wonhyeong
Glide Logo

안드로이드 작업을 하던 중 이미지뷰를 동그랗게 표시해야 하는 상황을 만났다. 카카오톡의 프로필 사진이 동그랗게 표시되는 것과 유사한 형태의 작업이었다. 당연히 안드로이드의 기본 UI를 통해 아주 간단하게 할 수 있을줄 알았는데, 세상 일이 그리 만만치 않았다.

언제나 나를 실망시키지 않는 안드로이드에 실망하면서 방법을 찾아보니 꼼수로 원형으로 뚤린 프레임을 만들어 이미지뷰 위에 덮어 씌우는 방법이 가장 간단한 방법인 것 같았다. 그런데, 내 경우에는 원형 뒤의 배경이 투명이어서 적용이 불가능한 방법이었다.

가장 정석대로 하려면 최종 Texture를 건드릴 수 있는 TextureView를 만들어 쉐이더로 연산을 하는 방법이 있는데 이 방법은 내가 하려는 일에 비해 배보다 배꼽이 큰 방법이었다.

결국 결론 적으로 선택한 방법은 동그란 모양으로 표시해주는 CircleImageView 라이브러리를 사용하는 방법과 GlidecenterCrop 옵션을 이용하는 방법이었다. 전자의 방법을 먼저 사용하다가 Glide에서 로딩한 GIF를 출력하니 스틸 이미지로 출력이 되어 후자의 방법을 찾아 알게 되었다. 두 방법에 대해 남겨본다.

CircleImageView

CircleImageView의 소스코드와 설명은 여기에서 찾을 수 있다. 사용 방법은 아주 간단한데 먼저 build.gradle (app)의 dependencies에 다음 내용을 추가해 준다.

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    ...
    implementation 'de.hdodenhof:circleimageview:3.1.0'
    ...
}

다음으로 레이아웃에서 원형으로 출력하기 원하는 부분에 CircleImageView를 추가해 준다. 예를 들어 100x100 크기의 myimage.png를 동그란 모양으로 출력하고 싶다면 다음과 같이 해준다.

<de.hdodenhof.circleimageview.CircleImageView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:src="@drawable/myimage" />

자, 이제 앱을 실행하면 동그란 이미지가 나타나는 것을 확인할 수 있다.

Glide.centerCrop()

글라이드를 사용한 이미지 표시 방법은 이 블로그의 여기에서 찾을 수 있다. myimage.png를 myimageview에 출력하는 방법은 다음과 같다.

Glide.with(this).load(R.drawable.myimage).circleCrop().into(myimageview);

간단한 코드이지만 아주 깔끔하게 동그란 이미지가 출력되는 것을 확인할 수 있다.

Example

종합 예제로 원본 이미지, CircleImageView를 통한 이미지, Glide의 centerCrop()을 통한 이미지, 마지막으로 Glide의 centerCrop()을 통해 GIF를 출력하는 방법을 남겨본다.

sample.png 파일은 drawable 폴더에 있고 sample.gif 파일은 raw폴더에 존재한다고 가정한다. 예제에서는 차이점을 보여주기 위해 GIF파일의 한 프레임을 캡처한 png 파일을 사용했는데 다음이 각각의 파일들이다.

안드로이드 이미지버튼 원형 - andeuloideu imijibeoteun wonhyeong
sample.png
안드로이드 이미지버튼 원형 - andeuloideu imijibeoteun wonhyeong
sample.gif

예제 코드는 다음과 같다.

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 이미지 표시
        loadImages();
    }

    protected void loadImages() {
        // 이미지뷰 가져오기
        ImageView view0 = (ImageView) findViewById(R.id.image0);
        CircleImageView view1 = (CircleImageView) findViewById(R.id.image1);
        ImageView view2 = (ImageView) findViewById(R.id.image2);
        ImageView view3 = (ImageView) findViewById(R.id.image3);

        // 원본 이미지 표시
        view0.setImageResource(R.drawable.sample);

        // CircleImageView로 표시
        view1.setImageResource(R.drawable.sample);

        // Glide CircleCrop으로 표시
        Glide.with(this).load(R.drawable.sample).circleCrop().into(view2);

        // Glide CircleCrop으로 GIF 표시
        Glide.with(this).load(R.raw.sample).circleCrop().into(view3);
    }
 }

예제에서 image0은 sample.png를 원본 그대로 보여준다. image1에는 같은 sample.png를 CircleImageView를 통해 원형으로 잘라 보여준다. image2에는 Glide의 circleCrop()을 통해 같은 원형 이미지를 보여준다. 마지막으로 image3에는 GIF 애니메이션을 원형으로 보여준다. 다음은 앱 실행 결과이다.

안드로이드 이미지버튼 원형 - andeuloideu imijibeoteun wonhyeong
예제 앱 실행 결과

참고로 이 예제의 레이아웃은 다음과 같다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:background="@android:color/white">
        <ImageView
            android:id="@+id/image0"
            android:layout_gravity="center_horizontal"
            android:layout_width="250dp"
            android:layout_height="0dp"
            android:layout_weight="20">
        </ImageView>
        <TextView
            android:layout_gravity="center_horizontal"
            android:gravity="center_horizontal|center_vertical"
            android:layout_width="250dp"
            android:layout_height="0dp"
            android:layout_weight="5"
            android:text="Original">
        </TextView>
        <de.hdodenhof.circleimageview.CircleImageView
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:id="@+id/image1"
            android:layout_gravity="center_horizontal"
            android:layout_width="250dp"
            android:layout_height="0dp"
            android:layout_weight="20"/>
        <TextView
            android:layout_gravity="center_horizontal"
            android:gravity="center_horizontal|center_vertical"
            android:layout_width="250dp"
            android:layout_height="0dp"
            android:layout_weight="5"
            android:text="CircleImageView">
        </TextView>
        <ImageView
            android:id="@+id/image2"
            android:layout_gravity="center_horizontal"
            android:layout_width="250dp"
            android:layout_height="0dp"
            android:layout_weight="20">
        </ImageView>
        <TextView
            android:layout_gravity="center_horizontal"
            android:gravity="center_horizontal|center_vertical"
            android:layout_width="250dp"
            android:layout_height="0dp"
            android:layout_weight="5"
            android:text="Glide CircleCrop">
        </TextView>
        <ImageView
            android:id="@+id/image3"
            android:layout_gravity="center_horizontal"
            android:layout_width="250dp"
            android:layout_height="0dp"
            android:layout_weight="20">
        </ImageView>
        <TextView
            android:layout_gravity="center_horizontal"
            android:gravity="center_horizontal|center_vertical"
            android:layout_width="250dp"
            android:layout_height="0dp"
            android:layout_weight="5"
            android:text="Glide CircleCrop GIF">
        </TextView>
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

Fin.