快速滚动大字母拇指预览未出现

Posted

技术标签:

【中文标题】快速滚动大字母拇指预览未出现【英文标题】:Fast scroll large letter thumb preview not appearing 【发布时间】:2015-09-28 01:58:26 【问题描述】:

我试图让包含大字母的快速滚动弹出窗口在我的列表中出现快速滚动功能时出现(如下图所示),但由于某种原因它不会出现。我已经查阅了各种教程,但它似乎仍然不起作用 + 我不确定是否缺少代码或某些代码位于错误的位置。我们将不胜感激。

strings.xml

<resources>
    <string name="app_name">World</string>

    <string name="action_search">Search</string>

    <string name="search_hint">Continent name</string>

    <string name="item0">Azerbaijan</string>
    <string name="item1">Bosnia &amp; Herzegovina</string>
    <string name="item2">Brazil</string>
    <string name="item3">China</string>
    <string name="item4">Denmark</string>
    <string name="item5">France</string>
    <string name="item6">Hungary</string>
    <string name="item7">Italy</string>
    <string name="item8">Japan</string>
    <string name="item9">Lithuania</string>
    <string name="item10">Luxembourg</string>
    <string name="item11">Malta</string>
    <string name="item12">Monaco</string>
    <string name="item13">Norway</string>
    <string name="item14">Portugal</string>
    <string name="item15">Thailand</string>
    <string name="item16">Singapore</string>
    <string name="item17">South Korea</string>
    <string name="item18">Sweden</string>
    <string name="item19">United Kingdom</string>
    <string name="item20">United States</string>


    <string name="item0_description">Item 0 description</string>
    <string name="item1_description">Item 1 description</string>
    <string name="item2_description">Item 2 description</string>
    <string name="item3_description">Item 3 description</string>
    <string name="item4_description">Item 4 description</string>
    <string name="item5_description">Item 5 description</string>
    <string name="item6_description">Item 6 description</string>
    <string name="item7_description">Item 7 description</string>
    <string name="item8_description">Item 8 description</string>
    <string name="item9_description">Item 9 description</string>
    <string name="item10_description">Item 10 description</string>
    <string name="item11_description">Item 11 description</string>
    <string name="item12_description">Item 12 description</string>
    <string name="item13_description">Item 13 description</string>
    <string name="item14_description">Item 14 description</string>
    <string name="item15_description">Item 15 description</string>
    <string name="item16_description">Item 16 description</string>
    <string name="item17_description">Item 17 description</string>
    <string name="item18_description">Item 18 description</string>
    <string name="item19_description">Item 19 description</string>
    <string name="item20_description">Item 20 description</string>

    <string-array name="items">
        //item 0    <item>@string/item0</item>
        //item 1    <item>@string/item1</item>
        //item 2    <item>@string/item2</item>
        //item 3    <item>@string/item3</item>
        //item 4    <item>@string/item4</item>
        //item 5    <item>@string/item5</item>
        //item 6    <item>@string/item6</item>
        //item 7    <item>@string/item7</item>
        //item 8    <item>@string/item8</item>
        //item 9    <item>@string/item9</item>
        //item 10    <item>@string/item10</item>
        //item 11    <item>@string/item11</item>
        //item 12    <item>@string/item12</item>
        //item 13    <item>@string/item13</item>
        //item 14    <item>@string/item14</item>
        //item 15    <item>@string/item15</item>
        //item 16    <item>@string/item16</item>
        //item 17    <item>@string/item17</item>
        //item 18    <item>@string/item18</item>
        //item 19    <item>@string/item19</item>
        //item 20    <item>@string/item20</item>
    </string-array>

    <string-array name="item_descriptions">
        //item 0    <item>@string/item0_description</item>
        //item 1    <item>@string/item1_description</item>
        //item 2    <item>@string/item2_description</item>
        //item 3    <item>@string/item3_description</item>
        //item 4    <item>@string/item4_description</item>
        //item 5    <item>@string/item5_description</item>
        //item 6    <item>@string/item6_description</item>
        //item 7    <item>@string/item7_description</item>
        //item 8    <item>@string/item8_description</item>
        //item 9    <item>@string/item9_description</item>
        //item 10    <item>@string/item10_description</item>
        //item 11    <item>@string/item11_description</item>
        //item 12    <item>@string/item12_description</item>
        //item 13    <item>@string/item13_description</item>
        //item 14    <item>@string/item14_description</item>
        //item 15    <item>@string/item15_description</item>
        //item 16    <item>@string/item16_description</item>
        //item 17    <item>@string/item17_description</item>
        //item 18    <item>@string/item18_description</item>
        //item 19    <item>@string/item19_description</item>
        //item 20    <item>@string/item20_description</item>
    </string-array>

