Android / / 2020. 3. 13. 19:54

[Android] selector 를 통해 Layout 모든 요소에 터치 효과 만들기

어플리케이션을 사용하면서 화면중에 Text 또는 Image를 터치할 경우,

Text의 색상 변경, Image 변경, 투명도(alpha) 변경 등을 통해 사용자에게 이 부분을 터치하였다는 느낌을 줄 수 있습니다.

이러한 효과를 나타내기 위해서 selector xml을 이용할 수 있습니다.

아래에서 Layout 내부 요소 중 하나를 터치했을 경우 모든 요소에 터치 효과가 나타나는 예제를 만들도록 만들어보겠습니다

아래와 같이 직사각형 테두리를 가진 Layout 내부를 짧게 또는 길게 터치하면, 내부요소인 TextView 의 색상 및 ImageView의 이미지가 변경됩니다.

예제 결과물

1. selector xml (selector.xml)

 1) TextView의 TextView에 설정할 selector (selector_text_pressed.xml)

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
 
    <!-- View가 눌렸을 때 @color/colorAccent 색상으로 출력한다.-->
    <item android:color="@color/colorAccent" android:state_pressed="true"/>
 
    <!-- View가 눌리지 않았을 때 @color/colorPrimaryDark 색상으로 출력한다.-->
    <item android:color="@color/colorPrimaryDark" android:state_pressed="false"/>
 
</selector>
 

 

 2) ImageView의 Background 속성에 설정할 selector (selector_star_pressed.xml

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
 
    <!-- View가 눌렸을 때 @android:drawable/star_big_on 을 보여준다.-->
    <item android:drawable="@android:drawable/star_big_on" android:state_pressed="true" />
 
    <!-- View가 눌리지 않았을 때 @android:drawable/star_big_off 를 보여준다.-->
    <item android:drawable="@android:drawable/star_big_off" android:state_pressed="false" />
 
</selector>
 

selector xml의 이벤트중 유용하게 쓰일만한 속성들은 아래의 것들이 있습니다.

android:state_pressed = true(눌렸을때) or false(안눌렸을때)
android:state_checked = true(체크했을때) or false(체크해제시)
android:state_enabled = true(사용가능할때) or false(사용불가할때)
android:state_focused = true(포커스 되었을때) or false(포커스되지 않았을때)
android:state_selected = true(선택 되었을때) or false(선택되지 않았을때)

 

2. 메인 layout xml (activity_main.xml)

TextView의 TextColor에 selector를, 그리고 ImageView에 selector를 설정해주고,

android:duplicateParentState="true" 속성을 설정해줍니다.

해당 속성 설정을 통하여 상위 Container(Parent)인 layoutTouch가 터치될때

하위 View 요소들도 ParentState를 적용받아 터치된것처럼 효과가 나타나게됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?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">
 
    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/layoutTouch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:background="@drawable/bg_6597c4_border"
        android:padding="24dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">
 
        <TextView
            android:id="@+id/textTitleThis"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:duplicateParentState="true"
            android:text="이곳을"
            android:textColor="@color/selector_text_pressed"
            android:textSize="24sp"
            android:textStyle="bold"
            app:layout_constraintEnd_toStartOf="@+id/textTitleTouch"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
 
        <TextView
            android:id="@+id/textTitleTouch"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:duplicateParentState="true"
            android:text="터치해주세요"
            android:textColor="@color/selector_text_pressed"
            android:textSize="24sp"
            android:textStyle="bold"
            app:layout_constraintBaseline_toBaselineOf="@+id/textTitleThis"
            app:layout_constraintEnd_toStartOf="@+id/imgStar"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/textTitleThis" />
 
        <ImageView
            android:id="@+id/imgStar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:background="@drawable/selector_star_pressed"
            android:duplicateParentState="true"
            app:layout_constraintBottom_toBottomOf="@+id/textTitleTouch"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/textTitleTouch"
            app:layout_constraintTop_toTopOf="@+id/textTitleTouch" />
 
    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
 

 

3. MainActivity.kt

해당 예제는 layout의 View 요소 속성(textColor & background)를 직접 설정했기 때문에, 코틀린 코드로 작성한 부분은 없습니다.

Layout에 ClickListener를 설정하여, 터치시 간단한 Toast를 출력하도록 설정했습니다.

하지만 어떤 경우에 따라서는 분기 처리를 하여,

aaaaa의 경우에는 selector 1을, bbbbb의 경우에는 selector 2를 설정하도록, 코드 상에서 selector를 설정해줄 수도 있을것입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
 
class MainActivity : AppCompatActivity() {
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
 
 
        layoutTouch.setOnClickListener{
            // Layout 터치시 Toast Print
            Toast.makeText(this"Layout Touch", Toast.LENGTH_SHORT).show() 
        }
    }
}
 
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유