2016-11-17 45 views
0

所以,我有一个带有自定义BaseAdapter的TextView和ListView的活动。本次活动是这样的:从ListView项目中的EditText值更新活动的TextView

enter image description here

正如你可以看到,该列表的每一个项目是一个自定义布局的基本思路是:每一个在它的数字的EditText从变化中,“总”的TextView时间活动(也就是每个产品的价格总和)也必须更新。

我想它必须以某种方式从Adapter类完成,但我不知道该怎么做。

我的动态文件看起来像这样(它从服务器产品的数据通过“GetCollectionProducts”的AsyncTask,在这里我设置适配器):

public class ProductAisleActivity extends AppCompatActivity implements View.OnClickListener{ 
ListView productList; 
Button participate; 

ImageButton search; 
EditText searchET; 
TextView productsTotal; 

Product[] colProducts; 
RelativeLayout collectionHeader; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_product_aisle); 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 

    getSupportActionBar().setDisplayHomeAsUpEnabled(true); 

    /* ... 
     Irrelevant code to this question 
    */ 

    productsTotal = (TextView) findViewById(R.id.products_aisle_total); 
    productsTotal.setText(
      getResources().getString(
        R.string.productsTotal, 
        String.valueOf(0.00) 
      ) 
    ); 

    productList = (ListView) findViewById(R.id.products_aisle_list); 
    new GetCollectionProducts().execute(); 
} 

private class GetCollectionProducts extends AsyncTask<Void,Void,JSONArray>{ 

    @Override 
    protected JSONArray doInBackground(Void... voids) { 
     /* Irrelevant code to this question */ 
    } 

    @Override 
    protected void onPostExecute(JSONArray jsonArray) { 
     /* Irrelevant code to this question */ 
       productList.setAdapter(
         new CollectionProductsAdapter(
           ProductAisleActivity.this, 
           colProducts 
         ) 
       ); 
} 
} 

我的适配器文件,如下所示:

public class CollectionProductsAdapter extends BaseAdapter { 
Context context; 
ProductAisleActivity.Product[] data; 
private static LayoutInflater inflater = null; 

public CollectionProductsAdapter(Context context, ProductAisleActivity.Product[] data) { 
    this.context = context; 
    this.data = data; 
    inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
} 

@Override 
public int getCount() { 
    return data.length; 
} 

@Override 
public Object getItem(int i) { 
    return data[i]; 
} 

@Override 
public long getItemId(int i) { 
    return i; 
} 

@Override 
public View getView(int i, View view, ViewGroup viewGroup) { 
    View v = view; 
    if (v == null) { 
     v = inflater.inflate(R.layout.product_row_layout, null); 
    } 

    ProductAisleActivity.Product product = data[i]; 

    /* ... 
     Irrelevant code to this question 
    */ 

    EditText productQuantity = (EditText) v.findViewById(R.id.productQuantity); 
    productQuantity.setText("0"); 


    return v; 
} 

} 

我被困在这一点上,任何帮助将不胜感激。

+0

有几种方法。您可以使用TextWatcher来检查EditText中的内容何时被修改并将其推送到Observer或其他东西。 – zgc7009

+0

@ zgc7009你能给我举个例子吗?谢谢! –

回答

0

首先,您需要监听EditText中的任何更改,以便您可以动态处理事件,而无需明确使用提交按钮之类的内容。你可以用TextWatcher来做到这一点。

productQuanity.addTextChangedListener(new TextWatcher() { 
     private double originalCost = 0.0; 

     @Override 
     public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
      // Before we change the text, set the originalCost 
      // so we can know what the change is after the edit 
      originalCost = getCost(s.toString()); 
     } 

     @Override 
     public void onTextChanged(CharSequence s, int start, int before, int count) { 
      // You don't need to utilize this method 
     } 

     @Override 
     public void afterTextChanged(Editable s) { 
      // After the change has taken place in the text, 
      // get the new cost and calculate the difference 
      double newCost = getCost(s.toString()); 
      double changeInCost = newCost - originalCost; 
     } 

     private double getCost(String input){ 
      String count = input.toString(); 
      if(TextUtils.isEmpty(count)) 
       return 0.0; 
      else 
       return (double) Integer.parseInt(count) * product.getPrice(); 
     } 
    }); 