</resources>

FragmentCountries.java

    public class FragmentCountries extends ListFragment implements SearchView.OnQueryTextListener 

    private CountriesListAdapter mAdapter;

    public FragmentCountries() 
        // Required empty constructor
    

    public static FragmentCountries newInstance() 
        return new FragmentCountries();
    

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
        View view = inflater.inflate(R.layout.fragment_countries, container, false);
        setHasOptionsMenu(true);
        initialize(view);
        return view;
    

    List<Countries> list = new ArrayList<Countries>();
    private void initialize(View view) 
        String[] items = getActivity().getResources().getStringArray(R.array.country_names);
        String[] itemDescriptions = getActivity().getResources().getStringArray(R.array.country_descriptions);
        for (int n = 0; n < items.length; n++)
            Countries countries = new Countries();
            countries.setID();
            countries.setName(items[n]);
            countries.setDescription(itemDescriptions[n]);
            list.add(countries);
        

        mAdapter = new CountriesListAdapter(list, getActivity());
        setListAdapter(mAdapter);
    

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) 
        // Set up search view
        inflater.inflate(R.menu.menu_countries, menu);
        MenuItem item = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
        searchView.setIconifiedByDefault(true);
        searchView.clearAnimation();
        searchView.setOnQueryTextListener(this);
        searchView.setQueryHint(getResources().getString(R.string.search_hint));

        View close = searchView.findViewById(R.id.search_close_btn);
        close.setBackgroundResource(R.drawable.ic_action_content_clear);
    

    @Override
    public boolean onQueryTextSubmit(String newText) 
        return false;
    

    @Override
    public boolean onQueryTextChange(String newText) 
        mAdapter.getFilter().filter(newText);
        return false;
    


    @Override
    public int getPositionForSection(int section) 
        return alphaIndexer.get(sections[section]);
    

    @Override
    public int getSectionForPosition(int position) 
        return 0;
    

    @Override
    public Object[] getSections() 
        return sections;
    

CountriesListAdapter.java

