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

listview.setItemChecked

0 추천

int Spos;로 전역변수하나 만들고 oncreate에

listview에 single_choice를 설정한후 list에 아이템 0,1,2,3,4

추가한후 setOnItemClickListener로 onclick되었을때

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  Spos=position;
}
위치를 받아온후에  Spos에 위치를 받아온다음에
리스너아래에 list.setItemChecked(Spos,true);로 다음에
 들어올때 list가체크된상태로 받고싶은데 엑티비티 나갔다가
 다시들어오니까 체크가 해제되어있네여 ㅠㅠ 전역변수Spos가 함수나가면서
초기화가 된건가요? 아니면 list.setItemChecked위치가 잘못된건가요?
 어떻게 엑티비티 다시 들어왔을때 체크되어있게 만드는지 궁금해요
류니 (540 포인트) 님이 2021년 11월 16일 질문

1개의 답변

+1 추천
 
채택된 답변

onStart나 onResume에 리스트뷰의 위치를 초기화하는 코드를 집어넣으세요.

@Override
protected void onStart () {
    super.onStart();
    // 리스트뷰에 데이터 로딩
    // 리스트뷰 위치초기화 
}

 

한가지 알아두셔할 점이 있는데, 안드로이드에서 전역변수는 주의해서 사용하셔야 합니다. 안드로이드에서는 크게 두가지를 고려해서 앱이 디자인 되어야 합니다. 디바이스 로테이션(회전)와 process death. 

전자의 경우는 AndroidManifest.xml에 별도로 세팅을 하지 않는 한(권장값), 앱은 종료되지 않고 현재의 액티비티가 다시 생성되게 됩니다. 따라서 액티비티 안에 사용하고 있던 상태값들을 보관해 주셔야 복구가 가능합니다. 이게 Bundle을 사용하는 이유 중의 하나입니다. 최근에는 ViewModel을 도입함으로써 이런 부분의 해결이 많이 쉬워졌습니다.

후자는 실제로 필드에서 많이 발생하는 경우인데(많은 앱들이 처리를 하지 않아서 Firebase Analytics와 같은 툴로 보면 이유없이 앱크래시로 보여지는 사례가 많습니다.), 앱이 백그라운드로 갔다가 돌아올 때, 시스템이 시스템 리소스가 달린다고 판단할 경우 백그라운드에 있는 앱을 아무런 통보없이 죽일 수 있습니다. 이 때 사용자가 최근 사용한 앱(디바이스에 있는 네모버튼)에서 앱을 클릭해서 시작할 경우, 앱을 다시 실행시켜주는게 아니라 마지막 사용했던 액티비티만 복구해 주게 됩니다. 따라서 전역변수가 static이라도 초기화될 수가 있기 때문에 어떤 상태를 위해서 전역변수를 사용하는 건 안드로이드에서는 피하는게 좋고, 이런 상태를 저장하는 용도로 사용하기 위해 도입된 것이 SaveStateHandle입니다.  이건 process death 후에도 살아남고 ViewModel과 조합해서 사용합니다. 이게 왜 구글에서 ViewModel을 홍보하는 이유이고 자신들도 ViewModel을 주된 앱 아키텍쳐로 가져가는 이유입니다.

그리고 디바이스의 개발자 세팅에 따라 액티비티를 하나만 유지하도록 할 수도 있고, 앱 프로세스를 한개만 유지하도록 설정이 가능합니다. 이건 process death 등과 같은 상황을 시뮬레이션해보도록 지원하는 겁니다.

위에서 말씀드렸다시피,  아이템이 눌린 포지션을 받아오는 변수는 전역으로 사용하지 마시고 해당 액티비티 또는 프레그먼트의 멤버변수로 사용하세요. 화면간 값전달은 bundle로 하시구요. 만약 전역변수를 부득이하게 사용해야 하는 상황이면 모든 액티비티의 onSaveInstance에 해당 변수를 저장했다 onCreate에서 복구해서 사용하셔야 해요.

@Override
protected void onCreate (Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     if (savedInstance != null) {
         Spos = savedInstanceState.getInt("Spos", 0);
     }
}

@Override
protected void onSaveInstanceState (Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putExtra("Spos", Spos);
}

 

spark (227,530 포인트) 님이 2021년 11월 17일 답변
류니님이 2021년 11월 17일 채택됨
감사합니다 덕분에 잘 해결되었습니다!
...