2012-05-02 22 views
1

私は、リストビューと編集テキストボックスを上部に持つページを持つアプリケーションで作業しています。 edittextボックスに項目を入力すると、リストビューに表示される項目がフィルタリングされます。私が抱えている問題は、スライダの側面に表示されるファーストスクロールアイコンです。私は、例えば、」bは文字を入力するとき スクロールビューを出て行く。setFastScrollEnabledが完全に機能しない

enter image description here

私は(私のリストのスクロールをリフレッシュするために)この行を追加して、それが動作しませんでした。

_filterText = (EditText) findViewById(R.id.search_box); 

_filterText.addTextChangedListener(new TextWatcher(){ 

    public void afterTextChanged(Editable s) { 

     _listView.setFastScrollEnabled(false); 

     _listView.setFastScrollEnabled(true); 

    } 

私も[OK]を、ここにすべての私のクラスでこのテーマをSEとそれに続く、と私はそれは同じ問題ではなかったと思います Android: fastScrollEnabled not working at first

いる:

public class StationsFragment extends GoogleAnalyticsFragment implements Observer{ 

    private Boolean mDebug = true; 

    private ListView   _listView; 

    @Override 

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

     super.onCreateView(inflater, container, savedInstanceState); 

     activity = (FragmentsActivity) getActivity(); 

     mStationsViewContainer = inflater.inflate(R.layout.stations_activity, null); 

     _listView = (ListView) mStationsViewContainer.findViewById(R.id.stations_listView); 

      activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); 

      _stationsAdapter = new StationsAdapter(); 

      _listView.setAdapter(_stationsAdapter); 

      _listView.setVerticalScrollBarEnabled(false); 

      _listView.setFastScrollEnabled(true); 

      _listView.setScrollingCacheEnabled(true); 

      registerForContextMenu(_listView); 

      _listView.setOnItemClickListener(new OnItemClickListener() { 

       @Override 

       public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 


       } 
      }); 

      _stationsList.addObserver(this); 

      _filterText = (EditText) mStationsViewContainer.findViewById(R.id.search_box); 

      TextWatcher filterTextWatcher = new TextWatcher() { 

       public void afterTextChanged(Editable s) { 
        _listView.setFastScrollEnabled(false); 

        _listView.setFastScrollEnabled(true); 
       } 

       public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
       } 

       public void onTextChanged(CharSequence s, int start, int before, int count) { 

        _filterMode = _filterText.getText().length() > 0; 

        _stationsAdapter.getFilter().filter(s); 
       } 
      }; 

      _filterText.addTextChangedListener(filterTextWatcher); 

      _stationsAdapter.getFilter().filter(""); 

     } 

     return mStationsViewContainer; 
    } 

class StationsAdapter extends BaseAdapter implements SectionIndexer, Filterable { 

     HashMap<String, Integer> _alphaIndexer; 

     public ArrayList<Station> _filtered = new ArrayList<Station>(); 

     String[]     _sections; 

     MyFilter     _filter; 

     public StationsAdapter() { 

      super(); 

      _filter = new MyFilter(); 
     } 

     public void updateIndex() { 

      _alphaIndexer = new HashMap<String, Integer>(); 

      for (int x = 0; x < _filtered.size(); x++) { 

       Station s = (Station) _filtered.get(x); 

       // get the first letter of the store 
       String ch = s.getTitle().substring(0, 1); 

       // convert to uppercase otherwise lowercase a -z will be sorted 
       // after upper A-Z 
       ch = ch.toUpperCase(); 

       if (!_alphaIndexer.containsKey(ch)) { 

        if (_filterMode) { 

         _alphaIndexer.put(ch, x); 

        } else { 

         _alphaIndexer.put(ch, x + _favouriteManager.getFavourites().length); 
        } 
       } 
      } 

      Set<String> sectionLetters = _alphaIndexer.keySet(); 

      ArrayList<String> sectionList = new ArrayList<String>(sectionLetters); 

      Collections.sort(sectionList); 

      if (!_filterMode && _favouriteManager.getFavourites().length > 0) { 

       sectionList.add(0, "\u2605"); 
      } 

      _sections = new String[sectionList.size()]; 

      sectionList.toArray(_sections); 

      if (!_filterMode && _favouriteManager.getFavourites().length > 0) { 

       _alphaIndexer.put("\u2605", 0); 
      } 
     } 

     public int getCount() { 

      if (_filterMode) { 

       if (mDebug) Log.i("StationFragment","filter size ="+_filtered.size()); 

       return _filtered.size(); 

      } else { 

       return _filtered.size() + _favouriteManager.getFavourites().length; 
      } 

     } 

     public Object getItem(int position) { 

      if (_filterMode) { 

       return _filtered.get(position); 

      } else { 

       if (position < _favouriteManager.getFavourites().length) { 

        return _favouriteManager.getFavourites()[position]; 

       } else { 

        return _filtered.get(position - _favouriteManager.getFavourites().length); 
       } 
      } 
     } 