public class CountriesListAdapter extends BaseAdapter implements Filterable, SectionIndexer 

    private String mSections = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private List<Countries> mData;
    private List<Countries> mFilteredData;
    private LayoutInflater mInflater;
    private ItemFilter mFilter;

    public CountriesListAdapter (List<Countries> data, Context context) 
        mData = data;
        mFilteredData = new ArrayList(mData);
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    

    @Override
    public int getCount() 
        return mFilteredData.size();
    

    @Override
    public String getItem(int position) 
        return mFilteredData.get(position).getName();
    

    @Override
    public long getItemId(int position) 
        return position;
    

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 

        ViewHolder holder;
        if (convertView == null) 
            convertView = mInflater.inflate(R.layout.list_item_dualline, parent, false);
            holder = new ViewHolder();

            holder.title = (TextView) convertView.findViewById(R.id.item_name);
            holder.description = (TextView) convertView.findViewById(R.id.item_description);

            convertView.setTag(holder);
         else 
            holder = (ViewHolder) convertView.getTag();
        

        holder.title.setText(mFilteredData.get(position).getName());
        holder.description.setText(mFilteredData.get(position).getDescription());

        return convertView;
    

    @Override
    public Filter getFilter() 
        if (mFilter == null) 
            mFilter = new ItemFilter();
        
        return mFilter;
    

    /**
     * View holder
     */
    static class ViewHolder 
        private TextView title;
        private TextView description;
    

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

            if (TextUtils.isEmpty(constraint)) 
                results.count = mData.size();
                results.values = new ArrayList(mData);
             else 
                //Create a new list to filter on
                List<Countries> resultList = new ArrayList<Countries>();
                for (Countries str : mData) 
                    if (str.getName().toLowerCase().contains(constraint.toString().toLowerCase())) 
                        resultList.add(str);
                    
                
                results.count = resultList.size();
                results.values = resultList;
            
            return results;
        


        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) 
            if (results.count == 0) 
                mFilteredData.clear();
                notifyDataSetInvalidated();
             else 
                mFilteredData = (ArrayList<Countries>)results.values;
                notifyDataSetChanged();
            
        
    


    @Override
    public int getPositionForSection(int section) 
        return alphaIndexer.get(sections[section]);
    

    @Override
    public int getSectionForPosition(int position) 
        return 0;
    

    @Override
    public Object[] getSections() 
        String[] sections = new String[mSections.length()];
        for (int i = 0; i < mSections.length(); i++)
            sections[i] = String.valueOf(mSections.charAt(i));
        return sections;
    


Main.java

public class Main 
    public Main()

    private String continent;
    private String description;
    private boolean selected;

    public String getContinent()
        return continent;
    

    public void setContinent(String continent)
        this.continent = continent;
    

    public String getDescription()
        return description;
    

    public void setDescription(String description)
        this.description = description;
    

    private int _id;
    public void getID(int _id)
        this._id = _id;
    

    public int setID()
        return _id;
    

    public boolean isSelected() 
        return selected;
    

    public void setSelected(boolean selected) 
        this.selected = selected;
    

drawable/orange_fastscroll_thumb.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <corners
        android:topLeftRadius="44dp"
        android:topRightRadius="44dp"
        android:bottomLeftRadius="44dp" />
    <padding
        android:paddingLeft="22dp"
        android:paddingRight="22dp" />

    <solid android:color="@color/orange" />
</shape>

清单

<activity
    android:name="OrangeActivity"
    android:label="@string/orange_title"
    android:theme="@style/OrangeTheme" >
</activity>

<style name="OrangeTheme" parent="AppBaseTheme">
    <item name="android:fastScrollThumbDrawable">@drawable/orange_fastscroll_thumb</item>
    <item name="android:fastScrollOverlayPosition">atThumb</item>
    <item name="android:fastScrollTextColor">@color/white</item>
    <item name="android:fastScrollTrackDrawable">@drawable/fastscroll_thumb_pressed</item>
</style>

xml 布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    android:orientation="vertical"
    android:id="@+id/fragmentorange">

    <ListView
        android:id="@android:id/list"
        android:layout_
        android:layout_
        android:fastScrollEnabled="true"
        android:scrollbarStyle="outsideInset">
    </ListView>

    <TextView
        android:layout_
        android:layout_
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="@string/no_results"
        android:visibility="invisible"
        android:gravity="center_horizontal"
        android:id="@android:id/empty"
        android:layout_marginTop="100dp"
        android:textColor="@color/white"/>

</LinearLayout>

MainListAdapter

