마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

thread 사용 시 textview 초기화

0 추천

안녕하세요. 제가 현재 LinearLayout(vertical) 내부에 2개의 LinearLayout(horizontal)이 존재하는데 첫번째 LinearLayout에는 textView가 5개 들어가있고, 두번째 LinearLayout에는 또 다시 LinearLayout(vertical)이 5개 들어가있습니다.

tvtvtvtvtv




LinearLayout


 



LinearLayout

 



LinearLayout

 



LinearLayout

 



LinearLayout

 

5개의 TextView에는 오늘 날짜를 시작으로 5일치의 날짜가 적혀있고,

밑의 5개의 LinearLayout에는 각각 날짜에 맞게 데이터값(view)이 들어가있습니다.

 

이를 onResume() 함수에서 1분에 한번씩 새로고침 하는 코드를 작성해줬고, LinearLayout 내부의 view들을 모두 초기화 해준 후 다시 불러주는 코드를 넣어주니 LinearLayout은 새로고침이 잘 동작하는데,

날짜가 바뀌었을때(다음날이 되었을 때) TextView는 자동으로 바뀌지 않습니다.

그래서 LinearLayout 내부의 view들을 초기화 할 때 textView도 초기화해줘야할지,

날짜가 바뀔 때만 textView를 초기화했다가 다시 불러오는 방식으로 하고싶은데 어떻게 해줘야할지 잘 모르겠습니다. 

코드는 다음과 같습니다.

 @Override
    protected void onResume() {         // 사용자와 상호작용 하는 단계 / Activity 스택의 Top 에 위치 / 주로 어플 기능이 OnResume()에 설정됨
        super.onResume();

        // 1분마다 refresh
        if (thread == null) {
            thread = new Thread() {
                @Override
                public void run() {
                    try {
                        while (true) {
                            synchronized (this) {
                                Thread.sleep(60000);        // 60000 : 60초

                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        refresh();
                                    }
                                });
                            }
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            thread.start();
        }

        // 오늘 토요일
        if (Globals.getCurrentNextDate(0, "EE").equals("토")) {
            CurrentNextDate(2, 3, 4, 5, 6);     // 0: 토, 1: 일
        }
        // 내일 토요일
        else if (Globals.getCurrentNextDate(1, "EE").equals("토")) {
            CurrentNextDate(0, 3, 4, 5, 6);     // 1: 토, 2: 일
        }
        // 세번째 날 토요일
        else if (Globals.getCurrentNextDate(2, "EE").equals("토")) {
            CurrentNextDate(0, 1, 4, 5, 6);     // 2: 토, 3: 일
        }
        // 네번째 날 토요일
        else if (Globals.getCurrentNextDate(3, "EE").equals("토")) {
            CurrentNextDate(0, 1, 2, 5, 6);     // 3: 토, 4: 일
        }
        // 다섯번째 날 토요일
        else if (Globals.getCurrentNextDate(4, "EE").equals("토")) {
            CurrentNextDate(0, 1, 2, 3, 6);     // 4: 토, 5: 일
        }
        // 여섯번째 날 토요일
        else if (Globals.getCurrentNextDate(5, "EE").equals("토")) {
            CurrentNextDate(0, 1, 2, 3, 4);     // 5 : 토, 6: 일
        }
    }

    public void CurrentNextDate(int day1, int day2, int day3, int day4, int day5) {
        tv_day1.setText(Globals.getCurrentNextDate(day1, "M월 dd일 (EE)"));
        tv_day2.setText(Globals.getCurrentNextDate(day2, "M월 dd일 (EE)"));
        tv_day3.setText(Globals.getCurrentNextDate(day3, "M월 dd일 (EE)"));
        tv_day4.setText(Globals.getCurrentNextDate(day4, "M월 dd일 (EE)"));
        tv_day5.setText(Globals.getCurrentNextDate(day5, "M월 dd일 (EE)"));
    }


    public void refresh() {
        // refresh 시 Layout 내 View 들 모두 초기화
        ll_day1.removeAllViews();
        ll_day2.removeAllViews();
        ll_day3.removeAllViews();
        ll_day4.removeAllViews();
        ll_day5.removeAllViews();

        fnLoadCalendar();  // 연결된 DB 불러오기
        db_update();
    }

 

오이52 (290 포인트) 님이 2022년 4월 27일 질문

2개의 답변

+1 추천
 
채택된 답변

Date 변경은 시스템에서 BroadCastReceiver를 통해 이벤트를 받아야 합니다. 근데, 이것만으로 모든 날짜 변경 이벤트를 받을 수는 없는 것으로 보이니 확인해 보시기 바랍니다. 간단한 버전의 BroadCastReciever입니다.

package com.mpark.myapplication.util;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

import androidx.annotation.NonNull;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import java.util.Date;

public abstract class DateChangeReceiver extends BroadcastReceiver {

    private Date currentDate;

    public void register(Context context, Date date) {
        currentDate = date;

        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_TIME_CHANGED);
        filter.addAction(Intent.ACTION_DATE_CHANGED);
        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
        context.registerReceiver(this, filter);

        if (!DateUtil.isSameDay(currentDate, date)) {
            onDateChanged(currentDate, date);
            currentDate = date;
        }
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Date now = new Date();
        if (!DateUtil.isSameDay(currentDate, now)) {
            onDateChanged(currentDate, now);
            currentDate = now;
        }
    }

    protected abstract void onDateChanged(Date oldDate, Date newDate);
}

 