     public long getItemId(int position) { 

      return position; 
     } 

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

      if (mDebug)  Log.i("ks3","getView called, position is " + position); 

      if (convertView == null) { 

       LayoutInflater inflater = (LayoutInflater) activity.getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

       convertView = inflater.inflate(R.layout.stations_cell_custom, null); 
      } 

      if (!_filterMode) { 

       if (position < _favouriteManager.getFavourites().length) { 

        Favourite favourite = _favouriteManager.getFavourites()[position]; 

        Station station = _stationsList.findStationById(favourite.getFavouriteId()); 

        TextView details = ((TextView) convertView.findViewById(R.id.details)); 

        if (_pushedFromRoutes || _pushedFromWidgetConfiguration) { 

         details.setVisibility(View.GONE); 

        } else { 

         details.setVisibility(View.VISIBLE); 
        } 

        TextView name = ((TextView) convertView.findViewById(R.id.name)); 

        if (station != null) { 

         name.setText(station.getName()); 

         //name.setTextColor(getResources().getColor(R.color.stations_list_favourite_text_color)); 

        } else { 

         name.setText(""); 
        } 

        details.setText(favourite.getUserSettings().formattedDateTime()); 

        TextView header = ((TextView) convertView.findViewById(R.id.header_textview)); 

        View headerBar = ((View) convertView.findViewById(R.id.header_bar)); 

        if (position == 0) { 

         header.setVisibility(View.VISIBLE); 

         headerBar.setVisibility(View.VISIBLE); 

         header.setText(getString(R.string.star_favourites)); 

        } else { 

         header.setVisibility(View.GONE); 

         headerBar.setVisibility(View.GONE); 

         header.setText(null); 
        } 

       } else { 

        Station station = _filtered.get(position - _favouriteManager.getFavourites().length); 

        TextView name = ((TextView) convertView.findViewById(R.id.name)); 

        name.setText(station.getName()); 

        name.setTextColor(getResources().getColor(R.color.stations_list_text_color)); 

        ((TextView) convertView.findViewById(R.id.details)).setVisibility(View.GONE); 

        TextView header = ((TextView) convertView.findViewById(R.id.header_textview)); 

        View headerBar = ((View) convertView.findViewById(R.id.header_bar)); 

        String firstLetter = station.getTitle().substring(0, 1); 

        /*if (position == _alphaIndexer.get(firstLetter)) { 

         TextView header = (TextView) activity.findViewById(R.id.header_textview); 

         header.setText(firstLetter); 
        }*/ 


        if (position == _alphaIndexer.get(firstLetter)) { 

         header.setVisibility(View.VISIBLE); 

         headerBar.setVisibility(View.VISIBLE); 

         header.setText(firstLetter); 

        } else { 

         header.setVisibility(View.GONE); 

         headerBar.setVisibility(View.GONE); 

         header.setText(null); 
        } 
       } 

      } else { 

       Station station = _filtered.get(position); 

       TextView name = ((TextView) convertView.findViewById(R.id.name)); 

       name.setText(station.getName()); 

       name.setTextColor(getResources().getColor(R.color.stations_list_text_color)); 

       ((TextView) convertView.findViewById(R.id.details)).setVisibility(View.GONE); 

       TextView header = ((TextView) convertView.findViewById(R.id.header_textview)); 

       View headerBar = ((View) convertView.findViewById(R.id.header_bar)); 

       String firstLetter = station.getTitle().substring(0, 1); 

       if (position == _alphaIndexer.get(firstLetter)) { 

        header.setVisibility(View.VISIBLE); 

        headerBar.setVisibility(View.VISIBLE); 

        header.setText(firstLetter); 

       } else { 

        header.setVisibility(View.GONE); 

        headerBar.setVisibility(View.GONE); 

        header.setText(null); 
       } 
      } 