public class MainListAdapter extends BaseAdapter implements Filterable, SectionIndexer 

    private List<Main> mData;
    private List<Main> mFilteredData;
    private LayoutInflater mInflater;
    private ItemFilter mFilter;

    private Object[] mSections;
    private int[] mSectionsIndexedByPosition;
    private int[] mPositionsIndexedBySection;

    public MainListAdapter (List<Main> data, Context context) 
        mData = data;
        mFilteredData = new ArrayList(mData);
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        setupSections();
    

    @Override
    public int getCount() 
        return mFilteredData.size();
    

    @Override
    public Main getItem(int position) 
        return mFilteredData.get(position);
    

    @Override
    public long getItemId(int position) 
        return position;
    

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 

        ViewHolder holder;
        if (convertView == null) 
            convertView = mInflater.inflate(R.layout.list_item, parent, false);
            holder = new ViewHolder();

            holder.title = (TextView) convertView.findViewById(R.id.item);
            holder.description = (TextView) convertView.findViewById(R.id.item_description);

            convertView.setTag(holder);
         else 
            holder = (ViewHolder) convertView.getTag();
        

        Main main = getItem(position);
        holder.title.setText(main.getContinent());
        holder.description.setText(main.getDescription());
        if (main.isSelected()) 
            convertView.setBackgroundColor(Color.parseColor("#1C3F96"));
            holder.title.setTextColor(Color.parseColor("#FFFFFF"));
            holder.description.setTextColor(Color.parseColor("#FFFFFF"));
         else 
            convertView.setBackgroundColor(Color.TRANSPARENT);
            holder.title.setTextColor(Color.parseColor("#FFFFFF"));
            holder.description.setTextColor(Color.parseColor("#B5B5B5"));
        

        holder.title.setText(mFilteredData.get(position).getContinent());
        holder.description.setText(mFilteredData.get(position).getDescription());

        return convertView;
    

    @Override
    public Filter getFilter() 
        if (mFilter == null) 
            mFilter = new ItemFilter();
        
        return mFilter;
    

    /**
     * View holder
     */
    static class ViewHolder 
        private TextView title;
        private TextView description;
    

    /**
     * Filter for filtering list items
     */
    /**
     * <p>An array filter constrains the content of the array adapter with
     * a prefix. Each item that does not start with the supplied prefix
     * is removed from the list.</p>
     */
    private class ItemFilter extends Filter 
        @Override
        protected FilterResults performFiltering(CharSequence constraint) 
            FilterResults results = new FilterResults();

            if (TextUtils.isEmpty(constraint)) 
                results.count = mData.size();
                results.values = new ArrayList(mData);
             else 
                //Create a new list to filter on
                List<Main> resultList = new ArrayList<Main>();
                for (Main str : mData) 
                    if (str.getContinent().toLowerCase().contains(constraint.toString().toLowerCase())) 
                        resultList.add(str);
                    
                
                results.count = resultList.size();
                results.values = resultList;
            
            return results;
        

        /**
         * Runs on ui thread
         * @param constraint the constraint used for the result
         * @param results the results to display
         */
        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) 
            if (results.count == 0) 
                mFilteredData.clear();
                notifyDataSetInvalidated();
             else 
                mFilteredData = (ArrayList<Main>)results.values;
                notifyDataSetChanged();
            
            setupSections();
        
    

    @Override
    public int getPositionForSection(int section) 
        return mPositionsIndexedBySection[section];
    

    @Override
    public int getSectionForPosition(int position) 
        return mSectionsIndexedByPosition[position];
    

    @Override
    public Object[] getSections() 

        return mSections;
    

    private void setupSections() 

        String initial = "\0";
        List<String> sections = new ArrayList<String>();
        mSectionsIndexedByPosition = new int[mFilteredData.size()];
        mPositionsIndexedBySection = new int[mFilteredData.size()]; // yes it's bigger than necessary

        int section = 0;
        for (int pos = 0; pos < mFilteredData.size(); pos++) 
            Main country = mFilteredData.get(pos);
            if (initial.charAt(0) != country.getContinent().charAt(0)) 
                initial = country.getContinent().substring(0, 1);
                sections.add(initial);
                mPositionsIndexedBySection[section] = pos;
                mSectionsIndexedByPosition[pos] = section;
                section++;
             else 
                mSectionsIndexedByPosition[pos] = section;
            
        
        mSections = sections.toArray();
        mPositionsIndexedBySection = Arrays.copyOf(mPositionsIndexedBySection, section);
    

【问题讨论】:

