java – 带有子微调器的Spinner无法按预期工作

我有两个
spinners,这样我的第二个微调器就会根据第一个微调器中选择的项目更改它可以提供的选项.简单?

示例:如果我在主微调器中选择“a”,则子微调器应显示“a1”作为选项.如果我在主微调器中选择’b’,则子微调器应显示’b1′,’b2’作为选项.如果我在主微调器中选择’c’,则子微调器应显示’c1′,’c2′,’c3’作为选项.

我使用一个名为SearchableSpinner的库,但这并不重要,因为它就像Android微调器一样.

public class PostComplaint extends AppCompatActivity {
    String[] problems_main = {"a","b","c"};
    String[][] problems_sub = {{"a1"},{"b1","b2"},{"c1","c2","c3"}};

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_post_complaint);

    spinner_main = (SearchableSpinner)findViewById(R.id.spinner_main);
    spinner_sub = (SearchableSpinner) findViewById(R.id.spinner_sub);

    ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, problems_main);
    spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner_main.setAdapter(spinnerAdapter);
    spinnerAdapter.notifyDataSetChanged();

    spinner_main.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            setSubSpinner(position);
        }
        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            Toast.makeText(PostComplaint.this, "Nothing selected", Toast.LENGTH_SHORT).show();
        }
    });
}

void setSubSpinner(int i){
    String[] myArray = problems_sub[i]; //Note: problems_sub is a two dimensional array
    ArrayAdapter<String> spinnerAdapter_sub = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, myArray);
    spinnerAdapter_sub.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner_sub.setAdapter(spinnerAdapter_sub);
    spinnerAdapter_sub.notifyDataSetChanged();
}

问题:根据选择的子微调器,我第一次点击主微调器上的任何一个项目.然后,如果我更改主微调器,则子微调器不会更改.

这个问题是开放的建议.评论是否不可理解.

最佳答案 由于SearchableSpinner类中的以下函数,错误即将发生:

@Override
public boolean onTouch(View v, MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        ArrayAdapter adapter = (ArrayAdapter) getAdapter();

        if (null != adapter) {

            if (_items.size() == 0) {
                for (int i = 0; i < adapter.getCount(); i++) {
                    _items.add(adapter.getItem(i));
                }
            }
            SearchableListDialog searchableListDialog = SearchableListDialog.newInstance
                    (_items);
            searchableListDialog.setOnSearchableItemClickListener(this);
            searchableListDialog.show(((Activity) _context).getFragmentManager(), "TAG");
        }
    }
    return true;
}

条件if(_items.size()== 0)仅在您第一次单击子微调器时变为true,因此它会正确初始化并且您将看到正确的值.但是,一旦单击了子微调器,_item.size()将永远不会为零,因此,永远不会渲染更新的子微调器值.

我建议你使用默认的Android Spinner或分叉存储库并修复错误并使用相同的错误.

编辑

您可以尝试使用此类:

import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Spinner;

import com.toptoche.searchablespinnerlibrary.SearchableListDialog;

import java.util.ArrayList;
import java.util.List;

public class CustomSearchableSpinner extends Spinner implements View.OnTouchListener,
    SearchableListDialog.SearchableItem {

private Context _context;
private List _items;
private boolean isDataSetChanged;

public CustomSearchableSpinner(Context context) {
    super(context);
    this._context = context;
    this.isDataSetChanged = true;
    init();
}

public CustomSearchableSpinner(Context context, AttributeSet attrs) {
    super(context, attrs);
    this._context = context;
    this.isDataSetChanged = true;
    init();
}

public CustomSearchableSpinner(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    this._context = context;
    this.isDataSetChanged = true;
    init();
}

private void init() {
    _items = new ArrayList();
    setOnTouchListener(this);
}

@Override
public boolean onTouch(View v, MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        ArrayAdapter adapter = (ArrayAdapter) getAdapter();

        if (null != adapter) {

            if (isDataSetChanged) {
                if(_items.size() != 0) {
                    _items = new ArrayList();
                }
                for (int i = 0; i < adapter.getCount(); i++) {
                    _items.add(adapter.getItem(i));
                }
                isDataSetChanged = false;
            }
            SearchableListDialog searchableListDialog = SearchableListDialog.newInstance
                    (_items);
            searchableListDialog.setOnSearchableItemClickListener(this);
            searchableListDialog.show(((Activity) _context).getFragmentManager(), "TAG");
        }
    }
    return true;
}

@Override
public void onSearchableItemClicked(Object item, int position) {
    setSelection(_items.indexOf(item));
}

public void notifyDataChanged(Boolean hasDataChanged) {
    this.isDataSetChanged = hasDataChanged;
}
}

此外,更新您的布局文件和PostComplaint类以使用CustomSearchableSpinner代替Searchable Spinner.它可能不是最好的方法,但它有效.

编辑2

调用spinnerAdapter_sub.notifyDataSetChanged();后,需要调用spinnerAdapter_sub.notifyDataChanged(true).

点赞