读取 recyclerview 适配器 activity 中的数据

Read data in activity of recyclerview adapter

我有一个带有卡片和微调器的回收视图,我需要将微调器中选择的值发送到下一个 activity 以计算估计价格。我在 activity 中有一个按钮,它不属于 recyclerview,它会将我带到下一个 activity 我需要这些值的地方。因此,当我单击此按钮时,我需要它来收集数据并将其发送到下一个 activity,我该如何实现。

我附上了图片。红色箭头(我需要在下一个 activity 中的数据),蓝色箭头(按下按钮将我带到下一个 activity)

Screenshot of screen

我正在使用此方法读取值

findMerchantTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                for (int i = 0; i < totalCards; i++) {
                    Spinner printColorSpinner = mRecyclerView.findViewHolderForLayoutPosition(i).itemView.findViewById(R.id.printColorSpinner);
                    Spinner printSidesSpinner = mRecyclerView.findViewHolderForAdapterPosition(i).itemView.findViewById(R.id.printSidesSpinner);
                    Spinner printSizeSpinner = mRecyclerView.findViewHolderForAdapterPosition(i).itemView.findViewById(R.id.paperSizeSpinner);
                    Spinner pagesSpinner = mRecyclerView.findViewHolderForAdapterPosition(i).itemView.findViewById(R.id.pagesSpinner);
                    Spinner orientationSpinner = mRecyclerView.findViewHolderForAdapterPosition(i).itemView.findViewById(R.id.orientationSpinner);
                    Spinner bindingTypeSpinner = mRecyclerView.findViewHolderForAdapterPosition(i).itemView.findViewById(R.id.bindingTypeSpinner);
                    MaterialTextView copiesTextView = mRecyclerView.findViewHolderForAdapterPosition(i).itemView.findViewById(R.id.copiesNumberText);
                    String color = printColorSpinner.getSelectedItem().toString().trim();
                    String sides = printSidesSpinner.getSelectedItem().toString().trim();
                    String size = printSizeSpinner.getSelectedItem().toString().trim();
                    String pages = pagesSpinner.getSelectedItem().toString().trim();
                    String orientation = orientationSpinner.getSelectedItem().toString().trim();
                    String bindingType = bindingTypeSpinner.getSelectedItem().toString().trim();
                    String totalCopies = copiesTextView.getText().toString().trim();
                }
            }
        });

但是当i变为2时,findViewHolderForLayoutPosition returnsNullPointerException。我搜索并了解到视图是可回收的,并且只有布局在屏幕上的视图才是可读的。

获得这些值的替代方法是什么?谢谢!

RecyclerView 重用视图以提高性能和内存消耗,您只能访问可见视图。实现你的目标的一种方法是使用一个接口来实现包含 RecyclerView 和适配器的 Activity 之间的交互,并更新你的对象的主数组。

示例:

  1. 假设您有一个 Class 来定义您的数据。

YourClass.java

public class YourClass extends Object implements Parcelable {

  public String color = "";
  public String sides = "";
  public String size = "";
  public String pages = "";
  public String orientation = "";
  public String bindingType = "";
  public String totalCopies = "";

  //... your methods and implementations
}
  1. 让我们定义一个接口来处理微调器的事件

AdapterSpinnerListener.java

public interface AdapterSpinnerListener {
    public void onSpinnerChanged(String spinnerType, String spinnerValue,  int position);

    //... other events
}
  1. 为您的 RecyclerView 实施自定义适配器

CustomAdapter.java

