한이음 프로젝트로 앱 개발을 거의 마무리하고 사용자 테스트를 진행하고 있는데

오늘 회의에서 얘기한 결과, 폰트의 가독성에 대한 피드백이 많이 있어서 폰트를 수정했다.

 

나눔스퀘어체로 수정했는데 글자 자체는 깔끔하지만 줄간격이 너무 좁아서 빼곡한 느낌이 있었다.

 

 

앱에서 제공하는 진단테스트, 상담 채팅 기능에서는 한 화면에 많은 양의 텍스트가 보이는데

이렇게 글자가 빼곡하면 가독성이 저하된다고 판단해서 줄간격을 넓히는 방법을 찾아보았다.

 

방법은 android:lineSpacingExtra 속성을 사용하는 것이었다.

 

<TextView
...
android:lineSpacingExtra="5dp"
/>

 

이런 식으로 특정 TextView에 직접 속성을 지정해줘도 되고

나는 앱 전체 텍스트에 적용이 되도록 style.xml에 TextView의 스타일을 지정했다.

 

values > style.xml

  <style name="TextViewFontStyle" parent="@android:style/Widget.DeviceDefault.TextView">
      <item name="android:fontFamily">@font/custom_font_family</item>
      <item name="android:textSize">16sp</item>
      <item name="android:lineSpacingExtra">5sp</item>
  </style>

 

참고로 custom_font_family는 폰트자체 속성을 지정하기 위해 작성한 것으로, 코드는 다음과 같다.

 

font > custom_font.family.xml

<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <font
        android:font="@font/nanumsquare"
        android:fontStyle="normal"
        android:fontWeight="500"
        app:font="@font/nanumsquare"
        app:fontStyle="normal"
        app:fontWeight="500"
        tools:ignore="ResourceCycle" />

</font-family>

 

font 폴더에 있는 나눔스퀘어 ttf를 지정했다.

 


 

 

줄간격 수정 전후를 비교해보았을 때 가독성이 훨씬 좋아졌다.

안드로이드 스튜디오 앱 개발 프로젝트를 진행하면서 다크모드는 생각도 못하고 있었는데

다크모드를 적용하고 앱을 실행하면 레이아웃의 많은 부분이 원치 않게 깨지는 현상을 발견했다.

 

res - values - themes 폴더에 일반/다크모드 전용 themes.xml 파일이 있어서

원하는 사람은 themes.xml (night) 파일을 수정하여 다크모드에 맞게 따로 디자인을 적용해도 좋을 것 같으나

나는 다크모드를 지원하지 않는 방법을 찾아보았다.

 

 

앱을 실행할 때 가장 먼저 실행되는 액티비티인 로딩 화면(스플래시 화면) java 파일 onCreate 메소드에

다음과 같이 코드를 작성했다.

public class ActivitySplash extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); //다크모드 지원 X
	//생략
    }
}

 

이렇게 작성하면 AppCompatActivity를 상속한 클래스는 다크모드를 킨 상태로 앱을 이용하더라도

다크모드 테마가 아닌 기본 테마가 적용이 된다.

 

하지만 일부 페이지는 위의 코드를 작성해도 다크모드가 적용되는 것을 발견했는데

AppCompatActivity가 아닌 Activity를 상속한 클래스들이었다.

따라서 해당 클래스들을 모두 AppCompatAcitivty를 상속하도록 수정했다.

 

이로써 다크모드 적용으로 인해 앱의 디자인이 원치 않게 깨지는 현상을 막을 수 있었다!

Dialogflow를 사이트 자체에서 세팅하는 것도 어려운 일이었는데

이것을 앱 화면에 띄우기 위해 Android Studio 내에서 코드를 짜는 것도 역시 어려운 일이었다.

관련 라이브러리가 무엇이 있는지도 모르고 어떤 메소드를 사용해야하고,

어떤 로직을 짜야하는지 너무 막막했기 때문이다.

 

그런 와중에 발견한 한줄기의 빛...!!!!🌟

 

https://youtu.be/zVxDBBCdpfY

 

영상으로 방법도 순서대로 알려주었으며

더보기란에 해당 코드의 GitHub 주소도 나와있어 많은 참고가 되었다!!

 

adapter, helper, interface, model 등 사용하는 파일이 많아 헷갈릴 수 있으나

해당 코드의 작동 원리를 분석하게된 덕분에 각 구성요소의 역할들을 학습할 수 있었다.

  • Adapter 패턴 사용

 

1. RecyclerView 태그 추가

  • 원하는 화면 xml 파일에 다음과 같이 추가
<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" />

 

2. 데이터.java 생성

  • model 폴더
  • 변수, 생성자, Get/Set 함수 만들기 (우클릭 → Generate)

 

3. 데이터_item.xml 생성

  • 각 데이터별 카드 디자인
  • CardView를 활용함
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:cardBackgroundColor="#FFFFFF"
        app:cardCornerRadius="10dp"
        app:cardElevation="5dp"
        app:cardUseCompatPadding="true">

    </androidx.cardview.widget.CardView>

</LinearLayout>

 

4. 데이터Adapter.java 생성

  • extends RecyclerView.Adapter<데이터Adapter.ViewHolder>
  • public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType){}
  • public void onBindViewHolder(ViewHolder viewHolder, int position){}
  • public int getItemCount(){}
  • static class ViewHolder extends RecyclerView.ViewHolder{} 등등 추가
package org.techtown.recyclerview;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

public class 데이터Adapter extends RecyclerView.Adapter<데이터Adapter.ViewHolder> {
    ArrayList<데이터> items = new ArrayList<데이터>();

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
        View itemView = inflater.inflate(R.layout.person_item, viewGroup, false);

        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
        데이터 item = items.get(position);
        viewHolder.setItem(item);
    }

    @Override
    public int getItemCount() {
        return items.size();
    }

    static class ViewHolder extends RecyclerView.ViewHolder{
        TextView textView; //데이터_item.xml 내부의 요소

        public ViewHolder(View itemView){
            super(itemView);

            textView = itemView.findViewById(R.id.textView);
        }

        public void setItem(데이터 item){
            textView.setText(item.getName());
        }
    }

    public void addItem(데이터 item){
        items.add(item);
    }

    public void setItems(ArrayList<데이터> items){
        this.items = items;
    }

    public 데이터 getItem(int position){
        return items.get(position);
    }

    public void setItem(int position, 데이터 item){
        items.set(position, item);
    }
}

 

5. 원하는 화면(RecyclerView를 포함한 화면)과 관련된.java에 코드 추가

  • LayoutManager 이용해서 recyclerView 레이아웃 설정
  • Adapter 생성 후 addItem
  • RecyclerView에 Adapter을 이용해서 데이터 넘기기
RecyclerView recyclerView = findViewById(R.id.recyclerView);

        LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(layoutManager);
        PersonAdapter adapter = new PersonAdapter();

        adapter.addItem(new 데이터("데이터1","데이터1속성"));
				adapter.addItem(new 데이터("데이터2","데이터2속성"));
				adapter.addItem(new 데이터("데이터3","데이터3속성"));
        recyclerView.setAdapter(adapter);

 

+ Recent posts