【问题标题】:Android - How to get the original item position after search filter in Android's Recycle ViewAndroid - 如何在 Android Recyclerview 中的搜索过滤器后获取原始项目位置
【发布时间】:2021-03-23 07:47:55
【问题描述】:

我正在使用 Java 开发一个移动应用程序。我的活动页面中有一个 EditText,它将搜索和过滤项目。这些项目使用适配器和视图支架列出。但是,当我从搜索结果中单击该项目时,该项目的位置会发生变化。即使在搜索过滤器之后,有没有办法获得原始位置?

这是我为活动课准备的内容

private ArrayList<BuildingItem> buildingList = new ArrayList<>(); 
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.building_selector);

    //initialize database
    db = new DatabaseHelper(this);

    buildings = db.getBuildingData();

    //populate buildingList with all database entries as BuildingItem objects
    for(ArrayList building : buildings) {
        String name = building.get(1).toString();
        String altName = building.get(3).toString();
        String dept = building.get(4).toString();
        BuildingItem bi = new BuildingItem(Integer.parseInt(building.get(2).toString()), name, altName, dept);
        buildingList.add(bi);
    }

    mRecyclerView = findViewById(R.id.recyclerView);
    mLayoutManager = new LinearLayoutManager(this);
    mAdapter = new BuildingAdapter(buildingList);

    mRecyclerView.setLayoutManager(mLayoutManager);
    mRecyclerView.setAdapter(mAdapter);
    mAdapter.setOnItemClickListener(new BuildingAdapter.OnItemClickListener(){
        @Override
        public void onItemClick(int position){
            //changeItem(position, "Clicked");
            passBuildings(position);
            //change color
            //TextView clicked = findViewById(R.id.textView2);
            //clicked.setTextColor(Color.parseColor("#FF0000"));
        }
    });
    //end of old buildingselector

    //  search feature
    buildingSearch = (EditText) findViewById(R.id.editTextSearch);
    buildingSearch.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void afterTextChanged(Editable editable) {
            filter(editable.toString());
        }
    });
}
private void filter(String text)
    {
        ArrayList<BuildingItem> filterNames = new ArrayList<>();

        //looping through existing elements
        for(BuildingItem b: buildingList)
        {
            String buildingName = b.getBuilding();
            if(buildingName.toLowerCase().contains(text.toLowerCase()))
                filterNames.add(b);
        }
        mAdapter.filterList(filterNames);
    }

我需要在活动页面中使用passBuildings函数中的位置,这需要item的原始位置值才能返回正确的Bui​​ldingItem

 public void passBuildings(int position){
        buildingsToPass.add(buildingList.get(position).getBuilding());
        if(buildingsToPass.size() == 1){
            changeItem(position, "Starting Point");
            TextView title = findViewById(R.id.SelectTitle);
            title.setText("Select a Destination Building");
            buildingSearch.getText().clear();
        }
        if(buildingsToPass.size()==2){
            changeItem(position, "Destination");

            // go to map page
            Intent launchActivity = new Intent(BuildingActivity.this, MapsActivity.class);
            launchActivity.putExtra("places", buildingsToPass);
            startActivity(launchActivity);
        }
    }   

这是我的适配器

public static class BuildingViewHolder extends RecyclerView.ViewHolder{
        public ImageView buildingImage;
        public TextView buildingName;
        public TextView buildingAltName;
        public TextView buildingDept;

    public BuildingViewHolder(View itemView, OnItemClickListener listener){
        super(itemView);
        buildingImage = itemView.findViewById(R.id.buildingImage);
        buildingName = itemView.findViewById(R.id.buildingName);
        buildingAltName = itemView.findViewById(R.id.buildingAltName);
        buildingDept = itemView.findViewById(R.id.buildingDept);

        itemView.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                if (listener != null){
                    int position = getAdapterPosition();
                    if (position != RecyclerView.NO_POSITION){
                        listener.onItemClick(position);
                    }
                }
            }
        });

    }
}
public void filterList(ArrayList<BuildingItem> building)
    {
        this.buildingList = building;
        this.notifyDataSetChanged();
    } 
public BuildingAdapter(ArrayList<BuildingItem> buildings){
        buildingList = buildings;
    }

    @Override
    public BuildingViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.building_item, parent, false);
        BuildingViewHolder evh = new BuildingViewHolder(v, mListener);
        return evh;
    }

    @Override
    public void onBindViewHolder(BuildingViewHolder holder, int position){
        BuildingItem currentItem = filteredBuildingList.get(position);

        holder.buildingImage.setImageResource(currentItem.getImageResource());
        holder.buildingName.setText(currentItem.getBuilding());
        holder.buildingAltName.setText(currentItem.getAltName());
        holder.buildingDept.setText(currentItem.getDept());
    }

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

【问题讨论】:

  • 请分享适配器
  • @Zain 我已经更新了适配器的完整代码
  • 据我了解,您需要一个位置来从列表中获取项目。您可以通过在列表中搜索或保留职位来做到这一点。但在我看来,最好的方法是创建一个接受 BuildingItem 作为参数的点击侦听器。可以直接访问activity中点击的BuildingItem。
  • 我刚刚更新了答案,看看吧

标签: android android-activity android-recyclerview filter android-adapter


【解决方案1】:

您可以将整个对象传递给整个对象,而不是将适配器中的position 传递回活动,因此将onItemClick 的参数更改为接受BuildingItem 而不是int

现在,当您单击一个项目(应用过滤器后)时,该项目将传递回活动,以获取位置使用buildingList.get(item)

mAdapter.setOnItemClickListener(new BuildingAdapter.OnItemClickListener(){
    @Override
    public void onItemClick(BuildingItem item){
         
       int position = buildingList.indexOf(item); // here is the position you need

       // rest of your code..........

    }
});

【讨论】:

    猜你喜欢
    • 2017-01-28
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    • 2019-02-26
    • 1970-01-01
    • 2020-09-18
    • 1970-01-01
    • 2017-04-06
    相关资源
    最近更新 更多