我遇到了一个我自己无法解决的自定义GridView适配器的奇怪问题。
GridView布局
我的网格的每个元素都有4个组件:
GridView适配器
在我的适配器内部,我添加了三个阵列:
CheckBox checkboxesInView[]
存储为网格的每个元素显示的复选框。 boolean checkboxesState[]
存储每个元素复选框的状态,用于在重绘时在元素视图中设置复选框的状态。int productsSelected[]
存储每个微调器的下拉列表中的所选项目。在网格的每个元素的getView()
方法内,我将onClickListener
设置为复选框,将onItemSelectedListener
设置为微调器。
在onClickListener
方法内部,只要单击一个复选框,侦听器就会更改该复选框的状态,并将状态存储在checkboxesState
数组中,这对于网格中的所有元素都可以正常工作0到位置n 。
在onItemSelected
方法内部,只要单击微调器并选择其列表中的项,侦听器就会存储所选项的位置并更改相应复选框的状态,这适用于所有网格的元素除了位置0的那个。
我的问题
位置0处元素的复选框不会使用微调器的侦听器设置的最新状态进行更新。但是,如果元素0被隐藏,然后重新出现在网格内(由于上下滚动),复选框将刷新并显示正确的状态。
代码
以下是我的适配器的完整代码:
import com.company.app.R;
import com.company.app.classes.CustomTypefaceSpan;
import com.company.app.classes.Product;
import com.company.app.utils.DatabaseWastes;
import org.w3c.dom.Text;
import java.util.ArrayList;
public class AdapterProductsGrid extends ArrayAdapter<Product> implements AdapterView.OnItemSelectedListener {
static class ViewHolder {
CheckBox selected;
TextView type;
ImageView icon;
Spinner productOptions;
LinearLayout layoutSpinner;
int position;
}
// declaring ArrayList of Orders
private Typeface dinotTf, dinotTfBold;
private Context context;
private CompoundButton.OnClickListener checkedOnClickListener;
private ArrayList<ArrayAdapter<Product>> spinnerAdapters;
private CheckBox checkboxesInView[];
private boolean checkboxesState[];
private int productsSelected[];
private Product productEmpty;
ArrayList<Product> listProducts;
public AdapterProductsGrid(Context context, int resource, ArrayList<Product> objects) {
super(context, resource, objects);
this.context = context;
this.listProducts = objects;
dinotTf = Typeface.createFromAsset(context.getAssets(), context.getString(R.string.font_dinot));
dinotTfBold = Typeface.createFromAsset(context.getAssets(), context.getString(R.string.font_dinot_Bold));
int size = listProducts.size();
checkboxesState = new boolean[size];
productsSelected = new int[size];
checkboxesInView = new CheckBox[size];
productEmpty = new Product();
productEmpty.setProductId(0);
productEmpty.setName(" - >seleziona<"); // name needs " - " character to be printed correctly
checkedOnClickListener = new CompoundButton.OnClickListener() {
@Override
public void onClick(View buttonView) {
checkboxListener(buttonView);
}
};
//init adapters for spinners
spinnerAdapters = new ArrayList<>();
DatabaseWastes db = DatabaseWastes.getInstance(context);
for (Product p : listProducts) {
// get all products
ArrayList<Product> productsNames = db.getProducts(p.getCategory(), p.getType());
if (productsNames.get(0).getName().contains("-")) {
productsNames.add(0, productEmpty);
}
ArrayAdapter<Product> adapter = new ArrayAdapter<>(context, android.R.layout.simple_spinner_item, productsNames);
adapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item);
spinnerAdapters.add(adapter);
}
}
@Override
public
@NonNull
View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
ViewHolder viewHolder;
GridView gridView = (GridView) parent;
int firstVisiblePosition = gridView.getFirstVisiblePosition();
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.grid_product_element, parent, false);
//Log.e("ADAPTER", "NEW view for POSITION " + position);
viewHolder = new ViewHolder();
viewHolder.selected = (CheckBox) convertView.findViewById(R.id.checkbox_product_selected);
viewHolder.icon = (ImageView) convertView.findViewById(R.id.image_product);
viewHolder.type = (TextView) convertView.findViewById(R.id.text_product_type);
viewHolder.layoutSpinner = (LinearLayout) convertView.findViewById(R.id.layout_spinner_product_options);
viewHolder.productOptions = (Spinner) convertView.findViewById(R.id.spinner_product_options);
convertView.setTag(viewHolder);
} else {
Log.e("ADAPTER", "RECYCLING view for POSITION " + position);
viewHolder = (ViewHolder) convertView.getTag();
}
Product product = listProducts.get(position);
if (product != null) {
checkboxesInView[position] = viewHolder.selected;
viewHolder.selected.setChecked(checkboxesState[position]);
viewHolder.selected.setTag(position);
viewHolder.selected.setOnClickListener(checkedOnClickListener);
viewHolder.type.setTypeface(dinotTfBold, Typeface.BOLD);
viewHolder.type.setText(product.getType());
//TODO: get rid of this
//viewHolder.type.setText(Integer.toString(position));
if (product.getCategory().equalsIgnoreCase("ufficio")) {
// for products of category "Ufficio"
viewHolder.type.setBackgroundColor(context.getResources().getColor(R.color.colorButtonBlue));
viewHolder.layoutSpinner.setVisibility(View.GONE);
} else {
// for products of other categories
viewHolder.type.setBackgroundColor(context.getResources().getColor(R.color.colorButtonGreen));
viewHolder.layoutSpinner.setVisibility(View.VISIBLE);
viewHolder.productOptions.setTag(position);
if (listProducts.get(position).getName().contains("-")) {
// for products with several quantity options (1/5kg, 6/10kg, ...)
viewHolder.layoutSpinner.setBackgroundColor(context.getResources().getColor(R.color.colorGridCellGray));
viewHolder.productOptions.setVisibility(View.VISIBLE);
viewHolder.productOptions.setAdapter(spinnerAdapters.get(position));
viewHolder.productOptions.setOnItemSelectedListener(this);
viewHolder.productOptions.setSelection(productsSelected[position]);
} else {
viewHolder.layoutSpinner.setBackgroundColor(context.getResources().getColor(R.color.colorGrid));
viewHolder.productOptions.setVisibility(View.GONE);
}
}
} else {
//Log.d("ADAPTER", "product null");
}
return convertView;
}
private void checkboxListener(View buttonView) {
CheckBox checkbox = (CheckBox) buttonView;
checkboxesState[(Integer) checkbox.getTag()] = checkbox.isChecked();
Log.d("ADAPTER GRID CHECKBOX", "checkbox " + (Integer) checkbox.getTag() + " is checked " + checkbox.isChecked());
}
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
// store index of product selected
int index = (Integer) parent.getTag();
productsSelected[index] = pos; // store the selected product
checkboxesState[index] = (pos != 0); // set state of checkbox
checkboxesInView[index].setChecked(checkboxesState[index]); // show state to user
Log.d("ADAPTER GRID SELECTION", "parentId " + index + ", position " + pos + ", checkbox id " + (Integer) checkboxesInView[index].getTag() + " is " + checkboxesInView[index].isChecked());
}
/**
* @param parent
*/
public void onNothingSelected(AdapterView<?> parent) {
// another interface callback
Log.d("ADAPTER GRID", "onNothingSelected called");
}
public boolean[] getCheckboxesState() { return checkboxesState;}
public int[] getProductsSelected(){return productsSelected;}
public ArrayList<ArrayAdapter<Product>> getSpinnerAdapters() {return spinnerAdapters;}
}
请帮助。
提前谢谢。