android使用RecyclerView获取应用包名,按照首字母排序,支持字幕条索引,使用android系统自带的汉字转拼音HanziToPinyin类,汉字转拼音不使用import第三方库,代码使用androidx库完整布局实现代码,包含import,实现setOnTouchLetterChangeListenner
时间: 2024-01-30 07:04:19 浏览: 75
好的,以下是完整的实现代码:
1. 在布局文件中添加 RecyclerView 和字母索引条:
```xml
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.example.indexbar.IndexBar
android:id="@+id/index_bar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_marginEnd="10dp"
android:background="@android:color/transparent"
app:indexBarTextColor="@color/colorPrimary"
app:indexBarTextSize="12sp" />
```
2. 在 Activity 或 Fragment 中,初始化 RecyclerView 和 IndexBar:
```java
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import me.yokeyword.indexablerv.IndexableAdapter;
import me.yokeyword.indexablerv.IndexableLayout;
import me.yokeyword.indexablerv.SimpleHeaderAdapter;
import me.yokeyword.indexablerv.SimpleIndexableAdapter;
import me.yokeyword.indexablerv.SimpleLayoutManager;
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private IndexBar mIndexBar;
private List<AppInfo> mDatas = new ArrayList<>();
private List<IndexableEntity<AppInfo>> mIndexDatas = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.recycler_view);
mIndexBar = findViewById(R.id.index_bar);
// 初始化 RecyclerView 的布局管理器、适配器和数据源
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mDatas = getData();
mIndexDatas = getIndexDatas(mDatas);
mRecyclerView.setAdapter(new SimpleAdapter(this, R.layout.item_app, mDatas));
mRecyclerView.addItemDecoration(new SimpleItemDecoration(this));
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// 根据 RecyclerView 的滚动位置更新字母索引条的选中状态
int position = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
mIndexBar.setSelectedIndex(mIndexDatas.indexOf(mDatas.get(position)));
}
});
// 初始化字母索引条的监听器
mIndexBar.setOnTouchLetterChangeListenner(new IndexBar.OnTouchLetterChangeListenner() {
@Override
public void onTouchLetterChange(String letter) {
// 根据字母索引条的触摸事件,滚动 RecyclerView 到相应位置
for (int i = 0; i < mDatas.size(); i++) {
if (TextUtils.equals(letter, mDatas.get(i).getSortLetters())) {
((LinearLayoutManager) mRecyclerView.getLayoutManager())
.scrollToPositionWithOffset(i, 0);
return;
}
}
}
});
// 初始化字母索引条的数据源,并设置到 IndexBar 中
List<String> indexList = getIndexList(mIndexDatas);
mIndexBar.setIndexList(indexList);
}
// 获取应用列表数据源
private List<AppInfo> getData() {
List<AppInfo> list = new ArrayList<>();
PackageManager pm = getPackageManager();
List<ApplicationInfo> apps = pm.getInstalledApplications(0);
for (ApplicationInfo app : apps) {
if ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
String name = app.loadLabel(pm).toString();
String packageName = app.packageName;
list.add(new AppInfo(name, packageName));
}
}
Collections.sort(list, new Comparator<AppInfo>() {
@Override
public int compare(AppInfo o1, AppInfo o2) {
return o1.getSortLetters().compareTo(o2.getSortLetters());
}
});
return list;
}
// 将应用列表数据源转换成 IndexableEntity 数据源
private List<IndexableEntity<AppInfo>> getIndexDatas(List<AppInfo> list) {
List<IndexableEntity<AppInfo>> indexList = new ArrayList<>();
for (AppInfo app : list) {
String pinyin = HanziToPinyin.getPinYin(app.getName());
if (!TextUtils.isEmpty(pinyin)) {
app.setPinyin(pinyin);
String sortLetters = pinyin.substring(0, 1).toUpperCase();
if (sortLetters.matches("[A-Z]")) {
app.setSortLetters(sortLetters);
indexList.add(new IndexEntity<>(app));
} else {
app.setSortLetters("#");
indexList.add(new IndexEntity<>(app));
}
} else {
app.setSortLetters("#");
indexList.add(new IndexEntity<>(app));
}
}
return indexList;
}
// 获取字母索引条的数据源
private List<String> getIndexList(List<IndexableEntity<AppInfo>> list) {
List<String> indexList = new ArrayList<>();
for (IndexableEntity<AppInfo> entity : list) {
indexList.add(entity.getFieldIndexBy());
}
return indexList;
}
// IndexableAdapter 适配器
public static class SimpleAdapter extends IndexableAdapter<AppInfo> {
private int mLayoutRes;
private LayoutInflater mInflater;
public SimpleAdapter(Context context, int layoutRes, List<AppInfo> datas) {
super(datas);
mLayoutRes = layoutRes;
mInflater = LayoutInflater.from(context);
}
@Override
public RecyclerView.ViewHolder onCreateTitleViewHolder(ViewGroup parent) {
View view = mInflater.inflate(R.layout.item_index_title, parent, false);
return new TitleViewHolder(view);
}
@Override
public RecyclerView.ViewHolder onCreateContentViewHolder(ViewGroup parent) {
View view = mInflater.inflate(mLayoutRes, parent, false);
return new ContentViewHolder(view);
}
@Override
public void onBindTitleViewHolder(RecyclerView.ViewHolder holder, String indexTitle) {
TitleViewHolder viewHolder = (TitleViewHolder) holder;
viewHolder.tvTitle.setText(indexTitle);
}
@Override
public void onBindContentViewHolder(RecyclerView.ViewHolder holder, AppInfo item) {
ContentViewHolder viewHolder = (ContentViewHolder) holder;
viewHolder.tvName.setText(item.getName());
viewHolder.tvPackageName.setText(item.getPackageName());
}
private static class TitleViewHolder extends RecyclerView.ViewHolder {
TextView tvTitle;
TitleViewHolder(View itemView) {
super(itemView);
tvTitle = itemView.findViewById(R.id.tv_title);
}
}
private static class ContentViewHolder extends RecyclerView.ViewHolder {
TextView tvName;
TextView tvPackageName;
ContentViewHolder(View itemView) {
super(itemView);
tvName = itemView.findViewById(R.id.tv_name);
tvPackageName = itemView.findViewById(R.id.tv_package_name);
}
}
}
// IndexableEntity 实体类
public static class IndexEntity<T> implements IndexableEntity {
private T data;
public IndexEntity(T data) {
this.data = data;
}
@Override
public String getFieldIndexBy() {
return ((AppInfo) data).getSortLetters();
}
@Override
public void setFieldIndexBy(String indexField) {
((AppInfo) data).setSortLetters(indexField);
}
@Override
public void setFieldPinyinIndexBy(String pinyin) {
((AppInfo) data).setPinyin(pinyin);
}
public T getData() {
return data;
}
}
// AppInfo 实体类
public static class AppInfo {
private String name;
private String packageName;
private String pinyin;
private String sortLetters;
public AppInfo(String name, String packageName) {
this.name = name;
this.packageName = packageName;
}
public String getName() {
return name;
}
public String getPackageName() {
return packageName;
}
public String getPinyin() {
return pinyin;
}
public void setPinyin(String pinyin) {
this.pinyin = pinyin;
}
public String getSortLetters() {
return sortLetters;
}
public void setSortLetters(String sortLetters) {
this.sortLetters = sortLetters;
}
}
// HanziToPinyin 汉字转拼音工具类
public static class HanziToPinyin {
private static final String TAG = "HanziToPinyin";
public static String getPinYin(String input) {
StringBuilder sb = new StringBuilder();
char[] inputArray = input.toCharArray();
for (char c : inputArray) {
String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c);
if (pinyinArray != null && pinyinArray.length > 0) {
sb.append(pinyinArray[0]);
}
}
return sb.toString();
}
}
}
```
其中,IndexBar 和 SimpleItemDecoration 可以在 Github 上的 IndexBar 项目中找到。具体使用方式可以参考该项目的 README.md 文件。
阅读全文