public class CustomAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private AdapterActionListener adapterActionListener;

    // Your constructor receive the Fragment of Activity which implements the AdapterSpinnerListener.
    // Also receive the array of objects to populate the RecyclerView
    public CustomAdapter(YourActivity activity, ArrayList<YourClass> customRows)
    {
      this.adapterActionListener = activity;
    }

    //... implements all the needed functions for the RecyclerView
    //getItemId
    //getItemCount
    //getItemViewType
    //onCreateViewHolder

    //In your onBindViewHolder, you should add a listener for each one of your spinners. 
    //Also I'm supossing you have a CustomViewHolder to reference the Layout and Spinners.

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
      CustomViewHolder holder = (CustomViewHolder)viewHolder;
      holder.textViewSomething.setText(...);

      holder.printColorSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
          @Override
          public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
              if (adapterActionListener != null) {
                  // You can retrieve the selected item using parent.getItemAtPosition(pos)
                  adapterActionListener.onSpinnerChanged("color", selectedValue,  position);
              }
          }

          @Override
          public void onNothingSelected(AdapterView<?> adapterView) {

          }
      });

      //holder.printSidesSpinner.setOnItemSelectedListener...
      //...
      //...
      //... You should implement a listener for each spinner
    }
}
  1. 在包含 RecyclerView 的 Activity 或 Fragment 中,您应该实现接口并定义对象数组并使用数据填充适配器。

YourActivity.java

public class YourActivity extends AppCompatActivity implements AdapterSpinnerListener {
    private RecyclerView recyclerView;
    private CustomAdapter customAdapter;
    private ArrayList<YourClass> customRows;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_activity);

        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        customAdapter = new CustomAdapter(this, customRows);
        recyclerView.setAdapter(customAdapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(this.getActivity()));
    }

  // Implements the method of the interface
  @Override
  public void onSpinnerChanged(String spinnerType, String spinnerValue,  int position) {
    if (spinnerType.equals("color")) {
      customRows.get(position).color = spinnerValue;
    } else if (spinnerType.equals("sides")) {
      customRows.get(position).sides = spinnerValue;
    }
    //...
    //...
  }
}
  1. 现在微调器的值位于 customRows 数组中。您可以在点击事件中检索值
findMerchantTextView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            for (int i = 0; i < customRows.size(); i++) {
                String color = customRows.get(i).color;
                String sides = customRows.get(i).sides;
                //...
                //...
                //... all the values you want to get for the next activity
                //... 
            }
        }
    });

假设每个微调器选择一个项目:

在您的 RecyclerView 的 adapter 中:

class MyAdapter extends ...........{

//have these as member fields
public String color = "default";
public String sides = "default";
public String size = "default";
public String pages = "default";
public String orientation = "default";
public String bindingType = "default";
public String totalCopies = "default";
.......
.......


//when you interact with the spinners in onBindViewHolder

@Override
public void onBindViewHolder(........){

//on selecting color spinner item

holder.colorSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {

      //set the color here  
      color = 
    }

    @Override
    public void onNothingSelected(AdapterView<?> parentView) {

    }

});


//on selecting sides spinner item

holder.sidesSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {

      //set the sides here  
      sides = 
    }

    @Override
    public void onNothingSelected(AdapterView<?> parentView) {

    }

});

// you get the idea, do the rest here..........

}






}

在activity中包含要点击发送数据的Button:

class YourActivity extends .........{




//lets say you initialized the adapter like this

MyAdapter adapter = new MyAdapter(.....);

//when you click the button:


findMerchantTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

Intent intent = new Intent(YourActivity.this , TheOtherActivityName.class);
intent.putExtra("color" , adapter.color);
intent.putExtra("sides" , adapter.sides);
intent.putExtra("size" , adapter.size);
intent.putExtra("pages" , adapter.pages);
intent.putExtra("orientation" , adapter.orientation);
intent.putExtra("bindingType" , adapter.bindingType);
intent.putExtra("totalCopies" , adapter.totalCopies);
startActivity(intent);

}

});




}

在activity中表示要读取按钮传递过来的数据:

class TheOtherActivityName extends .....{

//in onCreate()


String color = getIntent.getStringExtra("color");
String sides = getIntent.getStringExtra("sides");
String size = getIntent.getStringExtra("size");
........
........
........


}