2017-12-20 7 views
0

ユーザーがクリックするボタンに応じてフィルタリングしようとしているリストビューがあります。Androidリストがフィルタで更新されない

フィルタが機能していますが、私はpublishResultsメソッド内で期待した結果を得ていますが、リストは決して更新されません。 notifyDataSetChanged()がありますが、これは何もしないようです。

public void filterList(View view){ 
    mAdapter.resetData(); 
    Log.d(LOG_TAG, "FILTER Tsunami" + mAdapter.quakeList); 
    mAdapter.getFilter().filter("tsunamiOnly"); 
} 

public void filterListEarthquake(View view){ 
    mAdapter.resetData(); 
    Log.d(LOG_TAG, "FILTER earthquake" + mAdapter.quakeList); 
    mAdapter.getFilter().filter("earthquakeOnly"); 
} 

カスタム・アダプタ

public class QuakeAdapter extends ArrayAdapter<QuakeItem> implements Filterable { 
    public ArrayList<QuakeItem> origQuakeList; 
    public ArrayList<QuakeItem> quakeList; 
    private Filter quakeFilter; 
    private Context mContext; 

    public static final String LOG_TAG = QuakeAdapter.class.getName(); 

    public QuakeAdapter(Activity context, ArrayList<QuakeItem> quakeItems){ 
     super(context, 0, quakeItems); 
     origQuakeList = quakeItems; 
     quakeList = quakeItems; 
     mContext = context; 
    } 

    @NonNull 
    @Override 
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent){ 
     View listItemView = convertView; 

     if(listItemView == null){ 
      listItemView = LayoutInflater.from(getContext()).inflate(
        R.layout.list_item, parent, false 
      ); 
     } 

     QuakeItem currentItem = getItem(position); 

     double mag = currentItem.getMagnitude(); 

     TextView magnitudeTextView = (TextView) listItemView.findViewById(R.id.magnitudeView); 
     magnitudeTextView.setText(formatMagnitude(mag)); 

     GradientDrawable magnitudeCircle = (GradientDrawable) magnitudeTextView.getBackground(); 
     int magnitudeColour = getMagnitudeColour(mag); 
     magnitudeCircle.setColor(magnitudeColour); 

     int isTsunami = currentItem.getTsunami(); 
     int strokeColor = magnitudeColour; 
     if (isTsunami==1){ 
      strokeColor = Color.BLACK; 
     } 
     magnitudeCircle.setStroke(6, strokeColor); 

     String[] formattedString = formatLocation(currentItem.getLocation()); 

     TextView locationOffsetTextView = (TextView) listItemView.findViewById(R.id.locationOffsetView); 
     locationOffsetTextView.setText(formattedString[0]); 

     TextView locationTextView = (TextView) listItemView.findViewById(R.id.locationView); 
     locationTextView.setText(formattedString[1]); 

     Long timeInMilliseconds = currentItem.getTime(); 

     TextView timeTextView = (TextView) listItemView.findViewById(R.id.timeView); 
     timeTextView.setText(formatTime(timeInMilliseconds)); 

     TextView dateTextView = (TextView) listItemView.findViewById(R.id.dateView); 
     dateTextView.setText(formatDate(timeInMilliseconds)); 

     return listItemView; 
    } 

    public void resetData() { 
     quakeList = origQuakeList; 
    } 

    @Override 
    public Filter getFilter() { 
     if (quakeFilter == null) 
      quakeFilter = new QuakeFilter(); 

     return quakeFilter; 
    } 

    private class QuakeFilter extends Filter{ 
     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 
      FilterResults results = new FilterResults(); 

      if (constraint == null || constraint.length() == 0){ 
       // No filter found, return original list 
       results.values = origQuakeList; 
       results.count = origQuakeList.size(); 
      } else { 
       // Perform filter 
       ArrayList<QuakeItem> nQuakeList = new ArrayList<QuakeItem>(); 

       switch (constraint.toString()){ 
        case "tsunamiOnly": 
         for (QuakeItem q : quakeList){ 
          if (q.getTsunami() == 1){ 
           nQuakeList.add(q); 
          } 
         } 
         break; 
        case "earthquakeOnly": 
         for (QuakeItem q : quakeList){ 
          if (q.getTsunami() == 0){ 
           nQuakeList.add(q); 
          } 
         } 
         break; 
       } 

       results.values = nQuakeList; 
       results.count = nQuakeList.size(); 
      } 

      return results; 
     } 

     @Override 
     protected void publishResults(CharSequence constraint, FilterResults filterResults) { 
      if (filterResults.count == 0){ 
       notifyDataSetInvalidated(); 
      } else { 
       quakeList = (ArrayList<QuakeItem>) filterResults.values; 
       Log.d(LOG_TAG, "FILTER " + quakeList); 
       notifyDataSetChanged(); 
      } 
     } 
    } 
} 
+0

ArrayAdapterに 'getView()'がありますか? – emrekose26

+0

はい、申し訳ありませんが、私はちょうどコードの量を減らすためにコードスニペットにそれを含めていませんでした。 – SamH

+0

AsyncスレッドでUIの更新を行っていますか?その場合、メインUIに表示の問題が発生する可能性があります。 – Petro

答えて

0

フィルタを設定

分SDKレベル21と26

mAdapter = new QuakeAdapter(this, new ArrayList<QuakeItem>()); 
    ListView earthquakeListView = (ListView) findViewById(R.id.list); 
    earthquakeListView.setAdapter(mAdapter); 

をコンパイルは、私自身の問題を解決しました。予想どおり、それは何かばかげたものでした。

アダプターにgetCount、getItem、およびgetItemIdがありませんでした。

public int getCount() { 
    return quakeList.size(); 
} 

public QuakeItem getItem(int position) { 
    return quakeList.get(position); 
} 

public long getItemId(int position) { 
    return quakeList.get(position).hashCode(); 
} 
関連する問題