2017-12-18 160 views
1

自定義ArrayAdapter AutoCompleteTextView不觸發 我想與一個ArrayList的對象使用自定義列表適配器使用AutoCompleteTextView,我無法獲得自動完成列表顯示。這裏是我的代碼: activity_main.xml中自定義ArrayAdapter AutoCompleteTextView不觸發

<?xml version="1.0" encoding="utf-8"?> 
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     xmlns:app="http://schemas.android.com/apk/res-auto" 
     xmlns:tools="http://schemas.android.com/tools" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     tools:context="rick.customarrayadpter.MainActivity"> 

     <AutoCompleteTextView 
      android:id="@+id/customerACTV" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:hint="search" /> 
    </android.support.constraint.ConstraintLayout> 

MainActivity.java 
    import android.support.v7.app.AppCompatActivity; 
    import android.os.Bundle; 
    import android.widget.AutoCompleteTextView; 

    import java.util.ArrayList; 

    public class MainActivity extends AppCompatActivity { 
     private ArrayList<Customer> customerList; 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.activity_main); 

      customerList = new ArrayList<Customer>(); 
      customerList.add(new Customer(111, "Pete")); 
      customerList.add(new Customer(222, "Bob")); 
      customerList.add(new Customer(333, "Paul")); 
      customerList.add(new Customer(444, "Tom")); 
      customerList.add(new Customer(555, "Jane")); 
      customerList.add(new Customer(666, "Susan")); 

      CustomerListAdapter customerListAdapter = new CustomerListAdapter(this, R.layout.support_simple_spinner_dropdown_item, R.id.customerACTV, customerList); 
      AutoCompleteTextView customerACTV = (AutoCompleteTextView)findViewById(R.id.customerACTV); 
      customerACTV.setThreshold(1); 
      customerACTV.setAdapter(customerListAdapter); 

     } 

    } 

CustomerListAdapter.java 
    public class CustomerListAdapter extends ArrayAdapter<Customer> { 

      ArrayList<Customer> customerList = new ArrayList<>(); 

      public CustomerListAdapter(Context context, int resource,int textViewResourceId, ArrayList<Customer> objects) { 
       super(context, resource, textViewResourceId, objects); 
       customerList = objects; 
      } 

      @Override 
      public int getCount() { 
       return super.getCount(); 
      } 

      @Override 
      public View getView(int position, View convertView, ViewGroup parent) { 

       View v = convertView; 
       LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
       v = inflater.inflate(R.layout.list_items, null); 
       AutoCompleteTextView textView = (AutoCompleteTextView) v.findViewById(R.id.customerACTV); 
       textView.setText(customerList.get(position).getName()); 
       return v; 

      } 
     } 

list_items.xml 
    <?xml version="1.0" encoding="utf-8"?> 
    <android.support.constraint.ConstraintLayout 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:orientation="horizontal"> 

     <TextView 
      android:id="@+id/textView" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:layout_gravity="center" 

      android:text="Demo" 
      android:textColor="#000" /> 


    </android.support.constraint.ConstraintLayout> 

    Customer.java 
    public class Customer { 
     String name; 
     int id; 
     public Customer(int ID, String Name){ 
      this.id = ID; 
      this.name = Name; 
     } 

     public String getName(){return this.name;} 
     public int getId(){return this.id;} 
    } 

有一個在代碼中沒有錯誤,但它並不顯示自動完成選擇,當我進入了customerACTV字母。 CustomerListAdapter構造函數正在被調用,並且Customer對象的ArrayList正在通過,但CustomerListAdapter的getView沒有被調用。

感謝

+0

我已經看到了一些其他的帖子與此相同的問題,但沒有答案。 – rstambach

回答

1

對於汽車的建議工作,在自動完成的TextView,我們必須爲忽略getFilter(),在這裏我們設置過濾功能,默認的適配器只能過濾字符串,並且您正在使用一個對象Customer

所以,你需要做你以下幾點:

