我的应用程序中有一个recylerview,它包含两个textview,一个是rankTextView,另一个是nameTextview。像这样的东西;
我想要做的是对这个recylerview进行排序,首先是最低数字顺序,如果有两个相同的数字,那么我希望它由字符串排序。在上面的截图我有例如,两个人排名1,首先我希望recylerview将这些放在顶部,然后按字符串排序。
我在网上搜索过,看看我怎样才能做到这一点,但是对于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 ......如果有两个相同的数字,那么我想按名称字母顺序排序。此外,将来我的应用程序将包含点而不是排名,这将是十进制数字。 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);
}
答案 0 :(得分:12)
在RecyclerView
中实施排序有一些选项。当然,可以依赖Comparable<T>
和Comparator<T>
接口,但正如您所提到的,也可以利用Android SDK中定义的SortedList<T>
类。
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
}
定义活动在哪里构建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
方法定义了插入新Person时要执行的操作(通知数据集更改以进行更新RecyclerView
在这种情况下)。请注意第2点中描述的addPerson
方法的实现。它只是向SortedList
添加了一个Person,因为更新RecyclerView
的逻辑嵌入到Callback
方法中{ {1}}之前提到过。
onInserted
希望这可以提供帮助。 Here我已为您的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;
}
}
}
提供了一个实现,以防您需要有关代码的更多详细信息。
答案 1 :(得分:8)
public int compare(Person p1, Person p2) {
if(p1.getRank() == p2.getRank()){
return p1.getName().compareTo(p2.getName());
}else if(p1.getRank() > p2.getRank()){
return 1;
}else{
return -1;
}
}
排序取决于返回的比较结果。您需要返回-1
,0
或1
。在代码片段中,我所做的就是先检查排名。如果它们的排名相同,我会比较它们的名称String
s,每个String
都有一个compareTo( )
,按字典顺序比较两个字符串。
如果没有,我们只是根据排名对它们进行排序。
您可以通过制作compare( )
类实现Person
界面来进一步简化Comparable
方法。这样您就可以开箱即用Collections
框架好东西了。