你永远不会分配alphaIndexer ... 忘记这个...让 CountryListAdapter 实现 SectionIndexer ... 现在 getSections() 应该返回 String[] "*", "A" ,... "Z" ... getSectionForPosition 应该根据项目数据返回字母的索引(由 getSections() 返回的数组中 mFilteredData.get(position).getName()[0] 的索引 ... 和 getPositionForSection ... 你应该在 mFilteredData 返回索引第一个带字母的国家出现在哪里 @Selvin 我已经在适配器类中获得了implements Filterable,那么我应该如何包含implements SectionIndexer 呢? implements SectionIndexer 而不是, SectionIndexer 但是是的......然后会有困难的部分实施......但我在上一篇评论中给了你一些提示......你可以做它(看起来像一个基本的编程练习) @Selvin 我已经更新了我的代码 【参考方案1】:

MainListAdapter 中的setupSections() 替换为以下代码:

    private void setupSections() 

        String initial = "\0";
        List<String> sections = new ArrayList<String>();
        mSectionsIndexedByPosition = new int[mFilteredData.size()];
        mPositionsIndexedBySection = new int[mFilteredData.size()];

        int section = 0;
        for (int pos = 0; pos < mFilteredData.size(); pos++) 
            Main country = mFilteredData.get(pos);
            if (initial.charAt(0) != country.getContinent().charAt(0)) 
                initial = country.getContinent().substring(0, 1);
                section = sections.size();
                sections.add(initial);
                mPositionsIndexedBySection[section] = pos;
                mSectionsIndexedByPosition[pos] = section;
             else 
                mSectionsIndexedByPosition[pos] = section;
            
        
        mSections = sections.toArray();
        mPositionsIndexedBySection = Arrays.copyOf(mPositionsIndexedBySection, mSections.length);

    

关于索引字母的背景,您将 预览背景thumb 混淆了。拇指是沿轨道移动的元素。您调用orange_fastscroll_thumb.xml 的文件实际上是预览背景而不是拇指。如果你把名字改成orange_fastscroll_preview_bg,你可以这样设置:

<style name="OrangeTheme" parent="AppTheme">
    <item name="android:fastScrollPreviewBackgroundRight">@drawable/orange_fastscroll_preview_bg</item>
    <item name="android:fastScrollOverlayPosition">atThumb</item>
</style>

显然,谷歌编码快速滚动代码的方式,你不能直接设置拇指和轨道的样式。您可以在this question.中尝试一些建议

【讨论】:

好的,现在我看到你夸大了一个视图,你是说它有一个 ListView? ListFragment 已经拥有自己的 ListView,您可以在其中设置适配器。您应该做的是扩展 Fragment 而不是 ListFragment 并将适配器设置在正确的 ListView 上。 请更改您的答案以更好地回答问题 使用您的代码后return mFilteredData.get(position).getContinent(); 变为红色下划线并返回此错误:Required: 'com.apptacularapps.world.data.Main' Found: 'java.lang.String' Main.java 类已添加。截图:tiikoni.com/tis/view/?id=f790a24 那是因为getContinent()返回一个字符串,但是你定义getItem()返回Main。要么将public Main getItem(int position) 更改为public String getItem(int position) - 要么-- 通过取消getContinent()return mFilteredData.get(position).getContinent(); 更改为return mFilteredData.get(position); 您的第二个建议是我做的,因为它是更好的选择,但是在部署期间滚动列表后,我在public int getPositionForSection(int section) 中收到return mPositionsIndexedBySection[section]; 这一行的java.lang.ArrayIndexOutOfBoundsException: length=1; index=1 at com.apptacularapps.world.adapters.MainListAdapter.getPositionForSection(MainListAdapter.java:160) 错误

以上是关于快速滚动大字母拇指预览未出现的主要内容,如果未能解决你的问题,请参考以下文章

虚拟滚动条实现大数据集预览

相机预览层未显示

怎样快速预览pdf文档

sparkSQL新增优化器实现复杂计算的快速预览

确定何时显示 recyclerview 快速滚动拇指?

Xcode SwiftUI 如何滚动预览画布?