7

Tôi đang tạo một spinner có thể tìm kiếm bằng thư viện của bên thứ ba. Tôi đã thêm các lớp thư viện (SearchableListDialog, SearchableSpinner) vào ứng dụng của mình. Tất cả mọi thứ đang hoạt động tốt nhưng vẫn còn một vấn đề tôi đang phải đối mặt ví dụ, Trong widget tìm kiếm xem nếu tôi tìm kiếm Abc, tôi không nhận được kết quả lọc như Abc nhưng khi nhấp vào mục danh sách xem, kết quả sẽ hiển thị mục Abc. Nó giống như vị trí là thay đổi cho các mục nhưng danh sách không hiển thị kết quả tìm kiếm được. Tôi không nhận được nơi tôi là sai. Tôi đã sửa đổi mã nhiều lần nhưng không nhận được kết quả mong muốn.Làm thế nào để sử dụng SearchView.OnQueryTextListener() trong spinner có thể tìm kiếm?

enter image description here

Searchable Spinner đang xml:

<com.example.my.currencyconverterapp.activity.SearchableSpinner 
        android:id="@+id/spinner" 
        android:layout_below="@+id/rl_currency_converterted_data" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" /> 

Đây là mã Fragment tôi, nơi tôi đang thiết lập một adapter để spinner tìm kiếm.

countriesCustomAdapterInr = new CountriesCustomAdapterInr(getActivity(), R.layout.custom_spinner_items, arrayList,res); 
     spinner.setAdapter(countriesCustomAdapterInr); 
     assert spinner != null; 
     spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 
      @Override 
      public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) { 
       Toast.makeText(getActivity(), ""+arrayList.get(i).getFull_name()+i, Toast.LENGTH_LONG).show(); 
      } 

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

Đây là bên thứ ba lớp SearchableSpinner:

public class SearchableSpinner extends android.support.v7.widget.AppCompatSpinner implements View.OnTouchListener, 
     SearchableListDialog.SearchableItem { 

    public static final int NO_ITEM_SELECTED = -1; 
    private Context _context; 
    private List _items; 
    private SearchableListDialog _searchableListDialog; 

    private boolean _isDirty; 
    private ArrayAdapter _arrayAdapter; 
    private String _strHintText; 
    private boolean _isFromInit; 

    public SearchableSpinner(Context context) { 
     super(context); 
     this._context = context; 
     init(); 
    } 

    public SearchableSpinner(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     this._context = context; 
     TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SearchableSpinner); 
     final int N = a.getIndexCount(); 
     for (int i = 0; i < N; ++i) { 
      int attr = a.getIndex(i); 
      if (attr == R.styleable.SearchableSpinner_hintText) { 
       _strHintText = a.getString(attr); 
      } 
     } 
     a.recycle(); 
     init(); 
    } 

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

    private void init() { 
     _items = new ArrayList(); 
     _searchableListDialog = SearchableListDialog.newInstance 
       (_items); 
     _searchableListDialog.setOnSearchableItemClickListener(this); 
     setOnTouchListener(this); 

     _arrayAdapter = (ArrayAdapter) getAdapter(); 
     if (!TextUtils.isEmpty(_strHintText)) { 
      ArrayAdapter arrayAdapter = new ArrayAdapter(_context, android.R.layout 
        .simple_list_item_1, new String[]{_strHintText}); 
      _isFromInit = true; 
      setAdapter(arrayAdapter); 
     } 
    } 

    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     if (event.getAction() == MotionEvent.ACTION_UP) { 

      if (null != _arrayAdapter) { 

       // Refresh content #6 
       // Change Start 
       // Description: The items were only set initially, not reloading the data in the 
       // spinner every time it is loaded with items in the adapter. 
       _items.clear(); 
       for (int i = 0; i < _arrayAdapter.getCount(); i++) { 
        _items.add(_arrayAdapter.getItem(i)); 
       } 
       // Change end. 

       _searchableListDialog.show(scanForActivity(_context).getFragmentManager(), "TAG"); 
      } 
     } 
     return true; 
    } 

    @Override 
    public void setAdapter(SpinnerAdapter adapter) { 

     if (!_isFromInit) { 
      _arrayAdapter = (ArrayAdapter) adapter; 
      if (!TextUtils.isEmpty(_strHintText) && !_isDirty) { 
       ArrayAdapter arrayAdapter = new ArrayAdapter(_context, android.R.layout 
         .simple_list_item_1, new String[]{_strHintText}); 
       super.setAdapter(arrayAdapter); 
      } else { 
       super.setAdapter(adapter); 
      } 

     } else { 
      _isFromInit = false; 
      super.setAdapter(adapter); 
     } 
    } 

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

     if (!_isDirty) { 
      _isDirty = true; 
      setAdapter(_arrayAdapter); 
      setSelection(_items.indexOf(item)); 
     } 
    } 

    public void setTitle(String strTitle) { 
     _searchableListDialog.setTitle(strTitle); 
    } 

    public void setPositiveButton(String strPositiveButtonText) { 
     _searchableListDialog.setPositiveButton(strPositiveButtonText); 
    } 

    public void setPositiveButton(String strPositiveButtonText, DialogInterface.OnClickListener onClickListener) { 
     _searchableListDialog.setPositiveButton(strPositiveButtonText, onClickListener); 
    } 

    public void setOnSearchTextChangedListener(SearchableListDialog.OnSearchTextChanged onSearchTextChanged) { 
     _searchableListDialog.setOnSearchTextChangedListener(onSearchTextChanged); 
    } 

    private Activity scanForActivity(Context cont) { 
     if (cont == null) 
      return null; 
     else if (cont instanceof Activity) 
      return (Activity) cont; 
     else if (cont instanceof ContextWrapper) 
      return scanForActivity(((ContextWrapper) cont).getBaseContext()); 

     return null; 
    } 

    @Override 
    public int getSelectedItemPosition() { 
     if (!TextUtils.isEmpty(_strHintText) && !_isDirty) { 
      return NO_ITEM_SELECTED; 
     } else { 
      return super.getSelectedItemPosition(); 
     } 
    } 

    @Override 
    public Object getSelectedItem() { 
     if (!TextUtils.isEmpty(_strHintText) && !_isDirty) { 
      return null; 
     } else { 
      return super.getSelectedItem(); 
     } 
    } 
} 

