2017-02-04 107 views
0

我正在嘗試Android的數據綁定。我的應用程序調用API並將結果存儲在對象模型中。我想在活動中顯示模型的內容。我的API調用是通過點擊一個按鈕來完成的。代碼如下:Android數據綁定

public class MainActivity extends AppCompatActivity { 

private static final String apiKey = "somekey"; 
APIInterface apiService = null; 
EditText editText; 
Button button; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    apiService = APIClient.getClient().create(APIInterface.class); 

    button = (Button) findViewById(R.id.button); 
    editText = (EditText) findViewById(R.id.edit_text); 

    button.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Log.d("Result", "Inside onclick"); 
      String text = editText.getText().toString(); 
      Call<APIResultModel> call = apiService.getSearchResult(text, apiKey); 
      Log.d("Result", "Before enqueue"); 
      call.enqueue(new Callback<APIResultModel>() { 
       @Override 
       public void onResponse(Call<APIResultModel> call, Response<APIResultModel> response) { 
        if (response.body().results != null) { 
         List<ProductModel> productModelList = response.body().results; 
         if (productModelList != null && productModelList.size() > 0) { 
          final ProductModel productModel = productModelList.get(0); 
          ActivityMainBinding binding = DataBindingUtil.setContentView(MainActivity.this, R.layout.activity_main); 
          binding.setProduct(productModel); 
         } 
        } 
       } 

       @Override 
       public void onFailure(Call<APIResultModel> call, Throwable t) { 

       } 
      }); 
      Log.d("Result", "After enqueue") 
     } 
    }); 

} 
} 

的XML文件的內容如下:

<?xml version="1.0" encoding="utf-8"?> 
<layout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools"> 
<data> 
    <variable 
     name="product" 
     type="com.mvvm.prakh.mvvmarchitecture.models.ProductModel" /> 
</data> 

<RelativeLayout 
    android:id="@+id/activity_main" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context="com.mvvm.prakh.mvvmarchitecture.MainActivity"> 

    <EditText 
     android:id="@+id/edit_text" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 

    <Button 
     android:id="@+id/button" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/edit_text" 
     android:layout_marginTop="8dp" 
     android:text="Submit" /> 

    <TextView 
     android:id="@+id/brand_name" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/button" 
     android:layout_marginTop="8dp" 
     android:text="@{product.brandName}" 
     android:hint="Brand name comes here" /> 

    <TextView 
     android:id="@+id/product_name" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/brand_name" 
     android:layout_marginTop="8dp" 
     android:text="@{product.productName}" 
     android:hint="Product name comes here" /> 
</RelativeLayout> 

我的模型如下:

package com.mvvm.prakh.mvvmarchitecture.models; 

import android.databinding.BaseObservable; 
import android.databinding.Bindable; 

import com.android.databinding.library.baseAdapters.BR; 
import com.google.gson.annotations.SerializedName; 

public class ProductModel extends BaseObservable{ 
@SerializedName("brandName") 
public String brandName; 
@SerializedName("productName") 
public String productName; 

public ProductModel(String brandName, String productName) { 
    this.brandName = brandName; 
    this.productName = productName; 
} 

@Bindable 
public String getBrandName() { 
    return brandName; 
} 

public void setBrandName(String brandName) { 
    this.brandName = brandName; 
    notifyPropertyChanged(BR.brandName); 
} 

@Bindable 
public String getProductName() { 
    return productName; 
} 

public void setProductName(String productName) { 
    this.productName = productName; 
    notifyPropertyChanged(BR.productName); 
} 
} 

我已經把在onClick()內部的Log.d語句,在第一次單擊它時給出了輸出,但是爲了後續的clic ks我沒有得到輸出。在我看來,在我使用數據綁定填充字段後,點擊被禁用。

logcat的輸出:

02-04 14:53:30.040 16778-16778/com.mvvm.prakh.mvvmarchitecture D/Result: Inside on click 
02-04 14:53:30.135 16778-16778/com.mvvm.prakh.mvvmarchitecture D/Result: Before enqueue 
02-04 14:53:30.151 16778-16778/com.mvvm.prakh.mvvmarchitecture D/Result: After enqueue 

所以單擊按鈕時我可以看到數據被填充作爲API的結果,但在點擊該按鈕進一步變得反應遲鈍。有什麼我在這裏失蹤,重置條件,以再次點擊按鈕?

+0

你能分享亞行日誌? –

+0

@SungMinLee添加了相同的內容。 –

+0

只需在'onClick'方法內添加一些'Log.d'內容(當它開始和結束時)並觀看'logcat' – pskink

回答

0

考慮到Android數據綁定,您的代碼有幾個問題。無論如何,你應該在onCreate()的開頭設置綁定並從那時開始使用。如果您沒有提及它,可以再次使用DataBindingUtil找到它。無需findViewById()或重置onResponse()中的佈局。

DataBindingUtil.setContentView(MainActivity.this, R.layout.activity_main) 

這會創建您的視圖的新實例,以及其後創建的視圖的非實例。相反,你應該像下面這樣實現它。

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    ActivityMainBinding binding = DataBindingUtil.setContentView(MainActivity.this, R.layout.activity_main); 
    apiService = APIClient.getClient().create(APIInterface.class); 

    binding.button.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      String text = binding.editText.getText().toString(); 
      Call<APIResultModel> call = apiService.getSearchResult(text, apiKey); 
      call.enqueue(new Callback<APIResultModel>() { 
       @Override 
       public void onResponse(Call<APIResultModel> call, Response<APIResultModel> response) { 
        if (response.body().results != null) { 
         List<ProductModel> productModelList = response.body().results; 
         if (productModelList != null && productModelList.size() > 0) { 
          binding.setProduct(productModelList.get(0)); 
         } 
        } 
       } 

       @Override 
       public void onFailure(Call<APIResultModel> call, Throwable t) { 
       } 
      }); 
     } 
    }); 
} 
+0

謝謝,你能告訴我爲什麼點擊按鈕後,按鈕被禁用了嗎? –

+0

它仍然是一個問題?在剛從佈局中移除按鈕之前;也許用你膨脹的新佈局覆蓋onResponse()'。所以你有一個新的按鈕,並沒有設置它。 – tynn

0

你需要改變你的代碼有點

public class MainActivity extends AppCompatActivity { 
private static final String apiKey = "somekey"; 
APIInterface apiService = null; 
ActivityMainBinding binding; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
binding = DataBindingUtil.setContentView(MainActivity.this, 
R.layout.activity_main); 
apiService = APIClient.getClient().create(APIInterface.class); 
binding.button.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     Log.d("Result", "Inside onclick"); 
     String text = editText.getText().toString(); 
     Call<APIResultModel> call = apiService.getSearchResult(text, apiKey); 
     Log.d("Result", "Before enqueue"); 
     call.enqueue(new Callback<APIResultModel>() { 
     @Override 
     public void onResponse(Call<APIResultModel> call, Response<APIResultModel> response) { 
       if (response.body().results != null) { 
        List<ProductModel> productModelList = response.body().results; 
        if (productModelList != null && productModelList.size() > 0) { 
         final ProductModel productModel = productModelList.get(0); 
         binding.setProduct(productModel); 
        } 
       } 
      } 
      @Override 
      public void onFailure(Call<APIResultModel> call, Throwable t) { 
      } 
     }); 
     Log.d("Result", "After enqueue") 
    } 
}); 
} 
}  

看跌NotifyChanges(),而不是notifyPropertyChanged(INT fieldId)在二傳手的POJO。 Difference you can find from the link

和教程從這個鏈接enter link description here