본문 바로가기
안드로이드 자바

[Java][Android] Handler를 활용한 텍스트 자동 타이핑 애니메이션

by teamnova 2025. 1. 1.
728x90

 

안녕하세요,

 

오늘은 Handler를 활용하여 자동으로 타이핑되고 삭제되는 예제를 만들어보도록 하겠습니다. 

 

MainActivity.java


public class MainActivity extends AppCompatActivity {

    // 타이핑 애니메이션을 보여줄 TextView
    private TextView typingTextView;

    // UI 스레드에서 실행되는 Handler (MainLooper를 사용하여 생성)
    private Handler handler = new Handler(Looper.getMainLooper());

    // 타이핑 애니메이션에 표시할 텍스트 배열
    private String[] texts = {
            "오늘도 좋은 하루 되세요!",
            "오늘 점심 메뉴는 뭔가요?",
            "산책 한번 해보세요"
    };

    // 현재 표시 중인 텍스트의 인덱스
    private int textIndex = 0;

    // 현재 텍스트에서 표시 중인 문자 인덱스
    private int charIndex = 0;

    // 삭제 애니메이션 중인지 여부를 나타내는 플래그
    private boolean isDeleting = false;

    // 커서(`|`)가 표시되고 있는지 여부를 나타내는 플래그
    private boolean showCursor = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 레이아웃에서 TextView를 찾음
        typingTextView = findViewById(R.id.typingTextView);

        // 타이핑 애니메이션 시작
        startTypingAnimation();
    }

    // 타이핑 애니메이션을 시작하는 메서드
    private void startTypingAnimation() {
        // 타이핑 애니메이션을 처리하는 Runnable 실행
        handler.postDelayed(typingRunnable, 150);

        // 커서 깜박임 애니메이션을 처리하는 Runnable 실행
        handler.postDelayed(cursorBlinkRunnable, 500);
    }

    // 타이핑 애니메이션을 처리하는 Runnable
    private Runnable typingRunnable = new Runnable() {
        @Override
        public void run() {
            if (!isDeleting) { // 텍스트를 추가하는 단계
                if (charIndex < texts[textIndex].length()) {
                    // 현재 텍스트의 일부와 커서를 표시
                    typingTextView.setText(texts[textIndex].substring(0, charIndex + 1) + (showCursor ? "|" : ""));
                    charIndex++; // 다음 문자로 이동
                    handler.postDelayed(this, 150); // 150ms 후 다음 문자 표시
                } else {
                    isDeleting = true; // 텍스트 추가가 완료되면 삭제 단계로 전환
                    handler.postDelayed(this, 1000); // 1초 대기 후 삭제 시작
                }
            } else { // 텍스트를 삭제하는 단계
                if (charIndex > 0) {
                    // 현재 텍스트의 일부와 커서를 표시
                    typingTextView.setText(texts[textIndex].substring(0, charIndex - 1) + (showCursor ? "|" : ""));
                    charIndex--; // 이전 문자로 이동
                    handler.postDelayed(this, 100); // 100ms 후 다음 문자 삭제
                } else {
                    isDeleting = false; // 텍스트 삭제가 완료되면 추가 단계로 전환
                    textIndex = (textIndex + 1) % texts.length; // 다음 텍스트로 이동 (순환)
                    handler.postDelayed(this, 500); // 500ms 대기 후 타이핑 재개
                }
            }
        }
    };

    // 커서 깜박임 애니메이션을 처리하는 Runnable
    private Runnable cursorBlinkRunnable = new Runnable() {
        @Override
        public void run() {
            // 커서의 상태를 반전
            showCursor = !showCursor;

            // 현재 텍스트에 커서를 추가하거나 제거
            String currentText = typingTextView.getText().toString();
            if (currentText.endsWith("|") || currentText.endsWith("")) {
                typingTextView.setText(currentText.replace("|", "") + (showCursor ? "|" : ""));
            }

            // 500ms 후 다시 커서 깜박임 처리
            handler.postDelayed(this, 500);
        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 액티비티가 종료될 때 모든 Handler 작업을 제거
        handler.removeCallbacks(typingRunnable);
        handler.removeCallbacks(cursorBlinkRunnable);
    }
}

 

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    android:background="#FFFFFF">

    <TextView
        android:id="@+id/typingTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="24sp"
        android:textColor="#000000"
        android:gravity="center"/>
</LinearLayout>

 

시연 영상입니다.