首页 文章

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

提问于
浏览
96

我用 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

    }
}

12 回答

  • 135
    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

  • 1

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

    spinner.setSelection(0,false)
    
  • 1

    从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 . 奇迹般有效 .

  • 2

    这对我有用

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

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

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

  • 7

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

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

    我的解决方案

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

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

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

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

  • 10

    启用多个微调器的类似简单解决方案是将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.
    

    }

  • 63

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

    我有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在更新后触发 .

  • 49

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

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

    然后,可以在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);
    
  • 11

    To avoid calling spinner.setOnItemSelectedListener() during initialization

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

相关问题