2016-11-17 46 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