Đây là bên thứ ba lớp SearchableListDialog:

public class SearchableListDialog extends DialogFragment implements 
     SearchView.OnQueryTextListener, SearchView.OnCloseListener { 

    private static final String ITEMS = "items"; 

    private CountriesCustomAdapterInr listAdapter; 

    private ListView _listViewItems; 

    private SearchableItem _searchableItem; 

    private OnSearchTextChanged _onSearchTextChanged; 

    private SearchView _searchView; 

    private String _strTitle; 

    private String _strPositiveButtonText; 

    private DialogInterface.OnClickListener _onClickListener; 

    public SearchableListDialog() { 

    } 

    public static SearchableListDialog newInstance(List items) { 
     SearchableListDialog multiSelectExpandableFragment = new 
       SearchableListDialog(); 

     Bundle args = new Bundle(); 
     args.putSerializable(ITEMS, (Serializable) items); 

     multiSelectExpandableFragment.setArguments(args); 

     return multiSelectExpandableFragment; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams 
       .SOFT_INPUT_STATE_HIDDEN); 
     return super.onCreateView(inflater, container, savedInstanceState); 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 

     // Getting the layout inflater to inflate the view in an alert dialog. 
     LayoutInflater inflater = LayoutInflater.from(getActivity()); 

     // Crash on orientation change #7 
     // Change Start 
     // Description: As the instance was re initializing to null on rotating the device, 
     // getting the instance from the saved instance 
     if (null != savedInstanceState) { 
      _searchableItem = (SearchableItem) savedInstanceState.getSerializable("item"); 
     } 
     // Change End 

     View rootView = inflater.inflate(R.layout.searchable_list_dialog, null); 
     setData(rootView); 

     AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity()); 
     alertDialog.setView(rootView); 

     String strPositiveButton = _strPositiveButtonText == null ? "CLOSE" : _strPositiveButtonText; 
     alertDialog.setPositiveButton(strPositiveButton, _onClickListener); 

//  String strTitle = _strTitle == null ? "Select Country" : _strTitle; 
//  alertDialog.setTitle(strTitle); 

     final AlertDialog dialog = alertDialog.create(); 
     dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams 
       .SOFT_INPUT_STATE_HIDDEN); 
     return dialog; 
    } 

    // Crash on orientation change #7 
    // Change Start 
    // Description: Saving the instance of searchable item instance. 
    @Override 
    public void onSaveInstanceState(Bundle outState) { 
     outState.putSerializable("item", _searchableItem); 
     super.onSaveInstanceState(outState); 
    } 
    // Change End 

    public void setTitle(String strTitle) { 
     _strTitle = strTitle; 
    } 

    public void setPositiveButton(String strPositiveButtonText) { 
     _strPositiveButtonText = strPositiveButtonText; 
    } 

    public void setPositiveButton(String strPositiveButtonText, DialogInterface.OnClickListener onClickListener) { 
     _strPositiveButtonText = strPositiveButtonText; 
     _onClickListener = onClickListener; 
    } 

    public void setOnSearchableItemClickListener(SearchableItem searchableItem) { 
     this._searchableItem = searchableItem; 
    } 

    public void setOnSearchTextChangedListener(OnSearchTextChanged onSearchTextChanged) { 
     this._onSearchTextChanged = onSearchTextChanged; 
    } 

    private void setData(View rootView) { 
     SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE); 

     _searchView = (SearchView) rootView.findViewById(R.id.search); 
     _searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName 
       ())); 
     _searchView.setIconifiedByDefault(false); 
     _searchView.setOnQueryTextListener(this); 
     _searchView.setOnCloseListener(this); 
     _searchView.setQueryHint("Search Country"); 
     _searchView.clearFocus(); 
     InputMethodManager mgr = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); 
     mgr.hideSoftInputFromWindow(_searchView.getWindowToken(), 0); 


     List items = (List) getArguments().getSerializable(ITEMS); 

     _listViewItems = (ListView) rootView.findViewById(R.id.listItems); 

     //create the adapter by passing your ArrayList data 
