我的应用中有一个recyclerview,它包含两个textview,一个是rankTextView,另一个是nameTextview。像这样的东西;
我想要做的是对这个 recyclerview 进行排序,首先按最低数字顺序,如果有两个相同的数字,那么我希望它按字符串排序。在上面的截图中,我有两个人排名 1,首先我希望 recyclerview 将这些放在顶部,然后按 String 排序。
我已经在网上搜索过,看看我该怎么做,但是我是 android 新手,我无法在我的项目中使用/调整这些发现。例如;
How to sort Strings on an Android RecyclerView?
What is the SortedList<T> working with RecyclerView.Adapter?
我创建了一个自定义适配器,其中包含一个名为 rankTextview 的 TextView 和另一个名为 nameTextview 的 TextView ,如下所示;
rankTextview = (TextView) itemView.findViewById(R.id.ranktextview);
nameTextview = (TextView) itemView.findViewById(R.id.nametextview);
然后我有一个方法可以将这些 TextView 中的值作为参数,像这样;
public addPerson(String rankTextview, String personTextview,) {
this.rankTextview = rankTextview;
this.personTextview = personTextview;
}
然后我在我的主类中调用这个方法来添加数据,像这样;
person.add(new addPerson
("1\nrank", "James Kub"));
person.add(new addPerson
("2\nrank", "Peter Hanly"));
person.add(new addPerson
("3\nrank", "Josh Penny"));
person.add(new addPerson
("1\nrank", "Danny Jackson"));
person.add(new addPerson
("3\nrank", "Brad Black"));
现在我要做的是首先按排名最低的数字顺序排序这些数据,例如 1、2,3... 如果有两个相同的数字,那么我想按名称字母顺序排序。此外,将来我的应用程序将包含点,而不是像这样的十进制数字。 1.1, 1.5, 1.1, 2.1, 2.5 等等,那么按等级排序时是否可以考虑十进制数。
另外,由于我有这么多行代码,我不确定要提供哪些部分,不提供哪些部分,如果我缺少任何应该包含的代码,请告诉我。
已编辑:
public void animateTo(List<ExampleModel> models) {
applyAndAnimateRemovals(models);
applyAndAnimateAdditions(models);
applyAndAnimateMovedItems(models);
}
private void applyAndAnimateRemovals(List<ExampleModel> newModels) {
for (int i = mModels.size() - 1; i >= 0; i--) {
final ExampleModel model = mModels.get(i);
if (!newModels.contains(model)) {
removeItem(i);
}
}
}
private void applyAndAnimateAdditions(List<ExampleModel> newModels) {
for (int i = 0, count = newModels.size(); i < count; i++) {
final ExampleModel model = newModels.get(i);
if (!mModels.contains(model)) { // error here, saying cannot resolve method contains
addItem(i, model);
}
}
}
private void applyAndAnimateMovedItems(List<ExampleModel> newModels) {
for (int toPosition = newModels.size() - 1; toPosition >= 0; toPosition--) {
final ExampleModel model = newModels.get(toPosition);
final int fromPosition = mModels.indexOf(model);
if (fromPosition >= 0 && fromPosition != toPosition) {
moveItem(fromPosition, toPosition);
}
}
}
public ExampleModel removeItem(int position) {
final ExampleModel model = mModels.remove(position); // Error here, saying in sortedlist cannot be applied to (int)
notifyItemRemoved(position);
return model;
}
public void addItem(int position, ExampleModel model) {
mModels.add(position, model); // Error here, saying add has private access in 'android.support.v7.util.SortedList'
notifyItemInserted(position);
}
public void moveItem(int fromPosition, int toPosition) {
final ExampleModel model = mModels.remove(fromPosition); // Error here, saying in sortedlist cannot be applied to (int)
mModels.add(toPosition, model); // Error here, saying add has private access in 'android.support.v7.util.SortedList'
notifyItemMoved(fromPosition, toPosition);
}
最佳答案
在 RecyclerView
中有一些实现排序的选项.当然可以依赖Comparable<T>
和 Comparator<T>
接口(interface),但正如您所提到的,也可以利用 SortedList<T>
Android SDK 中定义的类。
SortedList<T>
的目的|正在简化 RecyclerView
中的元素排序,允许您拦截“添加新项目”、“已删除项目”等重要事件。
在您的情况下,您可以进行如下操作:
定义一个 Person 类来包装等级和名称。请注意,在这个版本中,我假设排名具有整数值,但移动到十进制值非常容易。
class Person { private String rank; private String name; public Person(String rank, String name) { this.rank = rank; this.name = name; } // getters and setters here }
定义一个 Activity 来构建
RecyclerView
和相应的适配器。在这个例子中,我包含了一个FloatingActionButton
用于插入新的随机人员。如您所见,当创建一个新的Person
, 方法addPerson
在适配器上调用。它的作用是更新RecyclerView
,根据适配器本身定义的标准对其进行排序(参见第 3 点)。public class SortPersonsActivity extends AppCompatActivity { private List<Person> mPersons; private SortPersonsAdapter mPersonsAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_persons_list); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); mPersons = new ArrayList<>(); mPersons.add(new Person("1\nrank", "James Kub")); mPersons.add(new Person("2\nrank", "Peter Hanly")); mPersons.add(new Person("3\nrank", "Josh Penny")); mPersons.add(new Person("1\nrank", "Danny Jackson")); mPersons.add(new Person("3\nrank", "Brad Black")); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.lst_items); recyclerView.setLayoutManager(getLayoutManager()); mPersonsAdapter = new SortPersonsAdapter(this, mPersons); recyclerView.setAdapter(mPersonsAdapter); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // building new fake person Person person = new Person( buildRandomInt(10) + "\nrank", buildRandomName(5) + " " + buildRandomName(5)); // let's keep also basic list updated mPersons.add(person); // let's update adapter mPersonsAdapter.addPerson(person); } }); } private RecyclerView.LayoutManager getLayoutManager() { LinearLayoutManager llm = new LinearLayoutManager(this); llm.setOrientation(LinearLayoutManager.VERTICAL); return llm; } // support method for random names and ranks here }
实现一个依赖于
SortedList<Person>
的 RecyclerView 适配器.在这里需要注意的是,所有的人都被插入到SortedList<Person>
中。 .创建SortedList<T>
需要Callback
被定义为拦截事件以及定义排序标准。如您所见,在我们的例子中,compare
方法定义了排序人员的标准,而onInserted
方法定义了当插入新的人时要做什么(在这种情况下通知数据集更改以更新RecyclerView
)。另请注意addPerson
的实现第 2 点描述的方法。它只是将 Person 添加到SortedList
, 因为更新的逻辑RecyclerView
嵌入到Callback
方法onInserted
前面提到过。class SortPersonsAdapter extends RecyclerView.Adapter<SortPersonsAdapter.PersonViewHolder> { protected static class PersonViewHolder extends RecyclerView.ViewHolder { View layout; TextView txt_rank; TextView txt_full_name; public PersonViewHolder(View itemView) { super(itemView); layout = itemView; txt_rank = (TextView) itemView.findViewById(R.id.txt_rank); txt_full_name = (TextView) itemView.findViewById(R.id.txt_full_name); } } private Context mContext; private LayoutInflater mLayoutInflater; private SortedList<Person> mPersons; public SortPersonsAdapter(Context context, List<Person> persons) { mContext = context; mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mPersons = new SortedList<>(Person.class, new PersonListCallback()); mPersons.addAll(persons); } public void addPerson(Person person) { mPersons.add(person); } @Override public int getItemCount() { return mPersons.size(); } @Override public SortPersonsAdapter.PersonViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = mLayoutInflater.inflate(R.layout.view_person_item, parent, false); return new PersonViewHolder(itemView); } @Override public void onBindViewHolder(final PersonViewHolder viewHolder, final int position) { Person person = mPersons.get(position); viewHolder.txt_rank.setText(person.getRank()); viewHolder.txt_full_name.setText(person.getName()); } /** * Implementation of callback for getting updates on person list changes. */ private class PersonListCallback extends SortedList.Callback<Person> { @Override public int compare(Person p1, Person p2) { String[] rank1 = p1.getStringRank().split("\n"); String[] rank2 = p2.getStringRank().split("\n"); int diff = Integer.parseInt(rank1[0]) - Integer.parseInt(rank2[0]); return (diff == 0) ? p1.getName().compareTo(p2.getName()) : diff; } @Override public void onInserted(int position, int count) { notifyItemInserted(position); } @Override public void onRemoved(int position, int count) { notifyItemRemoved(position); } @Override public void onMoved(int fromPosition, int toPosition) { } @Override public void onChanged(int position, int count) { } @Override public boolean areContentsTheSame(Person oldItem, Person newItem) { return false; } @Override public boolean areItemsTheSame(Person item1, Person item2) { return false; } } }
希望这会有所帮助。 Here我已经为你的 RecyclerView
做了一个实现,以防您需要有关代码的更多详细信息。
关于java - 如何按最低数字/字符串Android Studio对recyclerview进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34965147/