[英]Multiple Spinner in a Recyclerview item
I have a recycler view with 11-row data items.我有一个包含 11 行数据项的回收站视图。 I need to fix two spinners in each row.我需要在每行修复两个微调器。 That the second spinner data should be dependent on the first Spinner data changes.即第二个 Spinner 数据应该依赖于第一个 Spinner 数据的变化。 While I'm making new entry data loaded correctly.虽然我正在正确加载新的条目数据。 When I came to edit the first spinner data loading correctly done and already existing data was fixed correctly.当我开始编辑第一个微调器数据时,加载正确完成并且已经存在的数据被正确修复。 But in the second spinner, it shows the data of the last loaded item.但是在第二个微调器中,它显示了最后加载的项目的数据。 ie Last row (11th row) spinner data has been set in all the second spinners.即在所有第二个微调器中设置了最后一行(第 11 行)微调器数据。 How to solve this?如何解决这个问题?
Shown below code is under onBindViewHolder() method in recyclerViewAdapter下面显示的代码位于 recyclerViewAdapter 中的 onBindViewHolder() 方法下
fortnightLookupList = gCache.getFortNightLookup();
for(int i = 0; i<fortnightLookupList.size(); i++){
funtioningSpinnerList.add(fortnightLookupList.get(i).getFunctioning());
}
reasoningAdapter =
new ArrayAdapter<>(thisActivity, android.R.layout.simple_spinner_item, funtioningSpinnerList);
reasoningAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
holder.functioningSpinner.setAdapter(reasoningAdapter);
if (entryStatus.equals(Constants.NEW)) {
holder.functioningSpinner.setOnItemSelectedListener(new AdapterView . OnItemSelectedListener () {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if (pos > 0) {
remoteLocationEntryModelData.get(position).checkList =
funtioningSpinnerList.get(pos);
//loadScoreSpinner(funtioningSpinnerList.get(pos), holder, position);
scoreList.clear();
for (int i = 0; i < fortnightLookupList.size(); i++) {
if (fortnightLookupList.get(i).getFunctioning().equals(funtioningSpinnerList.get(pos)) ) {
scoreList.add(fortnightLookupList.get(i).getScore());
}
}
scoreAdapter =
new ArrayAdapter<>(thisActivity, android.R.layout.simple_spinner_item, scoreList);
scoreAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
holder.scoreSpinner.setAdapter(scoreAdapter);
} else {
remoteLocationEntryModelData.get(position).checkList = "$";
scoreList.clear();
scoreList.add(0, "---- select ----");
scoreAdapter =
new ArrayAdapter<>(thisActivity, android.R.layout.simple_spinner_item, scoreList);
scoreAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
holder.scoreSpinner.setAdapter(scoreAdapter);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
} else if (entryStatus.equals(Constants.EDIT)) {
if (!TextUtils.isEmpty( String.valueOf( editList.getDescriptions().get(position).getLogId() ) ) ) {
remoteLocationEntryModelData.get(position).logId =
editList.getDescriptions().get(position).getLogId();
}
if (!TextUtils.isEmpty(editList.getDescriptions().get(position).getRemarks())) {
holder.remarksEdt.setText(editList.getDescriptions().get(position).getRemarks());
}
holder.functioningSpinner.setSelection(
funtioningSpinnerList.indexOf(
editList.getDescriptions().get(position).getCheckList()
)
);
holder.functioningSpinner.setOnItemSelectedListener(new AdapterView . OnItemSelectedListener () {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if (pos > 0) {
remoteLocationEntryModelData.get(position).checkList =
funtioningSpinnerList.get(pos);
//loadScoreSpinner(funtioningSpinnerList.get(pos), holder, position);
scoreList.clear();
for (int i = 0; i < fortnightLookupList.size(); i++) {
if (fortnightLookupList.get(i).getFunctioning()
.equals(funtioningSpinnerList.get(pos))
) {
scoreList.add(fortnightLookupList.get(i).getScore());
}
}
scoreAdapter =
new ArrayAdapter<>(thisActivity, android.R.layout.simple_spinner_item, scoreList);
scoreAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
holder.scoreSpinner.setAdapter(scoreAdapter);
//holder.scoreSpinner.setSelection(scoreList.indexOf(editList.getDescriptions().get(position).getScore()));
} else {
remoteLocationEntryModelData.get(position).checkList = "$";
scoreList.clear();
scoreList.add(0, "---- select ----");
scoreAdapter =
new ArrayAdapter<>(thisActivity, android.R.layout.simple_spinner_item, scoreList);
scoreAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
holder.scoreSpinner.setAdapter(scoreAdapter);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
Note While I debug it step by step it is working correctly, but not when during run注意虽然我逐步调试它,但它工作正常,但在运行期间却没有
Expected Output预计 Output
You save scoreList
in a global variable and never redefines this value您将scoreList
保存在全局变量中,并且从不重新定义此值
In holder.functioningSpinner.setOnItemSelectedListener
you makes scoreList.clear()
在holder.functioningSpinner.setOnItemSelectedListener
你做scoreList.clear()
with always same line you set same List
reference to all adapters in new ArrayAdapter<>(thisActivity, android.R.layout.simple_spinner_item, scoreList)
始终在同一行中为new ArrayAdapter<>(thisActivity, android.R.layout.simple_spinner_item, scoreList)
中的所有适配器设置相同的List
引用
with scoreList.clear()
you removes data in all adapters and adds new values.使用scoreList.clear()
可以删除所有适配器中的数据并添加新值。
=> is the reason, why you see the data of last item in all list items => 是原因,为什么您会在所有列表项中看到最后一项的数据
Note While I debug it step by step it is working correctly, but not when during run注意虽然我逐步调试它,但它工作正常,但在运行期间却没有
Reason for it is:原因是:
HOW TO SOLVE怎么解决
Possibility 1. recreate the list instead of clear data.可能性 1. 重新创建列表而不是清除数据。 You make already always new ArrayAdapter
, why you store scoreList
instance globally?您已经创建了new ArrayAdapter
,为什么要全局存储scoreList
实例?
Possibility 2. Make a holder as own class and everything you do in onBindViewHolder
make in a holder class.可能性 2. 将持有人作为自己的 class 并且您在onBindViewHolder
中所做的一切都在持有人 class 中进行。
Example:例子:
generate base holder class生成底座支架 class
public abstract class BaseRecyclerBindingHolder<Item> extends RecyclerView.ViewHolder {
public BaseRecyclerBindingHolder(View itemView) {
super(itemView);
}
public abstract void configureView(Item item);
}
and base adapter class和基本适配器 class
public abstract class BaseRecyclerBindingAdapter<Item, Holder extends BaseRecyclerBindingHolder<? super Item>, ItemBinding extends ViewBinding>
extends RecyclerView.Adapter<Holder> {
// Store a member variable for the items
protected final List<Item> mItems;
/**
* @param items adapter items to show in UI
*/
public BaseRecyclerBindingAdapter(List<Item> items) {
mItems = items;
}
/**
* Usually involves inflating a layout from XML and returning the holder
*
* @param parent container of adapter items
* @param viewType type of item
* @return ViewHolder for adapter item
*/
@NonNull
@Override
public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// Inflate the custom layout
ItemBinding itemView = getLayoutResource(LayoutInflater.from(parent.getContext()), parent);
return getHolder(itemView, viewType);
}
/**
* Involves populating data into the item through holder
*
* @param holder ViewHolder class to construct UI for item
* @param position item position in adapter
*/
@Override
public void onBindViewHolder(@NonNull Holder holder, int position) {
Item item = mItems.get(position);
holder.configureView(item);
}
/**
* @return count of items in adapter
*/
@Override
public int getItemCount() {
return mItems.size();
}
/**
* gets the type of item of specified position in adapter
*
* @param position item position
* @return default 0
*/
@Override
public abstract int getItemViewType(int position);
/**
* Usually use:
* ItemBinding.inflate(layoutInflater);
* To use parents properties of width and height, make this way:
* ItemBinding.inflate(layoutInflater, parent, false);
*
* @param layoutInflater the inflater to set XMl to view
* @param parent container of adapter items
* @return ViewBinding element with access to all views with IDs in UI
*/
protected abstract ItemBinding getLayoutResource(LayoutInflater layoutInflater, ViewGroup parent);
/**
* based on viewType gets the ViewHolder class for the item
*
* @param viewBinding element with access to all views with IDs in UI
* @param viewType type of item
* @return ViewHolder for adapter item
*/
protected abstract Holder getHolder(ItemBinding viewBinding, int viewType);
/**
* @param position item position
* @return item on specified position in adapter
*/
public Item getItem(int position) {
return mItems.get(position);
}
/**
* @return list of items in adapter
*/
public List<Item> getItems() {
return mItems;
}
}
now generate specific holder for your purpose现在为您的目的生成特定的持有人
public class YourHolderName extends BaseRecyclerBindingHolder<YourHolderItem> {
private final YourHolderBinding binding;
// add here more variable that you needs from adapter
public YourHolderName(YourHolderBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
@Override
public void configureView(YourHolderItem yourHolderItem) {
// here comes what you make i your holder
}
}
and at least define adapter that is always super easy and small并且至少定义总是超级简单和小巧的适配器
public class YourAdapterName extends BaseRecyclerBindingAdapter<YourHolderItem, YourHolderName, YourHolderBinding> {
/**
* @param yourHolderItem adapter items to show in UI
*/
// add more parameters if needed
public YourAdapterName(List<YourHolderItem> yourHolderItems) {
super(yourHolderItems);
}
@Override
public int getItemViewType(int position) {
return 0;
}
@Override
protected YourHolderBinding getLayoutResource(LayoutInflater layoutInflater, ViewGroup parent) {
return YourHolderBinding.inflate(layoutInflater, parent, false);
}
@Override
protected YourHolderName getHolder(YourHolderBinding viewBinding, int viewType) {
// add more parameters if needed
return new YourHolderName(viewBinding);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.