亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

自定義 ArrayAdapter 上的 getFilter() 不起作用

自定義 ArrayAdapter 上的 getFilter() 不起作用

青春有我 2022-01-12 10:07:07
我正在使用自定義 ArrayAdapter來存儲用戶信息,例如 sammy、robert、lizie 都是一個用戶對象,我正在使用用戶類型ArrayList將所有用戶對象存儲到ArrayList。而且因為它不是字符串或 int(ArrayList),所以默認的getFilter不起作用,我已經完成了我的研究,但是getFilter方法的工作原理確實令人困惑,所以我可以修改自己。我想實現基于 name屬性形式的搜索User class我知道我必須在我的CustomAdapter類中實現Filterable接口,但是getFilter真的不直觀。這是我的自定義適配器class CustomArrayAdapter extends ArrayAdapter<User>  implements Filterable {    CustomArrayAdapter(@NonNull Context context, ArrayList<User> users) {        super(context, 0, users);    }    @NonNull    @Override    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {        User innserUser = getItem(position);        if (convertView == null){            convertView = LayoutInflater.from(getContext()).inflate(R.layout.row_layout, parent, false);        }        TextView username = (TextView) convertView.findViewById(R.id.userNameContact);        TextView userNumber = (TextView) convertView.findViewById(R.id.userNumberContact);        ImageView userImage = (ImageView) convertView.findViewById(R.id.userImageContact);        try {            if(innserUser != null) {                username.setText(innserUser.name);                userNumber.setText(innserUser.number);                userImage.setImageBitmap(innserUser.imageBitmap);            }        }catch (Exception e){            e.printStackTrace();        }        return convertView;    }}這是用戶類,這里沒什么特別的import android.graphics.Bitmap;public class User {    String id, name, number;    Bitmap imageBitmap;    User(String id, String name, String number, Bitmap imageBitmap){        this.id = id;        this.name = name;        this.number = number;        this.imageBitmap = imageBitmap;    }}我從許多線程中綁定了許多getFilter的變體,但它們都不適合我,而有很好解釋的是 BaseAdapter 而不是 ArrayAdapter我試過這個問題,我也試過這個問題,但對我不起作用。我是 android 開發領域的新手,這似乎特別不直觀。任何建議將不勝感激,謝謝。
查看完整描述

2 回答

?
侃侃爾雅

TA貢獻1801條經驗 獲得超16個贊

ArrayAdapter的內置函數Filter使用toString()模型類的返回值(即其類型參數)來執行其過濾比較。Filter如果您能夠覆蓋UsertoString()方法以返回您想要比較的內容,則不一定需要自定義實現(前提是其過濾算法適合您的情況)。在這種情況下:

@Override
public String toString() {
    return name;
    }

為了明確該算法是什么,ArrayAdapter的默認過濾如下:

過濾器String首先轉換為小寫。然后,遍歷數據集,將每個值的toString()返回值轉換為小寫,并檢查它是否startsWith()為 filter String。如果是,則將其添加到結果集中。如果不是,則執行第二次檢查,將值的小寫字母String拆分為空格 ( " "),并將其中的每個值與過濾器進行比較,再次使用startsWith(). 基本上,它首先檢查整個內容是否以過濾器文本開頭,然后在必要時檢查每個單詞。

如果這是一個合適的過濾器,那么這個解決方案是迄今為止最簡單的。


如果這不能滿足您的需求,并且您確實需要自定義Filter實現,那么您不應該一ArrayAdapter開始就使用。ArrayAdapter維護private List原始和過濾集合的internal, s - 最初從構造函數調用中傳遞的集合填充 - 您無權訪問這些。這就是為什么顯示的自定義Filter嘗試不起作用的原因,因為顯示的項目計數和返回的項目getItem(position)來自該內部過濾器List,而不是內置的自定義過濾器Filter。

在這種情況下,您應該直接進行子類化BaseAdapter,List為原始集合和過濾集合維護自己的s。您可以使用ArrayAdapter's source作為指南。

確實,ArrayAdapter在選擇Adapter擴展時通常是錯誤的選擇。ArrayAdapter是專為單數,有些簡單化的目標:將在平板String上的單個TextView在每個列表項。在某些情況下,子類化ArrayAdapter而不是BaseAdapter毫無意義和/或多余。例如:

  • 覆蓋getView()而不使用View從調用返回的super.getView().

  • TextView無論出于何種原因,手動設置自己的文本。

  • 維護和使用您自己的收藏;即,數組,或Lists,或者你有什么。

在這些和某些其他情況下,可以說BaseAdapter從一開始就使用它會更好。使用ArrayAdapter比具有基本功能的單個文本項更復雜的任何內容會很快變得麻煩且容易出錯,而且通常麻煩多于其價值。


最后,我要提到的ListView是,在撰寫本文時,盡管尚未正式發布,但目前基本上已棄用。目前的建議是RecyclerView改用。但是,對于那些剛接觸 Android 編程的人來說,ListView作為了解此類回收適配器的整體設計的開始步驟,仍然是有用的View。RecyclerView一開始可能有點不知所措。


查看完整回答
反對 回復 2022-01-12
?
MMTTMM

TA貢獻1869條經驗 獲得超4個贊

Filter myFilter = new Filter() {

        @Override

        protected FilterResults performFiltering(CharSequence constraint) {

         FilterResults filterResults = new FilterResults();   

         ArrayList<User> tempList=new ArrayList<User>();

         // Add the filter code here

         if(constraint != null && users!=null) {

             int length= users.size();

             int i=0;

                while(i<length){

                    User item= users.get(i);

                    //do whatever you wanna do here

                    //adding result set output array    

                    if()  {  // Add check here, and fill the tempList which shows as a result


                    tempList.add(item);

                  }


                    i++;

                }

                //following two lines is very important

                //as publish result can only take FilterResults users

                filterResults.values = tempList;

                filterResults.count = tempList.size();

          }

          return filterResults;

      }


      @SuppressWarnings("unchecked")

      @Override

      protected void publishResults(CharSequence contraint, FilterResults results) {

          users = (ArrayList<User>) results.values;

          if (results.count > 0) {

           notifyDataSetChanged();

          } else {

              notifyDataSetInvalidated();

          }  

      }

     };

最后,重寫此方法并返回過濾器實例。


@Override

     public Filter getFilter() {

        return myFilter;

    }

有關更多參考,請參閱https://gist.github.com/tobiasschuerg/3554252


查看完整回答
反對 回復 2022-01-12
  • 2 回答
  • 0 關注
  • 308 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號