setFastScrollEnabled不能完美地工作

时间:2012-05-02 09:41:56

标签: android listview

我正在开发一个应用程序,该应用程序的页面包含listview和顶部的edittext框。当您在edittext框中键入内容时,它将过滤列表视图中显示的项目。我遇到的问题是滑块侧面出现的快速滚动图标。 当我输入字母“b例如。

时,滚动条会从视图中移出

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);

    }

我也是这个主题,并遵循它,我想这不是同一个问题。 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);
                }
            }

        }

    }
}

你看我必须生成一个复杂的列表,我认为问题可能来自于此,也许滚动器可以获得最大值和最小值?我真的不明白吗?

我在一项活动中尝试了我的代码(我认为问题可能来自片段),当我测试它时,它仍然无法在我的平板电脑三星Galaxy中工作。我在Nexus S中尝试过它并且有效。问题我必须在片段中使用此代码,它必须在平板电脑中工作,尤其是GalaxyTab。

2 个答案:

答案 0 :(得分: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()中的哪个部分。< / p>

当我使用这个索引器代码运行一个简化的示例(在我的带有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

答案 1 :(得分:0)

onTextChanged()中尝试这些调用,以便在过滤后选择第一个项目。

listView.setSelectionAfterHeaderView();

OR

listView.setSelection(0);