Android Spinner:在初始化期间避免onItemSelected调用

问题描述 投票:120回答:14

我用SpinnerTextView创建了一个Android应用程序。我想在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

    }
}
android android-layout android-spinner
14个回答
153
投票
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);
   }
}

您可以使用布尔值以及检查当前位置和先前位置来执行此操作。 See here


2
投票

避免在初始化期间调用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) {

    }
});

2
投票

创建一个布尔字段

private boolean inispinner;

在里面创造活动

    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) {

        }
    });

2
投票

试试这个

spinner.postDelayed(new Runnable() {
        @Override
        public void run() {
            addListeners();
        }
    }, 1000);.o

1
投票

有同样的问题,这对我有用:

我有2个微调器,我在初始化期间以及与其他控件交互期间或从服务器获取数据后更新它们。

这是我的模板:

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) {

    }
}

当类启动时使用setSpinnersListeners()而不是直接设置监听器。

Runnable将在您设置其值后立即阻止微调器触发onItemSelected。

如果需要更新微调器(在服务器调用之后等),请在更新行之前使用removeSpinnersListeners(),并在更新行之后使用setSpinnersListeners()。这将阻止onItemSelected在更新后触发。


1
投票

你可以先通过setOnTouchListener实现它,然后再通过onTouch实现setOnItemSelectedListener

@Override
public boolean onTouch(final View view, final MotionEvent event) {
 view.setOnItemSelectedListener(this)
 return false;
}

78
投票

只需在设置OnItemSelectedListener之前放置此行

spinner.setSelection(0,false)

58
投票

从API级别3开始,您可以在具有布尔值的Activity上使用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。奇迹般有效。


16
投票

这对我有用

Spinner在Android中的初始化是有问题的,有时上述问题通过这种模式解决了。

Spinner.setAdapter();
Spinner.setSelected(false);  // must
Spinner.setSelection(0,true);  //must
Spinner.setonItemSelectedListener(this);

设置适配器应该是第一部分,onItemSelectedListener(this)在初始化微调器时将是最后一个。通过上面的模式,在初始化微调器期间不会调用我的OnItemSelected()


10
投票

哈哈......我有同样的问题。当initViews()只是这样做时。序列是关键,监听器是最后一个。祝好运 !

spinner.setAdapter(adapter);
spinner.setSelection(position);
spinner.setOnItemSelectedListener(listener);

7
投票

我的解决方案

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();
            }

        }

6
投票

你可以通过这种方式做到这一点:

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) {

        }
    });

首先,我创建一个监听器并归因于一个变量回调;然后我创建第二个匿名监听器,当第一次调用时,这会改变监听器=]


2
投票

启用多个微调器的类似简单解决方案是将AdapterView放在一个集合中 - 在活动超类中 - 首次执行onItemSelected(...)然后在执行之前检查AdapterView是否在集合中。这使得超类中的一组方法成为可能,并支持多个AdapterView以及多个微调器。

超级......

private Collection<AdapterView> AdapterViewCollection = new ArrayList<AdapterView>();

   protected boolean firstTimeThrough(AdapterView parent) {
    boolean firstTimeThrough = ! AdapterViewCollection.contains(parent);
    if (firstTimeThrough) {
       AdapterViewCollection.add(parent);
     }
    return firstTimeThrough;
   }

子类......

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.

}


2
投票

然后,可以在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
        }
    }

}

将侦听器作为OnItemSelectedListenerOnTouchListener添加到微调器:

SpinnerInteractionListener listener = new SpinnerInteractionListener();
mSpinnerView.setOnTouchListener(listener);
mSpinnerView.setOnItemSelectedListener(listener);
© www.soinside.com 2019 - 2024. All rights reserved.