在 RecyclerView 中获取微调器选择的项目
Get spinner selected item inside RecyclerView
我在 RecyclerView
中添加了 Spinner
,当我试图获取旋转器选择的项目数据时,它获得 another/wrong 位置数据,有人建议我获得正确的选择项目位置来自 Spinner
onItemSelected
这是我的代码
@Override
public void onBindViewHolder(final QuestionHolder holder, final int position) {
if (position % 2 == 1)
holder.itemView.setBackgroundColor(Color.parseColor("#F8F8F8"));
adapter = new ArrayAdapter<Option>(binding.getRoot().getContext(),
R.layout.item_spinner, questionList.get(position).getOptions());
adapter.setDropDownViewResource(R.layout.item_spinner);
binding.optionSpinner.setAdapter(adapter);
binding.serialNo.setText((position + 1) + ".");
binding.setQuestion(questionList.get(position));
binding.executePendingBindings();
binding.optionSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(holder.itemView.getContext(), position+" : "+binding.optionSpinner.getSelectedItem().toString(), Toast.LENGTH_SHORT).show();
spinnerData.setSelectedData(position, binding.optionSpinner.getSelectedItem().toString());
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
我想你必须试试这个
showSpinnerList.setOnItemSelectedListener(new
AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int
position, long id) {
// On selecting a spinner item
String item = parent.getItemAtPosition(position).toString();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// todo for nothing selected
}
});
检查这个,可能会有所帮助并可能解决您的问题。如果这不能解决您的问题,至少您可以摆脱 Lint 错误。 Lint error “Do not treat position as fixed; only use immediately…”。所以无论你在哪里使用 final int position**
将其更改为 getAdapterPosition()
;
The documentation of RecyclerView.Adapter.onBindViewHolder()
states:
Note that unlike ListView, RecyclerView will not call this method
again if the position of the item changes in the data set unless the
item itself is invalidated or the new position cannot be determined.
For this reason, you should only use the position parameter while
acquiring the related data item inside this method and should not keep
a copy of it. If you need the position of an item later on (e.g. in a
click listener), use getAdapterPosition() which will have the updated
adapter position
So, technically items may be re-arranged and binding will not be
necessary because items are not invalidated yet. The position
variable received holds true only for the scope of bind function and
will not always point to correct position in the data set. That's why
the function getAdapterPosition()
must be called everytime updated
position is needed.
IMHO, mLastPosition = holder.getAdapterPosition();
is still
potentially wrong. Because item may be re-arranged and mLastPosition
still points to old position.
About why lint is silent, perhaps Lint rule is not that thorough. Its
only checking whether position
parameter is being copied or not.
我在 RecyclerView
中添加了 Spinner
,当我试图获取旋转器选择的项目数据时,它获得 another/wrong 位置数据,有人建议我获得正确的选择项目位置来自 Spinner
onItemSelected
这是我的代码
@Override
public void onBindViewHolder(final QuestionHolder holder, final int position) {
if (position % 2 == 1)
holder.itemView.setBackgroundColor(Color.parseColor("#F8F8F8"));
adapter = new ArrayAdapter<Option>(binding.getRoot().getContext(),
R.layout.item_spinner, questionList.get(position).getOptions());
adapter.setDropDownViewResource(R.layout.item_spinner);
binding.optionSpinner.setAdapter(adapter);
binding.serialNo.setText((position + 1) + ".");
binding.setQuestion(questionList.get(position));
binding.executePendingBindings();
binding.optionSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(holder.itemView.getContext(), position+" : "+binding.optionSpinner.getSelectedItem().toString(), Toast.LENGTH_SHORT).show();
spinnerData.setSelectedData(position, binding.optionSpinner.getSelectedItem().toString());
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
我想你必须试试这个
showSpinnerList.setOnItemSelectedListener(new
AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int
position, long id) {
// On selecting a spinner item
String item = parent.getItemAtPosition(position).toString();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// todo for nothing selected
}
});
检查这个,可能会有所帮助并可能解决您的问题。如果这不能解决您的问题,至少您可以摆脱 Lint 错误。 Lint error “Do not treat position as fixed; only use immediately…”。所以无论你在哪里使用 final int position**
将其更改为 getAdapterPosition()
;
The documentation of RecyclerView.Adapter.onBindViewHolder() states:
Note that unlike ListView, RecyclerView will not call this method again if the position of the item changes in the data set unless the item itself is invalidated or the new position cannot be determined. For this reason, you should only use the position parameter while acquiring the related data item inside this method and should not keep a copy of it. If you need the position of an item later on (e.g. in a click listener), use getAdapterPosition() which will have the updated adapter position
So, technically items may be re-arranged and binding will not be necessary because items are not invalidated yet. The
position
variable received holds true only for the scope of bind function and will not always point to correct position in the data set. That's why the functiongetAdapterPosition()
must be called everytime updated position is needed.IMHO,
mLastPosition = holder.getAdapterPosition();
is still potentially wrong. Because item may be re-arranged andmLastPosition
still points to old position.About why lint is silent, perhaps Lint rule is not that thorough. Its only checking whether
position
parameter is being copied or not.