读取 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 之间的交互,并更新你的对象的主数组。
示例:
- 假设您有一个 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
}
- 让我们定义一个接口来处理微调器的事件
AdapterSpinnerListener.java
public interface AdapterSpinnerListener {
public void onSpinnerChanged(String spinnerType, String spinnerValue, int position);
//... other events
}
- 为您的 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
}
}
- 在包含 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;
}
//...
//...
}
}
- 现在微调器的值位于 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");
........
........
........
}
我有一个带有卡片和微调器的回收视图,我需要将微调器中选择的值发送到下一个 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 之间的交互,并更新你的对象的主数组。
示例:
- 假设您有一个 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
}
- 让我们定义一个接口来处理微调器的事件
AdapterSpinnerListener.java
public interface AdapterSpinnerListener {
public void onSpinnerChanged(String spinnerType, String spinnerValue, int position);
//... other events
}
- 为您的 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
}
}
- 在包含 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;
}
//...
//...
}
}
- 现在微调器的值位于 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");
........
........
........
}