Android - 自定义GridView适配器 - 位置0处的项目未更新

时间:2016-10-12 08:42:19

标签: android gridview android-arrayadapter

我遇到了一个我自己无法解决的自定义GridView适配器的奇怪问题。

GridView布局
我的网格的每个元素都有4个组件:

  • 一个复选框
  • TextView
  • A Spinner

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;}
}

请帮助。
提前谢谢。

0 个答案:

没有答案
相关问题