1

リストビューと編集テキストボックスが上部にあるページを持つアプリに取り組んでいます。edittext ボックスに何かを入力すると、リストビューに表示される項目がフィルターされます。私が抱えている問題は、スライダーの横に表示される高速スクロール アイコンにあります。たとえば、文字「b」を入力すると、スクローラーがビューから消えます。

ここに画像の説明を入力

この行を (リスト スクローラーを更新するために) 追加しましたが、機能しませんでした。

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

_filterText.addTextChangedListener(new TextWatcher(){

    public void afterTextChanged(Editable s) {

        _listView.setFastScrollEnabled(false);

        _listView.setFastScrollEnabled(true);

    }

私もこの件名を参照してフォローしましたが、同じ問題ではなかったと思います。 Android: 最初は fastScrollEnabled が機能しない

わかりました、ここにすべての私のクラスがあります:

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 で動作する必要があります。

4

2 に答える 2

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をよりバランスの取れたものに修正すると問題が解消され、スクロール ハンドルがビューの下に移動することはありません。このサンプル コードは、データ ソースのコピー/貼り付けが機能しない場合がありますが、コードに挿入する方法については理解できるはずです。

HTH

于 2012-05-24T20:20:36.250 に答える
0

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

listView.setSelectionAfterHeaderView();

また

listView.setSelection(0);
于 2012-05-21T18:36:04.747 に答える