自定义列表视图中的数字选择器自行更改数字
Number picker in custom listview changing number by itself
我正在开发一个应用程序,我在其中使用自定义 ArrayAdaptor 来填充我的 listView.The 自定义行,其中包括一个数字选择器以及 activity 中的一些文本框。
现在是问题部分-->
有趣的是,当我更改特定行中的数字选择器的数量时,其他行的其他数字选择器也会发生变化 automatically.I 已经盯着我的代码看了将近 2 天了。请帮忙
Custom_row.java
public class Custom_row 扩展 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 扩展 Activity {
public 列表视图列表视图;
public静态列表数据项;
按钮支付宝;
静态 NumberPicker 选择器;
@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);
}
}
`
您需要每次都设置您的侦听器,这样您就不会在多行上重复使用同一个侦听器。
而且 newValCount
似乎在所有号码选择器中都是共享的 - 所以如果它改变了一个,那么所有的选择器都会改变。
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;
}
在 if (convertView == null)
中,您应该只创建对视图的引用。不添加值更改侦听器。 (每件物品每次都需要做这个,不能回收。
另外不要在你的 getView
中执行此操作 LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
每次都获取它对性能不利
另外 static Button ProPay;
会导致内存泄漏,因为 Button
是 View
一个 View
有 Context
而 Context
是你的 Activity
使其静态意味着你将保留对 Activity
的引用,即使在那之后 Activity
不再出现在屏幕上,即内存泄漏
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);
}
}
});
我正在开发一个应用程序,我在其中使用自定义 ArrayAdaptor 来填充我的 listView.The 自定义行,其中包括一个数字选择器以及 activity 中的一些文本框。 现在是问题部分--> 有趣的是,当我更改特定行中的数字选择器的数量时,其他行的其他数字选择器也会发生变化 automatically.I 已经盯着我的代码看了将近 2 天了。请帮忙
Custom_row.java
public class Custom_row 扩展 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 扩展 Activity { public 列表视图列表视图; public静态列表数据项; 按钮支付宝; 静态 NumberPicker 选择器;
@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);
}
}
`
您需要每次都设置您的侦听器,这样您就不会在多行上重复使用同一个侦听器。
而且 newValCount
似乎在所有号码选择器中都是共享的 - 所以如果它改变了一个,那么所有的选择器都会改变。
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;
}
在 if (convertView == null)
中,您应该只创建对视图的引用。不添加值更改侦听器。 (每件物品每次都需要做这个,不能回收。
另外不要在你的 getView
中执行此操作 LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
每次都获取它对性能不利
另外 static Button ProPay;
会导致内存泄漏,因为 Button
是 View
一个 View
有 Context
而 Context
是你的 Activity
使其静态意味着你将保留对 Activity
的引用,即使在那之后 Activity
不再出现在屏幕上,即内存泄漏
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);
}
}
});