      return convertView; 
     } 

     public int getPositionForSection(int section) { 

      return _alphaIndexer.get(_sections[section]); 
     } 

     public int getSectionForPosition(int position) { 

      return 0; 
     } 

     public Object[] getSections() { 

      return _sections; 
     } 

     @Override 
     public Filter getFilter() { 

      return _filter; 
     } 

     class MyFilter extends Filter { 

      @Override 

      public CharSequence convertResultToString(Object resultValue) { 

       if (resultValue != null) { 

        Station station = (Station) resultValue; 

        if (station != null) { 

         return station.getTitle(); 
        } 
       } 

       return null; 
      } 

      @Override 

      protected FilterResults performFiltering(CharSequence constraint) { 

       String pattern = constraint.toString().toLowerCase(); 

       FilterResults result = new FilterResults(); 

       ArrayList<Station> filt = new ArrayList<Station>(); 

       if (_pushedFromRoutes || _pushedFromWidgetConfiguration) { 

        synchronized (_stationsList.stations()) { 

         for (int i = 0, l = _stationsList.stations().length; i < l; i++) { 

          Station s = _stationsList.stations()[i]; 

          if (pattern == null || pattern.length() == 0 || s.match(pattern)) 

           filt.add(s); 
         } 

         result.count = filt.size(); 

         result.values = filt; 
        } 

       } else { 

        synchronized (_stationsList.belgianStations()) { 

         for (int i = 0, l = _stationsList.belgianStations().length; i < l; i++) { 

          Station s = _stationsList.belgianStations()[i]; 

          if (pattern == null || pattern.length() == 0 || s.match(pattern)) 

           filt.add(s); 
         } 

         result.count = filt.size(); 

         result.values = filt; 
        } 
       } 

       return result; 
      } 

      @SuppressWarnings("unchecked") 
      @Override 

      protected void publishResults(CharSequence constraint, FilterResults results) { 

       _filtered = (ArrayList<Station>) results.values; 

       updateIndex(); 

       _listView.setFastScrollEnabled(false); 

       notifyDataSetChanged(); 

       _listView.setFastScrollEnabled(true); 

       if (mDebug) Log.i("StationFragment","list count ="+_listView.getCount()); 

       if (_filterMode && _filtered.size() == 0) { 

        _listView.setVisibility(View.GONE); 

        _noResultsTextView.setVisibility(View.VISIBLE); 

       } else { 

        _listView.setVisibility(View.VISIBLE); 

        _noResultsTextView.setVisibility(View.GONE); 
       } 
      } 

     } 

    } 
} 

複雑なリストを生成する必要があることがわかります。この問題は、おそらくスクロール側が最大と最小値を得ることができると思いますか?私は本当にそれを取得していないのですか?

アクティビティ(私は多分問題がフラグメントから来ていると思います)で自分のコードを試しました。テストすると、まだ私のタブレットのSamsung Galaxyでは動作しません。私はNexus Sで試してみました。問題は私がフラグメントでこのコードを使用する必要があり、タブレット、特にGalaxyTabで動作する必要があります。

+0

これが頻繁に発生します。データセットの変更やテキスト入力のフィルタリングに基づいて 'ListAdapter'を更新する場所にコードスニペットを投稿できますか? – Devunwired

+0

listAdapterを追加しました。確認してください。 ありがとうたくさん –

答えて

3

私が言うことができるものから、問題はあなたのSectionIndexer実装がアンバランスであるということです。現在、あなたは持っている:

public int getPositionForSection(int section) { 

     return _alphaIndexer.get(_sections[section]); 
    } 

    public int getSectionForPosition(int position) { 

     return 0; 
    } 

    public Object[] getSections() { 

     return _sections; 
    } 

リストを伝える作業可能な実装が与えられたセクションがgetPositionForSection()で始まる場所の位置が、与えられた位置はgetSectionForPosition()に配置されている部分を判別する方法について何をどのように決定するかがあります。

このインデクサーコードを使用して簡単な例(Android 3.1のGTab 10.1で)を実行すると、スクロールハンドルを完全にオフスクリーンにすることができますので、ユーザーはスクロールせずにリストの先頭に戻る。この問題を解決する方法は適切に他の方法を実装することで、インデクサーのバランスを取ることです。私の例では

public int getPositionForSection(int section) { 

     return _alphaIndexer.get(_sections[section]); 
    } 

    public int getSectionForPosition(int position) { 
     //Iterate over the sections to find the closest index 
     //that is not greater than the position 
     int closestIndex = 0; 
     int latestDelta = Integer.MAX_VALUE; 

     for(int i=0; i < _sections.length; i++) { 
      int current = _alphaIndexer.get(_sections[i]); 
      if(current == position) { 
       //If position matches an index, return it immediately 
       return i; 
      } else if(current < position) { 
       //Check if this is closer than the last index we inspected 
       int delta = position - current; 
       if(delta < latestDelta) { 
        closestIndex = i; 
        latestDelta = delta; 
       } 
      } 
     } 

     return closestIndex; 
    } 

    public Object[] getSections() { 

     return _sections; 
    } 

とにかく、問題とスクロールハンドルビューを下回ることはありませんが、よりバランスの取れたことSectionIndexerがなくなり固定します。このサンプルコードでは、データソースのコピー/貼り付けが機能しない場合がありますが、コードにコードを挿入する方法についての情報が必要です。リストを更新したりフィルタリングするためのコードが `FastScroller`オブジェクトは通知されませんように行われたとき

HTH

+0

ありがとう、ありがとう非常に非常に一致 –

+0

あなたは天才です –

0

フィルタリング後に最初の項目が選択されるように、これらの呼び出しをonTextChanged()で試してください。

listView.setSelectionAfterHeaderView(); 

OR

listView.setSelection(0); 
+0

私はこれを試して、それは動作しません! :( –

関連する問題