Android Spinner : 초기화 중 onItemSelected 호출 방지
a Spinner
및 a를 사용하여 Android 애플리케이션을 만들었습니다 TextView
. TextView의 Spinner 드롭 다운 목록에서 선택한 항목을 표시하고 싶습니다. onCreate
프로그램 에서 Spinner를 구현 했으므로 프로그램을 실행할 때 TextView
(드롭 다운 목록에서 항목을 선택하기 전에)에 값이 표시됩니다.
드롭 다운 목록에서 항목을 선택한 후에 만 TextView에 값을 표시하고 싶습니다. 어떻게해야합니까?
내 코드는 다음과 같습니다.
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
public class GPACal01Activity extends Activity implements OnItemSelectedListener {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Spinner spinner = (Spinner) findViewById(R.id.noOfSubjects);
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,R.array.noofsubjects_array, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(this);
}
public void onItemSelected(AdapterView<?> parent, View arg1, int pos,long id) {
TextView textView = (TextView) findViewById(R.id.textView1);
String str = (String) parent.getItemAtPosition(pos);
textView.setText(str);
}
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}
spinner.setOnItemSelectedListener(this); // Will call onItemSelected() Listener.
따라서 Integer 값으로 처음 처리하십시오.
예 : 처음에 int check = 0;
public void onItemSelected(AdapterView<?> parent, View arg1, int pos,long id) {
if(++check > 1) {
TextView textView = (TextView) findViewById(R.id.textView1);
String str = (String) parent.getItemAtPosition(pos);
textView.setText(str);
}
}
부울 값으로 현재 위치와 이전 위치를 확인하여 수행 할 수 있습니다. 여기를 보아라
OnItemSelectedListener 를 설정하기 전에이 줄을 넣으십시오.
spinner.setSelection(0,false)
API 레벨 3부터는 부울이있는 활동에서 onUserInteraction ()을 사용하여 사용자가 디바이스와 상호 작용하는지 판별 할 수 있습니다.
http://developer.android.com/reference/android/app/Activity.html#onUserInteraction ()
@Override
public void onUserInteraction() {
super.onUserInteraction();
userIsInteracting = true;
}
내가 활동에 대한 필드로 :
private boolean userIsInteracting;
마지막으로 내 스피너 :
mSpinnerView.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View view, int position, long arg3) {
spinnerAdapter.setmPreviousSelectedIndex(position);
if (userIsInteracting) {
updateGUI();
}
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
활동을 진행하면서 부울은 false로 재설정됩니다. 매력처럼 작동합니다.
이것은 나를 위해 일했다
안드로이드에서 스피너의 초기화는 문제가 될 수 있으며 때로는 위의 문제가이 패턴으로 해결되었습니다.
Spinner.setAdapter();
Spinner.setSelected(false); // must
Spinner.setSelection(0,true); //must
Spinner.setonItemSelectedListener(this);
설정 어댑터는 첫 번째 부분이어야하고 스피너를 초기화 할 때 onItemSelectedListener (this)가 마지막이됩니다. 스피너 초기화 중에 내 OnItemSelected () 위의 패턴으로 호출되지 않습니다
하하 ... 같은 질문이 있습니다. initViews ()가 이렇게하면 시퀀스가 핵심이며 리스너가 마지막입니다. 행운을 빕니다 !
spinner.setAdapter(adapter);
spinner.setSelection(position);
spinner.setOnItemSelectedListener(listener);
내 해결책 :
protected boolean inhibit_spinner = true;
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int pos, long arg3) {
if (inhibit_spinner) {
inhibit_spinner = false;
}else {
if (getDataTask != null) getDataTask.cancel(true);
updateData();
}
}
이 방법으로이를 수행 할 수 있습니다.
AdapterView.OnItemSelectedListener listener = new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
//set the text of TextView
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
yourSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
yourSpinner.setOnItemSelectedListener(listener);
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
처음에는 리스너를 만들고 변수 콜백에 기여했습니다. 그런 다음 익명으로 두 번째 리스너를 만들고 이것이 처음 호출되면 리스너가 변경됩니다.]
그런 다음 onTouch 메소드에서 사용자 상호 작용 플래그를 true로 설정 onItemSelected()
하고 선택 변경이 처리되면 재설정 할 수 있습니다 . 사용자 상호 작용 플래그는 스피너에 대해서만 독점적으로 처리되며 원하는 동작에 영향을 줄 수있는 활동의 다른보기에는 적용되지 않기 때문에이 솔루션을 선호합니다.
코드에서 :
스피너에 대한 리스너를 작성하십시오.
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) {
userSelect = false;
// Your selection handling code here
}
}
}
리스너를 스피너에 an OnItemSelectedListener
및 an 모두로 추가하십시오 OnTouchListener
.
SpinnerInteractionListener listener = new SpinnerInteractionListener();
mSpinnerView.setOnTouchListener(listener);
mSpinnerView.setOnItemSelectedListener(listener);
초기화 중 spinner.setOnItemSelectedListener () 호출을 피하려면
spinner.setSelection(Adapter.NO_SELECTION, true); //Add this line before setting listener
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
Similar simple solution that enables multiple spinners is to put the AdapterView in a collection - in the Activities superclass - on first execution of onItemSelected(...) Then check to see if the AdapterView is in the collection before executing it. This enables one set of methods in the superclass and supports multiple AdapterViews and therefor multiple spinners.
Superclass ...
private Collection<AdapterView> AdapterViewCollection = new ArrayList<AdapterView>();
protected boolean firstTimeThrough(AdapterView parent) {
boolean firstTimeThrough = ! AdapterViewCollection.contains(parent);
if (firstTimeThrough) {
AdapterViewCollection.add(parent);
}
return firstTimeThrough;
}
Subclass ...
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if (! firstTimeThrough(parent)) {
String value = safeString(parent.getItemAtPosition(pos).toString());
String extraMessage = EXTRA_MESSAGE;
Intent sharedPreferencesDisplayIntent = new Intent(SharedPreferencesSelectionActivity.this,SharedPreferencesDisplayActivity.class);
sharedPreferencesDisplayIntent.putExtra(extraMessage,value);
startActivity(sharedPreferencesDisplayIntent);
}
// don't execute the above code if its the first time through
// do to onItemSelected being called during view initialization.
}
create a boolean field
private boolean inispinner;
inside oncreate of the activity
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (!inispinner) {
inispinner = true;
return;
}
//do your work here
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
Try this
spinner.postDelayed(new Runnable() {
@Override
public void run() {
addListeners();
}
}, 1000);.o
You could achieve it by setOnTouchListener first then setOnItemSelectedListener in onTouch
@Override
public boolean onTouch(final View view, final MotionEvent event) {
view.setOnItemSelectedListener(this)
return false;
}
This worked for me:
spinner.setSelection(0, false);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
spinner.setOnItemSelectedListener(listener);
}, 500);
Had the same problem and this works for me:
I have 2 spinners and I update them during init and during interactions with other controls or after getting data from the server.
Here is my template:
public class MyClass extends <Activity/Fragment/Whatever> implements Spinner.OnItemSelectedListener {
private void removeSpinnersListeners() {
spn1.setOnItemSelectedListener(null);
spn2.setOnItemSelectedListener(null);
}
private void setSpinnersListeners() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
spn1.setOnItemSelectedListener(MyClass.this);
spn2.setOnItemSelectedListener(MyClass.this);
}
}, 1);
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// Your code here
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
When the class is initiating use setSpinnersListeners() instead of directly setting the listener.
The Runnable will prevent the spinner from firing onItemSelected right after the you set their values.
If you need to update the spinner (after a server call etc.) use removeSpinnersListeners() right before your update lines, and setSpinnersListeners() right after the update lines. This will prevent onItemSelected from firing after the update.
Based on Abhi's answer i made this simple listener
class SpinnerListener constructor(private val onItemSelected: (position: Int) -> Unit) : AdapterView.OnItemSelectedListener {
private var selectionCount = 0
override fun onNothingSelected(parent: AdapterView<*>?) {
//no op
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
if (selectionCount++ > 1) {
onItemSelected(position)
}
}
}
'IT' 카테고리의 다른 글
파이썬과 BeautifulSoup을 사용하여 웹 페이지에서 링크를 검색 (0) | 2020.07.02 |
---|---|
`git :`url을`http :`url로 변환하는 방법 (0) | 2020.07.02 |
Visual Studio : 두 개의 별도 탭 그룹에서 동일한 파일을 어떻게 볼 수 있습니까? (0) | 2020.07.02 |
AND 대신 OR로 범위 쿼리를 연결하는 방법은 무엇입니까? (0) | 2020.07.02 |
ngSrc 경로가 404로 해석되면 기본값으로 대체하는 방법이 있습니까? (0) | 2020.07.02 |