迷你播放器--第一阶段(6)
添加搜索定位功能(进阶)-使用filter过滤以及对汉语拼音的排序匹配;
本文章为CSDN作者原创,转载请保留出处:http://blog.csdn.net/lrs0304/article/details/38434239
查看项目源代码请前往:迷你播放器-综述
请注意,该项目为android项目,如果已经学习过这一节请阅读下一篇。
先上效果图(本项目出现的小bug将在下一阶段修复,同时界面将有一定调整)
注:本节参考了xiaanming 的博客:http://blog.csdn.net/xiaanming/article/details/12684155,详情请打开链接,有详细的原理介绍,这里主要讲我优化的地方
- 重写排序方法
- 针对onScroll会出现的一些错误进行修复;
- 快速定位如果点击的字母没有存在节点,则定位到该字母前一个最近的节点;
- 支持使用大小写进行搜索,例如存在 广岛之恋-莫文蔚.mp3,无论输入"Guang"还是"guang"还是"广"都能给出搜索结果。
1、重写排序方法,两个if的作用是将如果输入的是拼音,将以汉字为开头的数据排在后面。
package com.liangrensheng.music_player.player;
import java.util.Comparator;
import com.liangrensheng.music_player.player.MusicData;
/**
* PinyinComparator接口用来对ListView中的数据根据A-Z进行排序, 前面两个if判断主要是将不是以汉字开头的数据放在后面
*
*/
public class MusicComparator implements Comparator<MusicData> {
@Override
public int compare(MusicData o1, MusicData o2) {
if (o1.mSortLetter.equals("@") || o2.mSortLetter.equals("#")) {
return -1;
} else if (o1.mSortLetter.equals("#") || o2.mSortLetter.equals("@")) {
return 1;
} else {
return o1.mSortLetter.compareTo(o2.mSortLetter);
}
}
}
2、针对原项目ListView中onScroll时间的一些优化,主要是为了使搜索结果页面在滑动的时候依然具有挤压效果。
mListView.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (totalItemCount == 0) { // 如果没有item则无需配置挤压效果
titleLayout.setVisibility(View.GONE);
return;
} else if (totalItemCount == 1) { // 仅有一个的时候是没有nextSection的
titleLayout.setVisibility(View.VISIBLE);
int section = mListViewAdapter.getSectionForPosition(firstVisibleItem);
title.setText(mListViewAdapter.getBean(mListViewAdapter.getPositionForSection(section)).sortLetters);
} else {
titleLayout.setVisibility(View.VISIBLE);
int section = mListViewAdapter.getSectionForPosition(firstVisibleItem);
int nextSection = mListViewAdapter.getSectionForPosition(firstVisibleItem + 1);
int nextSecPosition = mListViewAdapter.getPositionForSection(+nextSection);
if (firstVisibleItem != lastFirstVisibleItem) {
MarginLayoutParams params = (MarginLayoutParams) titleLayout.getLayoutParams();
params.topMargin = 0; // 初始位置
titleLayout.setLayoutParams(params);
title.setText(mListViewAdapter.getBean(mListViewAdapter.getPositionForSection(section)).sortLetters);
}
if (nextSecPosition == firstVisibleItem + 1) { // 实现挤压效果
View childView = view.getChildAt(0);
if (childView != null) {
int titleHeight = titleLayout.getHeight();
int bottom = childView.getBottom();
MarginLayoutParams params = (MarginLayoutParams) titleLayout.getLayoutParams();
if (bottom < titleHeight) {
float pushedDistance = bottom - titleHeight;
params.topMargin = (int) pushedDistance;
titleLayout.setLayoutParams(params);
} else if (params.topMargin != 0) {
params.topMargin = 0;
titleLayout.setLayoutParams(params);
}
}
}
lastFirstVisibleItem = firstVisibleItem;
}
}
});
3、快速定位如果点击的字母没有存在节点,则定位到该字母前一个最近的节点。
sideBar.setOnTouchingLetterChangedListener(new OnTouchingLetterChangedListener() {
@Override
public void onTouchingLetterChanged(String s) { // 设置右侧触摸监听
// 该字母首次出现的位置
char ch = s.charAt(0);
int position = mListViewAdapter.getPositionForSection(ch);
while (position == -1) { // 找不到则找最近的一个
ch--;
if (ch < 'A')
break;
position = mListViewAdapter.getPositionForSection(ch);
}
mListView.setSelection(position);
}
});
4、支持使用大小写进行搜索,例如存在 广岛之恋-莫文蔚.mp3,无论输入"Guang"还是"guang"还是"广"都能给出搜索结果。
/**
* 根据输入框中的值来过滤数据并更新ListView
*
* @param filterStr
*/
private void filterData(String filterStr) { //这个filterStr在传入的时候已经转化为小写的了
List<ListViewBean> filterDateList = new ArrayList<ListViewBean>();
if (TextUtils.isEmpty(filterStr)) {
filterDateList = mListViewSource;
tvNoMusic.setVisibility(View.GONE);
} else {
filterDateList.clear();
for (ListViewBean sortModel : mListViewSource) {
String name = sortModel.musicName.toLowerCase();// 转为小写在寻找
if (name.indexOf(filterStr) != -1
|| characterParser.getSelling(name).startsWith(
filterStr)) {
filterDateList.add(sortModel);
}
}
}
// 根据a-z进行排序
Collections.sort(filterDateList, listViewComparator);
mListViewAdapter.refreshAdapter(filterDateList);
lastFirstVisibleItem = -1;// 刷新了列表,布局重新初始化
MarginLayoutParams params = (MarginLayoutParams) titleLayout
.getLayoutParams();
params.topMargin = 0;// 初始位置
titleLayout.setLayoutParams(params);
if (filterDateList.size() == 0) {
tvNoMusic.setVisibility(View.VISIBLE);
}
}