2016-03-15 1 views
4

У меня есть два spinners, так что мой второй счетчик меняет параметры, которые он может предложить в соответствии с пунктом, выбранным в первом счетчике. Легко?Spinner with sub-spinner не работает как ожидалось

Пример: Если я выбираю «a» в главном счетчике, субпараметр должен показывать «a1» в качестве опции. Если я выберу «b» в главном счетчике, субпараметр должен отображать «b1», «b2» в качестве параметров. Если я выбираю «c» в главном счетчике, sub spinner должен отображать «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(); 
} 

Проблема: Какой элемент я нажимаю на основной блесны в первый раз, в соответствии с этим выбирается вспомогательный счетчик. Затем, если я сменю главный счетчик, дополнительный счетчик не изменится.

Вопрос раскрывается для предложений. Комментарий, если это не понятно.

+0

попробуйте с этим первым invalidateDataSet, а затем снова добавьте –

+0

@VivekMishra. Вы имеете в виду 'spinner_sub.invalidateDataSet()'? –

+0

да как это как данные в нем в зависимости от старого счетчика. вы сначала удаляете эти данные, а затем добавляете новый –

ответ

1

ошибка приходит из следующей функции в 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) становится истинным только первый раз, когда вы щелкните на вспомогательном блесны и, следовательно, он получает инициализирован правильно, и вы будете см. правильные значения. Однако, как только вы нажмете на вспомогательный счетчик, _item.size() никогда не будет равен нулю, и, таким образом, обновленные значения вспомогательных счетчиков никогда не будут отображаться.

Предлагаю вам использовать Android Spinner по умолчанию или переделать репозиторий и исправить ошибку и использовать ее.

EDIT

Вы можете попробовать использовать этот класс:

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. Возможно, это не лучший подход, но он работает.

EDIT 2

Вам нужно будет позвонить spinnerAdapter_sub.notifyDataChanged(true) после вызова spinnerAdapter_sub.notifyDataSetChanged();.

+0

Чтобы быть откровенным, мне будет сложно развить и решить проблему самостоятельно, но я хочу попробовать. Это будет первый раз для меня, чтобы развить и решить проблему. Поразите меня любыми другими подсказками, если сможете. Я ценю ваши усилия. –

+0

О, это должно сработать. Но прежде чем я попытаюсь, вы заслуживаете огромной благодарности. 21 час, чтобы отдать щедрость. Терпение. –

+0

Рад, что я мог бы помочь :) –

Смежные вопросы