public static boolean isSameDay(Date date1, Date date2) {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(date1);

        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(date2);

        return calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR)
                && calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH)
                && calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH);
    }

 

public class MainActivity extends AppCompatActivity {

    private DateChangeReceiver dateChangeReceiver = new DateChangeReceiver() {
        @Override
        public void onDateChanged(Date oldDate, Date newDate) {
            System.out.println("***** Date changed *****");
        }
    };

    @Override
    protected void onStart() {
        super.onStart();
        dateChangeReceiver.register(this, new Date());
    }

    @Override
    protected void onStop() {
        super.onStop();
        unregisterReceiver(dateChangeReceiver);
    }
}

 

 대충 테스트한 클래스이므로 BroadCastReceiver에 대해 공부하시면서 진행하시기 바랍니다.

 

spark (226,420 포인트) 님이 2022년 4월 28일 답변
오이52님이 2022년 4월 29일 채택됨
질문 내용 뿐만 아니라 고쳐야하는 코드 부분까지 설명해주셔서 감사합니다!
알려주신대로 더 공부하겠습니다~!
+1 추천

질문과는 다르지만, 꼭 개선을 하셔야할 것 같아 적습니다. 각 요일에 해당하는 레이아웃을 커스텀 컴포넌트로 만드세요. XML에 직접 레이아웃을 넣고 그 안에 텍스트뷰를 넣고 관리하는 건 너무 복잡해져서 피하셔야 할 것 같아요.

아래처럼 요일뷰를 만드시고, 이걸 다섯개 연결한 뷰를 하나 더 만드셔서 액티비티에서 사용하세요.

layout/view_days.xml

<merge 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="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    tools:ignore="RtlSymmetry"
    tools:parentTag="android.widget.LinearLayout">

    <TextView
        android:id="@+id/titleTxt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?attr/textAppearanceBody1"
        android:textStyle="bold"
        tools:text="@string/app_name" />

    <TextView
        android:id="@+id/event1Txt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:text="@string/app_name" />

    <TextView
        android:id="@+id/event2Txt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:text="@string/app_name" />

    <TextView
        android:id="@+id/event3Txt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:text="@string/app_name" />

    <TextView
        android:id="@+id/event4Txt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:text="@string/app_name" />

    <TextView
        android:id="@+id/event5Txt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:text="@string/app_name" />

</merge>

 

public class DayView extends LinearLayout {
    private TextView titleTxt, event1Txt, event2Txt, event3Txt, event4Txt, event5Txt;

    public DayView(Context context) {
        super(context);
        init(null, 0);
    }

    public DayView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, 0);
    }

    public DayView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs, defStyle);
    }

    private void init(AttributeSet attrs, int defStyle) {
        setOrientation(LinearLayout.VERTICAL);
        LayoutInflater.from(getContext()).inflate(R.layout.view_day, this, true);
        bindViews();

        final TypedArray a = getContext().obtainStyledAttributes(
                attrs, R.styleable.DayView, defStyle, 0);

        String title = a.getString(R.styleable.DayView_title);
        setTitle(title);
        a.recycle();
    }

    private void bindViews() {
        titleTxt = findViewById(R.id.titleTxt);
        event1Txt = findViewById(R.id.event1Txt);
        event2Txt = findViewById(R.id.event2Txt);
        event3Txt = findViewById(R.id.event3Txt);
        event4Txt = findViewById(R.id.event4Txt);
        event5Txt = findViewById(R.id.event5Txt);
    }

    public CharSequence getTitle() {
        return titleTxt.getText();
    }

    public void setTitle(CharSequence value) {
        titleTxt.setText(value);
    }
}

 

values/attrs.xml

<resources>
    <declare-styleable name="DayView">
        <attr name="title" format="string" />
    </declare-styleable>
</resources>

 

layout/view_weekdays.xml

<merge 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="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    tools:ignore="RtlSymmetry"
    tools:parentTag="android.widget.LinearLayout">

    <com.mpark.myapplication.customview.DayView
        android:id="@+id/mondayView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        app:title="월요일"
     />

    <com.mpark.myapplication.customview.DayView
        android:id="@+id/tuesdayView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <com.mpark.myapplication.customview.DayView
        android:id="@+id/wednesdayView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <com.mpark.myapplication.customview.DayView
        android:id="@+id/thursdayView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <com.mpark.myapplication.customview.DayView
        android:id="@+id/fridayView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />
</merge>

 

spark (226,420 포인트) 님이 2022년 4월 28일 답변
...