3

我正在尝试创建实现多个过滤器以在 Recyclerview 中搜索数据。

例如,在购物清单中,我可以将过滤器放在符合以下条件的计算机上。

品牌 = 苹果,屏幕尺寸 = 10 到 13 英寸,硬盘尺寸 = 250 到 500

现在,我的飞机 ViewModel 将在模型类 ResponseBase 中包含具有所有这些标准的计算机列表,这是我从后端获取的。

class ItemViewModel : ViewModel() {

var mResponse : MutableLiveData<ResponseBase>? = null

fun getData() : MutableLiveData<ResponseBase> {
    if(null == mResponse) {
       mResponse = NetworkProcessor().loadSearchData()
    }
    return mResponse as MutableLiveData<ResponseBase>
  }
}

响应库.kt

data class ResponseBase(
    val matches: List<ComputersData>
)

计算机数据.kt

data class ComputersData(
    val brand: String,
    val screenSize: Int,
    val hardDisk: Int,
    val processor: String,
    val display_name: String,
    val ram: Int,
)

现在根据Android Sunflower示例, RecyclerView 可以具有DiffUtil,可用于高效过滤。

但是如何使用RecyclerView 适配器中的DiffUtil根据这样的条件过滤 ComputersData?

品牌 = 苹果 && screenSize = 10 到 13 ,硬盘 = 250 到 500

任何想法将不胜感激!

4

1 回答 1

2

主要活动

public class MainActivity extends AppCompatActivity {

private RecyclerView mRecyclerView;
private EmployeeRecyclerViewAdapter mRecyclerViewAdapter;
private List<Employee> employeeList;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    employeeList = DummyEmployeeDataUtils.getEmployeeList();
    mRecyclerViewAdapter = new EmployeeRecyclerViewAdapter(
            employeeList);
    mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    mRecyclerView.setAdapter(mRecyclerViewAdapter);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.sort_menu, menu);
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.age_above_employees:        
    mRecyclerViewAdapter.updateEmployeeListItems(DummyEmployeeDataUtils.getEmployessWithAgeAbove50());
            return true;
    }
    return super.onOptionsItemSelected(item);
   }
 }

根据年龄创建虚拟员工列表

public class DummyEmployeeDataUtils {

public static List<Employee> getEmployessWithAgeAbove50() {
    final List<Employee> employeeList = getEmployeeList();
    final List<Employee> filteredEmployees = new ArrayList<>();
    for (int i = 0; i < employeeList.size(); i++) {
        if (employeeList.get(i).getAge() > 50)
            filteredEmployees.add(employeeList.get(i));
    }
    return filteredEmployees;
}

public static List<Employee> getEmployeeList() {
    final List<Employee> employees = new ArrayList<>();

    employees.add(new Employee(1, "Employee 1", "Developer", 12));
    employees.add(new Employee(2, "Employee 2", "Tester", 52));
    employees.add(new Employee(3, "Employee 3", "Support", 72));
    employees.add(new Employee(4, "Employee 4", "Sales Manager", 11));
    employees.add(new Employee(5, "Employee 5", "Manager", 64));
    employees.add(new Employee(6, "Employee 6", "Team lead", 99));
    employees.add(new Employee(7, "Employee 7", "Scrum Master", 89));
    employees.add(new Employee(8, "Employee 8", "Sr. Tester", 23));
    employees.add(new Employee(9, "Employee 9", "Sr. Developer", 21));
    return employees;
  }
}

这是我们的适配器

public class EmployeeRecyclerViewAdapter extends
    RecyclerView.Adapter<EmployeeRecyclerViewAdapter
            .ViewHolder> {

private List<Employee> mEmployees = new ArrayList<>();

public EmployeeRecyclerViewAdapter(List<Employee> employeeList) {
    this.mEmployees.addAll(employeeList);
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    final View view = inflater.inflate(R.layout.list_item, parent, false);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    final Employee employee = mEmployees.get(position);
    holder.bindView(employee);
}

public void updateEmployeeListItems(List<Employee> employees) {
    final EmployeeDiffCallback diffCallback = new EmployeeDiffCallback(this.mEmployees, employees);
    final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallback);
    this.mEmployees.clear();
    this.mEmployees.addAll(employees);
    diffResult.dispatchUpdatesTo(this);
}

@Override
public int getItemCount() {
    return mEmployees.size();
}

public static class ViewHolder extends RecyclerView.ViewHolder {

    private final TextView role;
    private final TextView name;
    private final TextView age;

    public ViewHolder(View itemView) {
        super(itemView);
        name = (TextView) itemView.findViewById(R.id.employee_name);
        role = (TextView) itemView.findViewById(R.id.employee_role);
        age = (TextView) itemView.findViewById(R.id.employee_age);
    }

    void bindView(Employee employee) {
        name.setText(employee.getName());
        role.setText(employee.getRole());
        age.setText("Age ".concat(employee.getAge()+""));
    }
  }
}

这是 DiffUtil 适配器

public class EmployeeDiffCallback extends DiffUtil.Callback {

private final List<Employee> mOldEmployeeList;
private final List<Employee> mNewEmployeeList;

public EmployeeDiffCallback(List<Employee> oldEmployeeList, List<Employee> newEmployeeList) {
    this.mOldEmployeeList = oldEmployeeList;
    this.mNewEmployeeList = newEmployeeList;
}

@Override
public int getOldListSize() {
    return mOldEmployeeList.size();
}

@Override
public int getNewListSize() {
    return mNewEmployeeList.size();
}

@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
    return mOldEmployeeList.get(oldItemPosition).getId() == mNewEmployeeList.get(
            newItemPosition).getId();
}

@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
    final Employee oldEmployee = mOldEmployeeList.get(oldItemPosition);
    final Employee newEmployee = mNewEmployeeList.get(newItemPosition);

    return oldEmployee.getName().equals(newEmployee.getName());
}

@Nullable
@Override
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
    // Implement method if you're going to use ItemAnimator
    return super.getChangePayload(oldItemPosition, newItemPosition);
   }
}

更新的答案

编辑 Manoj 的答案。由作者更新以供将来参考

在没有 ViewModels 的 RecyclerView 的情况下,上述答案可以正常工作。一旦 viewmodel 出现并且 RecyclerView 监听 VM 中的变化,逻辑应该是用 ViewModel 本身的新结果更新过滤列表。这样回收站视图就会一直监听更新并保持数据更新。

在这种情况下,Diff Utils可能不会派上用场。相当有效的方法(因为问题在 Kotlin 中)是使用过滤器

我发现过滤器比 Diff Util 实现简单得多。

为了将来参考,具有多个谓词的示例过滤方法如下

mViewModelObject 是 View Model 对象的实例

val valueOne =  mViewModelObject.criteriaOne.value
val valueTwo =  mViewModelObject.criteriaTwo.value

 val newList  = originalList.filter {
                    it.listVariableABC == valueOne 
                    &&
                    it.listVariablePQR == valueTwo
}

根据多个条件创建新列表后,在 ViewModel 中更新相同的列表。这样 Recycler View 将获得更新的列表。

于 2019-07-09T06:58:30.253 回答