现在我们已经改变了成本,我们该怎么做呢?我们需要通知活动我们有变化。我们可以用观察者来做到这一点,这很好,但为了好玩,我们使用一个接口来实现一个监听器。

修改您的适配器类现在

public class CollectionProductsAdapter extends BaseAdapter { 

    public interface CostChangedListener{ 
     void onCostChanged(double change); 
    } 

    Context context; 
    ProductAisleActivity.Product[] data; 
    private LayoutInflater inflater = null; // THIS SHOULDN'T BE STATIC 
    CostChangedListener listener; 

    public CollectionProductsAdapter(Context context, ProductAisleActivity.Product[] data, CostChangedListener listener) { 
     this.context = context; 
     this.data = data; 
     inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     this.listener = listener; 
    } 

    // The rest of your code 
} 

,当我们更新我们的TextWatcher成本,我们可以称之为

if(listener != null) 
    listener.onCostChanged(changeInCost); 

末,以确保我们正确地利用这一点,我们就需要通过一个听众在我们的CollectionProductsAdapter构造函数

productList.setAdapter(new CollectionProductsAdapter(
      ProductAisleActivity.this, colProducts, 
      new CostChangeListener(){ 
       @Override 
       public void onCostChanged(double change){ 
        double currentTotal = Double.valueOf(productTotal.getText()); 
        double newTotal = currentTotal + change; 
        productTotal.setText(String.valueOf(newTotal)); 
       })); 

显然你可能ne编辑调整一些这使它完美匹配,我没有测试它,所以有些事情可能会有点偏差,但这应该让你朝着正确的方向前进。如果您有任何问题请随时发表评论,我会尽力帮助您解决问题。

注意

  1. 不要让静态参考像你和你的布局吹气
  2. 这是值得考虑看看RecyclerView或至少ViewHolder模式与适配器
+0

谢谢!我现在会测试它,并告诉你它是怎么回事! –

+0

嘿!我有两个问题。 1)我在哪里可以在'afterTextChanged()'方法中获得'oldCost'变量值?它没有宣布! 2)我在哪里放置这个'if(listener!= null) listener.onCostChanged(changeInCost);'?谢谢! –

+0

@GénessisSánchez应该说'originalCost'不是'oldCost',我编辑过它。感谢您的通知。计算'changeInCost'后,您可以将侦听器回调放在'afterTextChanged()'中。 – zgc7009

0

您想添加一个textChangedListener用于在EditText中更改值时更改项目值。

你可以在这里使用TextChangedListener:

EditText myEditTextField = new EditText(this); 

myEditTextField.addTextChangedListener(new TextWatcher() { 
    @Override 
    public void beforeTextChanged(CharSequence s, int start, int count, int after) { 

    } 

    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 

    } 

    @Override 
    public void afterTextChanged(Editable s) { 

    } 
}); 

您可以根据您的需要执行的任务。它有3种方法:

1.beforeTextChanged

2.onTextChanged

3.afterTextChanged

这样你可以得到你的任务由 “afterTextChanged” 的帮助下完成。你必须简单地将你的计算方法称为no。当用户输入一个特定的号码时,它会显示你想要的价格。

希望得到这个帮助!

+0

非常感谢,这似乎是我正在寻找的答案。不过,我有两个问题,第一个问题: 必须在哪里声明TextWatcher?进入活动文件或进入适配器文件? 第二个: 如果在适配器文件中,我该如何访问活动的TextView? 再次感谢您! –

+0

你可以在你的editText声明下面实现你的textWatcher。如果你想在适配器文件中实现它,那么首先你必须在你的适配器的viewHolder中定义editText,并在其下面(在相同的viewHolder类中) ,你可以实现textWatcher – Swr7der

+0

onTextChanged不会提供适当的答案。 onTextChanged提供后续编辑。 afterTextChanged将为他提供完整的字符串来计算。 – zgc7009