2017-02-04 2 views
0

Ich versuche Datenbindung für Android. Meine App ruft eine API auf und speichert das Ergebnis in einem Objektmodell. Ich möchte den Inhalt des Modells in einer Aktivität anzeigen. Mein API-Aufruf erfolgt auf Knopfdruck. Der Code ist wie folgt:Android DataBinding

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

} 
} 

die Inhalte der XML-Datei sind wie folgt:

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

Mein Modell ist wie folgt:

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

Ich habe setzen eine Log.d-Anweisung innerhalb der onClick(), auf den ersten Klick gibt es die Ausgabe aber für den nachfolgenden Klick ks Ich bekomme keine Ausgabe. Es scheint mir, dass der Klick deaktiviert ist, nachdem ich die Felder mit Datenbindung gefüllt habe.

Logcat Ausgang:

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 

So auf die Schaltfläche klicken kann ich die Daten sehen als Folge der API bevölkert wird, aber die Schaltfläche weiter klicken wird es nicht mehr reagiert. Gibt es etwas, das mir hier fehlt, das die Bedingung zurücksetzt, um zu erlauben, den Knopf wieder zu klicken?

+0

Könnten Sie adb log teilen? –

+0

@SungMinLee hinzugefügt das gleiche. –

+0

fügen Sie einfach ein 'Log.d' Zeug in' onClick' Methode (wenn es beginnt und wenn es endet) und beobachten Sie die 'logcat' – pskink

Antwort

0

Ihr Code hat mehrere Probleme hinsichtlich der Datenbindung von Android. Alles zusammen sollten Sie die Bindung am Anfang von onCreate() einrichten und ab diesem Zeitpunkt verwenden. Wenn Sie keinen Verweis darauf haben, können Sie es wieder mit finden. Keine Notwendigkeit für findViewById() oder Zurücksetzen des Layouts in onResponse().

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

Dies erstellt neue Instanzen Ihrer Ansichten und nicht von diesen Sie Setup danach. Stattdessen sollten Sie es wie folgt implementieren.

@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

Danke, können Sie mir sagen, warum die Schaltfläche deaktiviert werden, nachdem Sie einmal geklickt? –

+0

Ist es immer noch ein Problem?Bevor Sie die Schaltfläche aus dem Layout entfernt haben; vielleicht überlagert es mit dem neuen Layout, das du "onResponse()" aufgeblasen hast. Du hast also einen neuen Button und hast ihn nicht eingerichtet. – tynn

0

Sie benötigen Code wenig für 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") 
    } 
}); 
} 
}  

Put NotifyChanges() statt notifyPropertyChanged (int fieldID) in Setter zu ändern. Difference you can find from the link

und Anleitung von diesem Link enter link description here

Verwandte Themen