快速滚动大字母缩略图预览未出现
Fast scroll large letter thumb preview not appearing
当我在列表中使用快速滚动功能时(如下图所示),我试图让包含大字母的快速滚动弹出窗口出现,但由于某种原因它不会出现。我已经查阅了各种教程,但它似乎仍然不起作用 + 我不确定代码是否丢失或某些代码在错误的位置。我们将不胜感激。
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 & 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_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/fragmentorange">
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fastScrollEnabled="true"
android:scrollbarStyle="outsideInset">
</ListView>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
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 = "[=17=]";
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);
}
}
将 MainListAdapter
中的 setupSections()
替换为以下代码:
private void setupSections() {
String initial = "[=10=]";
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);
}
关于索引字母的背景,您将 预览背景 与 缩略图 混淆了。拇指是沿着轨道移动的元素。您称为 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>
显然,Google 编写快速滚动代码的方式无法直接设置缩略图和轨道的样式。您可以尝试 this question.
中的一些建议
当我在列表中使用快速滚动功能时(如下图所示),我试图让包含大字母的快速滚动弹出窗口出现,但由于某种原因它不会出现。我已经查阅了各种教程,但它似乎仍然不起作用 + 我不确定代码是否丢失或某些代码在错误的位置。我们将不胜感激。
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 & 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_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/fragmentorange">
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fastScrollEnabled="true"
android:scrollbarStyle="outsideInset">
</ListView>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
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 = "[=17=]";
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);
}
}
将 MainListAdapter
中的 setupSections()
替换为以下代码:
private void setupSections() {
String initial = "[=10=]";
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);
}
关于索引字母的背景,您将 预览背景 与 缩略图 混淆了。拇指是沿着轨道移动的元素。您称为 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>
显然,Google 编写快速滚动代码的方式无法直接设置缩略图和轨道的样式。您可以尝试 this question.
中的一些建议