2017-02-04 1 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

から Difference you can find from the link

とチュートリアルでは、adbのログを共有してもらえますか? –

+0

@ SungMinLeeは同じことを追加しました。 –

+0

'log.d'を' onClick'メソッドの中に追加して(起動時と終了時に) 'logcat'を見てください。 – pskink

答えて

0

あなたのコードにはAndroid Data Bindingを考慮したいくつかの問題があります。すべてのtogtherあなたは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

DataBindingUtil.setContentViewを呼び出すと、onclicklistenerがリセットされます。 これは私のデータバインディングデモプロジェクトです。希望がお手伝いします。 https://github.com/LenaYan/AndroidMVVM

0

あなたはPOJOのためのセッターにあなたのコードを少しに

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型フィールド識別子)を変更する必要があります。このリンクenter link description here

関連する問題