//  listAdapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, items); 
listAdapter = new CountriesCustomAdapterInr(getActivity(), R.layout.custom_spinner_items, arrayList, getResources()); 
// 

     //attach the adapter to the list 
     _listViewItems.setAdapter(listAdapter); 

     _listViewItems.setTextFilterEnabled(true); 

     _listViewItems.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       _searchableItem.onSearchableItemClicked(listAdapter.getItem(position), position); 
       getDialog().dismiss(); 
      } 
     }); 
    } 

    @Override 
    public boolean onClose() { 
     return false; 
    } 

    @Override 
    public boolean onQueryTextSubmit(String s) { 
     _searchView.clearFocus(); 
     return true; 
    } 

    @Override 
    public boolean onQueryTextChange(String s) { 
//  listAdapter.filterData(s); 
     if (TextUtils.isEmpty(s)) { 
//    _listViewItems.clearTextFilter(); 
      ((ArrayAdapter) _listViewItems.getAdapter()).getFilter().filter(null); 
     } else { 
      ((ArrayAdapter) _listViewItems.getAdapter()).getFilter().filter(s); 
     } 
     if (null != _onSearchTextChanged) { 
      _onSearchTextChanged.onSearchTextChanged(s); 
     } 
     return true; 
    } 

    public interface SearchableItem<T> extends Serializable { 
     void onSearchableItemClicked(T item, int position); 
    } 

    public interface OnSearchTextChanged { 
     void onSearchTextChanged(String strText); 
    } 
} 

Đây OnQueryTextListener() không làm việc tốt. Làm ơn giúp tôi. Tôi đã thử nhưng không có giải pháp nào cả. Ai đó làm ơn giúp tôi với. Ở trên, tôi đã đề cập đến truy vấn của mình. Cảm ơn

Trả lời

2

Thay vì sử dụng một Spinner với SearchView, tôi sẽ đề nghị bạn đạt được điều này với ListView và SearchView, tôi đã thử và nó hoạt động rất tốt.

Đặt nút vào hoạt động của bạn. Bây giờ nhấp vào nút này sẽ mở ra một hộp thoại tùy chỉnh.

enter image description here

custom_dialog.xml bạn

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

    <android.support.v7.widget.SearchView 
     android:id="@+id/searchView" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 

    <ListView 
     android:id="@+id/listView" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" /> 

</LinearLayout> 

Sau đó thiết lập nút onClick sự kiện của bạn và làm như sau.

@Override 
      public void onClick(View view) { 
       Dialog dialog = new Dialog(SearchText.this); 
       LayoutInflater inflater = LayoutInflater.from(SearchText.this); 
       View view1 = inflater.inflate(R.layout.custom_search_layout, null); 
       ListView listView = view1.findViewById(R.id.listView); 
       SearchView searchView = view1.findViewById(R.id.searchView); 

       final ArrayAdapter<String> stringArrayAdapter = new ArrayAdapter<String>(SearchText.this, android.R.layout.simple_list_item_1, getResources().getStringArray(R.array.my_currency)); 
       listView.setAdapter(stringArrayAdapter); 

       searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { 
        @Override 
        public boolean onQueryTextSubmit(String newText) { 
         return false; 
        } 

        @Override 
        public boolean onQueryTextChange(String newText) { 
         stringArrayAdapter.getFilter().filter(newText); 
         return false; 
        } 
       }); 
       dialog.setContentView(view1); 
       dialog.show(); 
      } 

enter image description here

Bây giờ làm tìm kiếm của bạn, và thêm OnItemClickListener trên listview của bạn, và làm bất cứ điều gì bạn muốn sau khi chọn bạn đã chọn.

enter image description here

+0

@Kenjin Bạn cũng có thể sử dụng Spinner thay cho Listview, tôi đã thử nghiệm và hoạt động. Hãy cho tôi biết nếu bạn có bất kỳ truy vấn nào. –

Các vấn đề liên quan