Number picker in custom listview changing number by itself

瘦欲@ 提交于 2019-12-23 07:10:02

问题


I am working on app in which I am using a Custom ArrayAdaptor to populate my listView.The customoized row includes a number Picker along with some text boxes in its activity. Now the Problem Part--> The funny part is that when i am changing the number of number picker in a particular row other number pickers of other rows get changed automatically.I have been staring at my code almost 2 days now .Please help

Custom_row.java

public class Custom_row extends ArrayAdapter {

static Button ProPay;
Context context;
int newValcount=0;

public Custom_row(Context context, int resourceId,
                  List<DataItem> items) {
    super(context, resourceId, items);
    this.context = context;
}
private class ViewHolder {
    TextView Items,Cost;
    NumberPicker number;


}
public View getView(int position, View convertView, ViewGroup parent) {

    ViewHolder holder = null;
    DataItem dataItem = getItem(position);
    LayoutInflater mInflater = (LayoutInflater) context
            .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.activity_custom_row, null);
        holder = new ViewHolder();
        holder.Items = (TextView) convertView.findViewById(R.id.tvItem);
        holder.Cost = (TextView) convertView.findViewById(R.id.tvCost);
        holder.number=(NumberPicker)convertView.findViewById(R.id.numberPicker);
        holder.number.setMaxValue(10);
        holder.number.setMinValue(0);
        holder.number.setValue(0);
        holder.number.setFocusable(false);
        ItemList.picker = holder.number;
        holder.number.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
            @Override
            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {

                if(newVal!=0){
                    newValcount++;
                    if(newValcount > 0)
                        ProPay.setVisibility(View.VISIBLE);
                }
                else{
                    newValcount--;
                    if(newValcount==0)
                        ProPay.setVisibility(View.INVISIBLE);

                }
            }
        });
        convertView.setTag(holder);
    }
    else{
        holder = (ViewHolder) convertView.getTag();
    }
    holder.Items.setText(dataItem.getItem());
    holder.Cost.setText(dataItem.getCost());
    return convertView;
}

}

ItemList.java `public class ItemList extends Activity { public ListView listView; public static List dataItems; Button PayPro; static NumberPicker picker;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_item_list);
    listView = (ListView)findViewById(R.id.itemList);
    Custom_row.ProPay=(Button)findViewById(R.id.bProPay);
    Custom_row adapter = new Custom_row(this,
            R.layout.activity_custom_row, dataItems);
    listView.setAdapter(adapter);
}
}

`


回答1:


You need to set your listener everytime so you are not reusing the same listener on multiple rows.

Also newValCount seems to be shared amoungst all number pickers - so if it changes for one it'll change for them all.

public View getView(int position, View convertView, ViewGroup parent) {   
    ViewHolder holder = null;
    DataItem dataItem = getItem(position);
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.activity_custom_row, null);
        holder = new ViewHolder();
        holder.Items = (TextView) convertView.findViewById(R.id.tvItem);
        holder.Cost = (TextView) convertView.findViewById(R.id.tvCost);
        holder.number =(NumberPicker)convertView.findViewById(R.id.numberPicker);
        holder.number.setMaxValue(10);
        holder.number.setMinValue(0);    
        holder.number.setFocusable(false);
        ItemList.picker = holder.number;

        convertView.setTag(holder);
    }
    else{
        holder = (ViewHolder) convertView.getTag();
    }
    holder.Items.setText(dataItem.getItem());
    holder.Cost.setText(dataItem.getCost());
    holder.number.setValue(0);
    holder.number.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
            @Override
            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {

                if(newVal!=0){
                    newValcount++; // THIS IS SHARED AMOUNGST ALL NUMBER PICKERS
                    if(newValcount > 0)
                        ProPay.setVisibility(View.VISIBLE);
                }
                else{
                    newValcount--;
                    if(newValcount==0)
                        ProPay.setVisibility(View.INVISIBLE);

                }
            }
        });
    return convertView;
}

inside if (convertView == null) you should only be creating references to views. Not adding a value change listener. (This needs to be done for every item every time, not recycled.


Separately don't do this LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); inside your getView it's bad for performance to get it everytime


Also static Button ProPay; will lead to a memory leak, as a Button is a View a View has Context and the Context is your Activity making it static means you will hold a reference to an Activity even after that Activity is no longer on the screen i.e. memory leak




回答2:


Custom_row.java :

holder.numberPicker.setOnValueChangedListener(new                               NumberPicker.OnValueChangeListener() {
        @Override
        public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
            View parentRow = (View)picker.getParent();
            ListView mListView =(ListView)parentRow.getParent();
            final int position = mListView.getPositionForView(parentRow);
            setPickerNumber(position,newVal);
            if(newVal > oldVal){
                newValcount = newValcount + newVal - oldVal;

            }
            if(oldVal > newVal){
                newValcount = newValcount + newVal - oldVal;
            }
            if(newValcount>0)
            {
                ProPay.setVisibility(View.VISIBLE);
            }
            else{
                ProPay.setVisibility(View.INVISIBLE);
            }
        }
    });


来源:https://stackoverflow.com/questions/33843389/number-picker-in-custom-listview-changing-number-by-itself

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!