在Android中设置微调器onClickListener()

时间:2010-10-13 21:15:15

标签: java android onclick spinner

我正在尝试在Spinner上触发onClickListener,但是我收到以下错误:

  

Java.lang.RuntimeException是“不要为AdapterView调用setOnClickListener。你可能需要setOnItemClickListener,”

我确定我想调用onClickListener而不是onItemClickListener。我在Stack Overflow上找到了其他人提出的问题, Is there a way to use setOnClickListener with an Android Spinner?

答案是:

  

您必须设置Click   基础视图上的监听器   (通常是带有id的TextView:   微调器的android.R.id.text1)。至   这样做:

     

创建自定义微调器   构造函数(带属性)创建   通过提供布局来实现微调器   android.R.layout.simple_spinner_item   做一个findViewById(android.R.id.text1)   获取TextView Now设置   onClickListener到TextView

我已经尝试过那里提到的答案,但似乎没有用。在执行findViewById()之后,我得到一个指向TextView的空指针。

这就是我正在做的事情:

Spinner spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.layoutspinner,dataArray);

spinner.setAdapter(adapter);

TextView SpinnerText = (TextView)findViewById(R.id.spinnerText);
if (SpinnerText == null) {
    System.out.println("Not found");
}
else {
    SpinnerText.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {
            //Do something
        }
    });
}

文件layoutspinner.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
                  android:id="@+id/spinnerText"
                  android:singleLine ="true"
                  android:layout_width="fill_parent"
                  android:layout_height="wrap_content"
                  android:textSize="6pt"
                  android:gravity="right"/>

我做错了什么?

我是Stack Overflow的新手,我没有找到任何方法向另一个帖子发布一个aditional问题(或评论,因为我需要很少代表)所以我开始了一个新问题。

根据推荐,我试过这个:

int a = spinnerMes.getCount();
int b = spinnerMes.getChildCount();
System.out.println("Count = " + a);
System.out.println("ChildCount = " + b);
for (int i = 0; i < b; i++) {
    View v = spinnerMes.getChildAt(i);
    if (v == null) {
        System.out.println("View not found");
    }
    else {
        v.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Click code
            }
        });
    }
}

但是LogCat没有显示出有希望的结果。

10-14 16:09:08.127: INFO/System.out(3116): Count = 7
10-14 16:09:08.127: INFO/System.out(3116): ChildCount = 0

我已经在API级别7和8上对此进行了测试,结果相同。

7 个答案:

答案 0 :(得分:56)

这是一个有效的解决方案:

我们不是设置微调器的OnClickListener,而是设置OnTouchListener和OnKeyListener。

spinner.setOnTouchListener(Spinner_OnTouch);
spinner.setOnKeyListener(Spinner_OnKey);

和听众:

private View.OnTouchListener Spinner_OnTouch = new View.OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            doWhatYouWantHere();
        }
        return true;
    }
};
private static View.OnKeyListener Spinner_OnKey = new View.OnKeyListener() {
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
            doWhatYouWantHere();
            return true;
        } else {
            return false;
        }
    }
};

答案 1 :(得分:26)

每当您必须在Android中点击Spinner时执行某些操作,请使用以下方法。

mspUserState.setOnTouchListener(new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            doWhatIsRequired();
        }
        return false;
    }
});

要记住的一件事是在使用上述方法时总是返回 False 。如果您将返回 True ,则点击微调器时不会显示微调器的下拉项。

答案 2 :(得分:12)

就个人而言,我使用它:

    final Spinner spinner = (Spinner) (view.findViewById(R.id.userList));
    spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {                

            userSelectedIndex = position;
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
        }
    });  

答案 3 :(得分:5)

首先,微调器不支持项目点击事件。调用此方法将引发异常。

您可以使用setOnItemSelectedListener:

Spinner s1;
s1 = (Spinner)findViewById(R.id.s1);
int selectionCurrent = s1.getSelectedItemPosition();

spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
            if (selectionCurrent != position){
                // Your code here
            }
            selectionCurrent= position;
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> parentView) {
        // Your code here
    }
});

答案 4 :(得分:4)

以下是你想要的方式,但它并不理想。

public class Tester extends Activity {

    String[] vals = { "here", "are", "some", "values" };
    Spinner spinner;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        spinner = (Spinner) findViewById(R.id.spin);
        ArrayAdapter<String> ad = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, vals);
        spinner.setAdapter(ad);
        Log.i("", "" + spinner.getChildCount());
        Timer t = new Timer();
        t.schedule(new TimerTask() {

            @Override
            public void run() {
                int a = spinner.getCount();
                int b = spinner.getChildCount();
                System.out.println("Count =" + a);
                System.out.println("ChildCount =" + b);
                for (int i = 0; i < b; i++) {
                    View v = spinner.getChildAt(i);
                    if (v == null) {
                        System.out.println("View not found");
                    } else {
                        v.setOnClickListener(new View.OnClickListener() {

                            @Override
                            public void onClick(View v) {
                                        Log.i("","click");
                                        }
                        });
                    }
                }
            }
        }, 500);
    }
}

让我确切地知道你需要微调器如何表现,我们可以找到更好的解决方案。

答案 5 :(得分:2)

我建议Spinner的所有事件分为两种类型:

  1. 用户事件(您的意思是“点击”事件)。

  2. 计划活动。

  3. 我还建议,当你想要捕获用户事件时,你只想摆脱“程序事件”。所以这很简单:

    private void setSelectionWithoutDispatch(Spinner spinner, int position) {
        AdapterView.OnItemSelectedListener onItemSelectedListener = spinner.getOnItemSelectedListener();
        spinner.setOnItemSelectedListener(null);
        spinner.setSelection(position, false);
        spinner.setOnItemSelectedListener(onItemSelectedListener);
    }
    

    关键时刻:你需要setSelection(position,false)。动画参数中的“false”会立即触发事件。默认行为是将事件推送到事件队列。

答案 6 :(得分:0)

Spinner类实现DialogInterface.OnClickListener,从而有效劫持了标准View.OnClickListener

如果您不使用子类化的Spinner或不想使用它,请选择其他答案。

否则,只需将以下代码添加到自定义微调器中即可:

@Override
/** Override triggered on 'tap' of closed Spinner */
public boolean performClick() {
    // [ Do anything you like here ]
    return super.performClick();
}

示例:每当打开微调器时,通过Snackbar显示预先提供的提示:

private String sbMsg=null;      // Message seen by user when Spinner is opened.
public void setSnackbarMessage(String msg) { sbMsg=msg; }
@Override
/** Override triggered on 'tap' of closed Spinner */
public boolean performClick() {
    if (sbMsg!=null && !sbMsg.isEmpty()) { /* issue Snackbar */ }
    return super.performClick();
}

Trapping 'click' of closed Spinner

自定义Spinner是在整个项目中以编程方式标准化Spinner外观的绝佳起点。

如果有兴趣,请here