2015-01-02 1 views
4

세 개의 스피너가있는 레이아웃이 있습니다. 드롭 다운에 표시되는 옵션이 다릅니다. 내 onCreateView에는 회 전자를 설정하는 방법이 있습니다. 그 방법 안에는 다음과 같은 것이 있습니다 :화면 회전 후 Android 스피너 onItemSelected가 여러 번 호출되었습니다.

mySpinner = (Spinner) view.findViewById(R.id.my_spinner); 
    ArrayAdapter<String> mySpinner = 
      new ArrayAdapter<String>(getActivity(), R.layout.background, 
        new ArrayList<String>(Arrays.asList(getResources().getStringArray(R.array.spinner_one_data)))); 
    mySpinner.setDropDownViewResource(R.layout.spinner_text); 
    mySpinner.setAdapter(mySpinner); 
    mySpinner.setOnItemSelectedListener(this); 

제가 말했듯이, 다른 두 스피너는 거의 같지만 옵션은 다양합니다.

저는 "첫 번째 설정"의 모든 회 전자마다 한 번씩 onItemSelected이 호출되므로이 문제를 방지하는 플래그가 있음을 알고 있습니다. 이 플래그 솔루션으로 내 스피너가 예상대로 작동합니다. 문제는 각 회 전자에서 옵션을 선택한 다음 화면을 회전 할 때입니다. 자, onItemSelected은 내가 예상했던 3 번 대신 6 번 호출됩니다 (나는 3 번 호출의 상황을 관리하기위한 플래그를 설정했습니다).

왜 이런 일이 발생하고 괭이를 처리해야합니까?

+0

당신이 당신의 mainefest –

+0

번호 I에서 화면 회전을 처리 되세요 매니 페스트를 변경하고 싶지는 않습니다. 나는 그것을해야합니까? – Favolas

+0

mainefest를 변경하지 않고 응용 프로그램에 방향 변경시 요소를 다시 그리지 않도록 처리기를 추가하면 요소를 다시 그려서 메서드가 실행됩니다. –

답변

1

나는 저를 위해 작동하는 해결책을 찾아 냈습니다.

저는 3 스피너를 가지고 있으므로 onItemSelected은 초기 스피너 설정에서 3 번 호출됩니다. onItemSelected가 초기 설정에서 메소드를 실행하지 못하게하려면 onItemSelected 메소드 만 카운터 값을 발생 시키므로 카운터를 생성했습니다.

나는 내 상황에서 화면이 회전하면 3 번을 onItemSelected 번 다시 발생시키고 각 스피너에는 0이 아닌 시간을 더한 것을 알았습니다.

예 :

나는 3 스피너를 가지고 있고 사용자는 위치 0 그래서 그는이 같은 상황에 끝나는 다른 가능한 옵션 중 하나에의 2을 변경합니다

First spinner - > Item 2 selected 
Second spinner -> Item 0 selected (no changes) 
Third spinner -> Item 1 selected 

자, 내가 화면을 회전하면 onItemSelected는 초기 스피너 설정에 대해 3 번을 더한 후 0이 아닌 스피너의 경우 2 번 걸립니다.

@Override 
public void onSaveInstanceState(Bundle outState) { 
    int changedSpinners = 0; 
    if (spinner1.getSelectedItemPosition() != 0) { 
     changedSpinners += 1; 
    } 
    if (spinner2.getSelectedItemPosition() != 0) { 
     changedSpinners += 1; 
    } 
    if (spinner3.getSelectedItemPosition() != 0) { 
     changedSpinners += 1; 
    } 
    outState.putInt("changedSpinners", changedSpinners); 
} 

나는 onSaveInstanceState 상태를 저장 한 후, onCreateView에 나는 savedInstanceState != null 경우 확인하고 만약 그렇다면, 번들에서 changedSpinners을 추출하고 그에 따라 행동하는 내 카운터를 업데이트했습니다.

22

일반적으로 onItemSelected 메서드를 트리거 할 수있는 여러 이벤트가 있으며 모든 이벤트를 추적하기가 어렵다는 것을 발견했습니다. 대신 OnTouchListener를 사용하여 사용자가 시작한 변경에만 응답하는 것이 더 간단하다는 것을 알았습니다.

public class SpinnerInteractionListener implements AdapterView.OnItemSelectedListener, View.OnTouchListener { 

    boolean userSelect = false; 

    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     userSelect = true; 
     return false; 
    } 

    @Override 
    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { 
     if (userSelect) { 
      // Your selection handling code here 
      userSelect = false; 
     } 
    } 

} 

는 OnItemSelectedListener와 OnTouchListener 모두와 회 전자에 리스너를 추가합니다 : 스피너에 대한 리스너를 만듭니다

SpinnerInteractionListener listener = new SpinnerInteractionListener(); 
mSpinnerView.setOnTouchListener(listener); 
mSpinnerView.setOnItemSelectedListener(listener); 
+3

우수 답변, 감사합니다. 이것은 받아 들여진 대답이어야합니다. –

+1

android의 최악의 위젯을 처리하는 데 가장 좋은 답변입니다. – AlvaroSantisteban

관련 문제