2017-02-04 4 views
0

Android 용 데이터 바인딩을 시도하고 있습니다. 내 애플 리케이션 API를 호출하고 개체 모델에 결과를 저장합니다. 나는 그 활동의 모델 내용을 보여주고 싶다. 내 API 호출은 버튼 클릭만으로 이루어집니다. 코드는 다음과 같다 :Android 데이터 바인딩

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); 
} 
} 

내가 넣어 가지고 다음과 같이

<?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> 

내 모델은 다음과 같이

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 파일의 내용은 onClick() 안에있는 Log.d 문은 첫 번째 클릭시 출력을 제공하지만 이후의 진실을 나타냅니다. ks 출력이 없습니다. 데이터 바인딩을 사용하여 필드를 채운 후에 클릭이 비활성화 된 것으로 보입니다.

로그 캣 출력 :

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 

그래서 버튼 I 데이터는 API의 결과로하지만 버튼을 클릭에 채워지는 볼 수 클릭에 더는 응답된다. 여기서 버튼을 다시 클릭 할 수 있도록 조건을 재설정하는 누락 된 것이 있습니까?

+0

에서 Difference you can find from the link

및 튜토리얼은 ADB 로그를 공유 할 수 있을까요? –

+0

@SungMinLee도 같은 것을 추가했습니다. –

+0

'on.d' 메쏘드 안에'Log.d'를 추가하고 (시작과 끝날 때)'logcat'을 보시오. – pskink

답변

0

코드에 Android 데이터 바인딩을 고려하면 몇 가지 문제가 있습니다. 모든 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에 대한 세터에서 (fieldID가를 INT) 오히려 notifyPropertyChanged보다) (코드 조금에게

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을 변경해야합니다. 이 링크 enter link description here