如何从NumberPicker setOnValueChangedListener一个BaseAdapter里面里面、NumberPicker、setOnValueChangedListener、Ba

2023-09-07 10:02:38 作者:君悦君兮君不知

我想创建一个BaseAdapter其中每个元素都有NumberPicker和一个按钮。按钮的操作参数取决于采摘NumberPicker的价值。一个解决方案,我还以为是建立一个setOnClickListener(按钮)的NumberPicker的onValueChange内,问题是onValueChange当我改变了一些永远不会被解雇了。

I am trying to create a BaseAdapter which each element has a NumberPicker and a Button. The button's action parameters depends on the value picked in NumberPicker. One solution I thought was creating a setOnClickListener (of the button) inside the onValueChange of the NumberPicker, the problem is onValueChange never gets fired when I change the number.

我离开你的code,以使其更清晰:

I leave you the code to make it clearer:

public class Adapter extends BaseAdapter{
...

  public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        if (v == null)
        {
            LayoutInflater vi = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.row, null);
        }
        button = (Button) v.findViewById(R.id.button);
        numPick = (NumberPicker) v.findViewById(R.id.numPick);
        numPick.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
                val = newVal;
                button.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View arg0) {
                        actionToPerform(val);
                    }
                });
            }
        });

我该如何解决这个问题呢?谢谢!

How can I solve this problem? Thank you!

推荐答案

由于该适配器将重用的布局,则需要在创建布局来设置你的听众。移动按钮侦听出来。否则,它会被每个价值变动设置。下面是修改后的code:

Since the adapter will reuse the layout, you will need to set your listener when you create the layout. Move the button listener out. Otherwise, it will get set on every value change. Here is the revised code:

// Put the array as a member of your activity or fragment's class
// Remember to save it between life cycle event
// Initialize it to same size as your adapter data
int[] numValues;

public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    if (v == null)
    {
        LayoutInflater vi = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.row, null);

        final Button button = (Button) v.findViewById(R.id.button);
        final NumberPicker numPick = (NumberPicker) v.findViewById(R.id.numPick);

        button.setOnClickListener(new View.OnClickListener() {
                public void onClick(View arg0) {
                    // Get the position value from the tag field
                    int pos = (int)button.tag;
                    actionToPerform(numValues[pos]);
                }
            });

        numPick.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
        public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
              // Save the value in the number picker
              numPick.tag = newVal;
          }
        });
    }

    // Save the position in the button's tag field
    button.tag = position;
    // Restore picker value
    final NumberPicker numPick1 = (NumberPicker) v.findViewById(R.id.numPick);
    numPicker1.setValue(numValues[position]);

}

保存在标签字段中的数据将确保您得到正确的行的数据,单击按钮时。我不知道你的数据被再次presented所以我介绍一个int数组存储的值。否则,机械手将失去价值时,它得到重用。

Saving the data in the tag field will ensure you get the right row's data when the button is clicked. I don't know how your data is represented so I introduce a int array to store the values. Otherwise, the picker will lose the value when it gets reused.