@NonNull 
@Override 
public Filter getFilter() { 

    return new Filter() { 
     final Object object = new Object(); 

     @Override 
     public String convertResultToString(Object resultValue) { 
     return resultValue.toString(); 

     } 

     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 




      FilterResults filterResults = new FilterResults(); 
      List<Customer> customers = new ArrayList<>(); 

      if (constraint != null) { 

       for (Customer customer : customerList) { 
        if (department instanceof SearchableStrings) { 
         if (customer.getname().toLowerCase().contains(constraint.toString().toLowerCase())) { 
          customers.add(customer); 

         } 

        } 
        if (customers.size() > 1) { 
         filterResults.values = customers; 
         filterResults.count =  customers.size(); 
        } else { 
         filterResults.values = null; 
         filterResults.count = 0; 


       } 



      } 
      //notifyDataSetChanged(); 
      return filterResults; 
     } 

     @Override 
     protected void publishResults(CharSequence constraint, FilterResults results) { 

      // mObjects.clear(); 
      if (results != null && results.count > 0) { 
       clear(); 
       // avoids unchecked cast warning when using customerList.addAll((ArrayList<Customer>) results.values); 
       for (Object object : (List<?>) results.values) { 
        add(object); 


       } 
       notifyDataSetChanged(); 
      } 
     } 


    }; 
+0

謝謝Kaustubh, – rstambach

+0

謝謝Kaustubh,這是問題,它現在工作,但我仍然有一個小問題。當我從自動完成的下拉列表中選擇一些內容,然後使用退格鍵或更改文本時,自動完成下拉列表不顯示。如果用戶想要更改選擇,它應該再次顯示。有什麼建議麼?再次感謝。 – rstambach

+0

我只能看到適配器,它看起來不錯,只有在publishresults方法中沒有任何內容時,autocomplete下拉框纔會顯示,請調試並檢查它 –

0
public class CustomerListAdapter extends ArrayAdapter<Customer> { 

ArrayList<Customer> customerList, suggestionList; 


public CustomerListAdapter(Context context, int resource, int textViewResourceId, ArrayList<Customer> customerList) { 
    super(context, resource, textViewResourceId, customerList); 
    this.customerList = new ArrayList<>(); 
    this.customerList = customerList; 

} 

@Override 
public int getCount() { 
    return super.getCount(); 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 

    View view = convertView; 
    if(convertView == null){ 
     LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     view = inflater.inflate(R.layout.list_items, parent, false); 
    } 

    Customer customer = customerList.get(position); 
    if(customer != null){ 
     TextView textView = view.findViewById(R.id.textView); 
     if(textView != null) 
      textView.setText(customer.getName()); 
    } 
    return view; 
} 



@NonNull 
@Override 
public Filter getFilter() { 
    return new Filter() { 
     final Object object = new Object(); 

     @Override 
     public String convertResultToString(Object resultValue) { 
      Customer customer = (Customer) resultValue; 
      return customer.getName(); 
     } 

     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 


      FilterResults filterResults = new FilterResults(); 
      suggestionList = new ArrayList<>(); 
      if (constraint != null) { 
       for (Customer customer : customerList) { 

        if (customer.getName().toLowerCase().contains(constraint.toString().toLowerCase())) { 
         suggestionList.add(customer); 
        } 
        if (customerList.size() > 1) { 
         filterResults.values = suggestionList; 
         filterResults.count = suggestionList.size(); 
        } else { 
         filterResults.values = null; 
         filterResults.count = 0; 
        } 
       } 
      } 
      return filterResults; 
     } 

     @Override 
     protected void publishResults (CharSequence constraint, FilterResults results){ 
      ArrayList<Customer> filterList = (ArrayList<Customer>)results.values; 

      if (results != null && results.count > 0) { 
       clear(); 
       for (Customer customer : filterList) { 
        add(customer); 
        notifyDataSetChanged(); 
       } 
       notifyDataSetChanged(); 
      } 
     } 
    }; 
} 

}

+0

我在調試時發現了一些問題。必須更改getFilter performFiltering函數和CustomerListAdapter構造函數。 – rstambach

0

公共類CustomerListAdapter擴展ArrayAdapter {

private ArrayList<Customer> customerList; 
private ArrayList<Customer> filteredList; 

public CustomerListAdapter(Context context, int resource, int textViewResourceId, ArrayList<Customer> customerList) { 
    super(context, resource, textViewResourceId, customerList); 
    this.customerList = new ArrayList<Customer>(customerList); 
    this.filteredList = customerList; 
} 

@Override 
public int getCount() { 
    return super.getCount(); 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 

    View view = convertView; 
    if(convertView == null){ 
     LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     view = inflater.inflate(R.layout.list_items, parent, false); 
    } 

    Customer customer = filteredList.get(position); 
    if(customer != null){ 
     TextView textView = view.findViewById(R.id.textView); 
     if(textView != null) 
      textView.setText(customer.getName()); 
    } 
    return view; 
} 

@NonNull 
@Override 
public Filter getFilter() { 
    return new Filter() { 
     final Object object = new Object(); 

     @Override 
     public String convertResultToString(Object resultValue) { 
      Customer customer = (Customer) resultValue; 
      return customer.getName(); 
     } 

     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 
      FilterResults filterResults = new FilterResults(); 
      ArrayList<Customer> filters = new ArrayList<Customer>(); 
      if (constraint != null && constraint.length()>0) { 
       for (Customer customer : customerList) { 

        if (customer.getName().toLowerCase().contains(constraint.toString().toLowerCase())) { 
         filters.add(customer); 
        } 
       } 
       filterResults.values = filters; 
       filterResults.count = filters.size(); 
       filteredList = filters; 
      } 
      return filterResults; 
     } 

     @Override 
     protected void publishResults (CharSequence constraint, FilterResults results){ 
      ArrayList<Customer> filterList = (ArrayList<Customer>)results.values; 

      if (results != null && results.count > 0) { 
       clear(); 
       for (Customer customer : filterList) { 
        add(customer); 
        notifyDataSetChanged(); 
       } 
       notifyDataSetChanged(); 
      } 
     } 
    }; 
} 

}

+0

在構造函數中,我有customerList = objects;它將變量customerList設置爲與對象相同的引用。所以,如果我修改了任何對象項目,它也改變了customerList項目,並且基類必須改變它們。所以我把它改成this.customerList = new ArrayList (customerList);這會保留原始ArrayList在performFiltering中的使用副本,如通過退格鍵更改選擇內容。 感謝您幫助Kaustubh。我真的被困在那一個。 – rstambach

相關問題