2016-06-06 13 views
0

Das TabLayout von MainActivity instanziiert dieses Fragment mit einem RecyclerView, wobei jedes einzelne Element ein CardView ist. Daten werden von einem Backend-Server abgerufen und aktualisieren den Adapter. Der Adapter bindet an den ViewHolder und der ViewHolder sollte die Widgets jedes CardView mit den Serverdaten aktualisieren.ViewHolder-Daten wurden gebunden, aber warum werden die Widgets nicht aktualisiert?

Dies ist die Vision, aber der ViewHolder aktualisiert das TextView-Widget von CardView nicht. Es zeigt weiterhin den Standardwert hardcoded aus dem Layout-XML an.

Um zu testen, fügte ich Breakpoints und Log-Anweisungen innerhalb des Adapters und der ViewHolder und durchschritten. Alles sah gut aus.

Überall wo ich die Log-Anweisung legte, protokollierte es die richtigen Daten.

Wenn die Datenbindung in Ordnung scheint und keine anderen Fehler vorhanden sind, warum aktualisiert dann die bindModel-Methode des ViewHolders nicht die TextView?

public class ModelsFragment extends Fragment { 

private final String API_KEY = "INSERT API KEY HERE"; 

private static final String ARG_CATEGORY = "model_category"; 
private String mCategory; 

private RecyclerView mModelRecyclerView; 
private ModelAdapter mModelAdapter; 

private List<Model> mModels; 

public static Fragment newInstance(String category) { 
    Bundle args = new Bundle(); 
    args.putString(ARG_CATEGORY, category); 
    ModelsFragment modelsFragment = new ModelsFragment(); 
    modelsFragment.setArguments(args); 

    return modelsFragment; 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    mCategory = getArguments().getString(ARG_CATEGORY); 

    final ProgressDialog progressDialog = new ProgressDialog(getActivity(), R.style.ProgressDialogTheme); 
    progressDialog.setCancelable(false); 
    progressDialog.setProgressStyle(android.R.style.Widget_ProgressBar); 
    progressDialog.show(); 

    EdmundsService service = EdmundsServiceGenerator.createService(EdmundsService.class); 

    Map<String, String> options = new HashMap<>(); 
    options.put("state", "new"); 
    options.put("year", "2016"); 
    options.put("view", "basic"); 
    options.put("api_key", API_KEY); 
    if (mCategory != null) { 
     options.put("category", mCategory); 
    } 

    // Use the hash map to actually query the backend API server with a GET request. 
    Call<Models> call = service.getModels(options); 
    call.enqueue(new Callback<Models>() { 
     @Override 
     public void onResponse(Call<Models> call, Response<Models> response) { 
      if (response.isSuccessful()) { 
       mModels = response.body().getModels(); 
       progressDialog.dismiss(); 
       updateUI(); 
       Log.i("GET Status", "Successfully retrieved data"); 
       Log.i("GET Status", response.body().getModelsCount().toString()); 
      } 
      else { 
       Log.i("GET Status", "Failed to retrieve data"); 
      } 
     } 

     @Override 
     public void onFailure(Call<Models> call, Throwable t) { 
      Log.e("Error retrieving data", t.getMessage()); 
     } 
    }); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    mModelRecyclerView = (RecyclerView) inflater.inflate(R.layout.fragment_models, container, false); 
    mModelRecyclerView.setHasFixedSize(true); 
    mModelRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); 

    updateUI(); 

    return mModelRecyclerView; 
} 

private void updateUI() { 
    mModelAdapter = new ModelAdapter(mModels); 
    mModelRecyclerView.setAdapter(mModelAdapter); 
} 

public class ModelHolder extends RecyclerView.ViewHolder { 

    private Model model; 
    private TextView mName; 

    public ModelHolder(LayoutInflater inflater, ViewGroup parent) { 
     super(inflater.inflate(R.layout.fragment_models_card_view_item, parent, false)); 
     View view = inflater.inflate(R.layout.fragment_models_card_view_item, parent, false); 

     mName = (TextView) view.findViewById(R.id.card_view_name); 
    } 

    public void bindModel(Model model) { 
     this.model = model; 

     // This if statement added to prevent null object reference errors. 
     if (this.model != null) { 
      // Data correctly logged. 
      Log.i("Inside IF statement", this.model.getName()); 

      mName.setText(this.model.getName()); // Why doesn't this update? 
     } 

     // Data correctly logged. 
     Log.i("Bound model", String.valueOf(this.model.getName())); 
    } 

} 

public class ModelAdapter extends RecyclerView.Adapter<ModelHolder> { 
    // Set number of Cards in the recycler view. 
    private List<Model> models; 

    public ModelAdapter(List<Model> models) { 
     this.models = models; 
    } 

    @Override 
    public ModelHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     return new ModelHolder(LayoutInflater.from(parent.getContext()), parent); 
    } 

    @Override 
    public void onBindViewHolder(ModelHolder holder, int position) { 
     // For our list of models, get one model by position and bind it to our view holder class. 
     Model model = models.get(position); 

     Log.i("Just prior to binding", model.getName()); 

     holder.bindModel(model); 
    } 

    @Override 
    public int getItemCount() { 
     return models == null ? 0 : models.size(); 
    } 
} 
} 
+0

Versuchen 'updateUI()' auf dem UI-Thread ausgeführt wird. – dharms

Antwort

0

Sie aufblasen 2 Aufrufe in Ihrer ModelHolder

public ModelHolder(LayoutInflater inflater, ViewGroup parent) { 
     super(inflater.inflate(R.layout.fragment_models_card_view_item, parent, false)); 
     View view = inflater.inflate(R.layout.fragment_models_card_view_item, parent, false); 

     mName = (TextView) view.findViewById(R.id.card_view_name); 
    } 

Die Ansicht, die Sie den Super-Anruf passieren ist die Ansicht, die Sie angezeigt werden. Die Ansicht, die Sie danach aufblasen, wird nicht angezeigt (und das, was Sie verwenden, um mName zu finden), weshalb Sie keine Änderungen sehen. Sie sollten nur eine Ansicht aufblasen und sie in die ModelHolder eingeben, damit Sie nach Ihrer R.id.card_view_name Ansicht suchen können.

Ex.

public ModelHolder(View view) { 
     super(view); 
     mName = (TextView) view.findViewById(R.id.card_view_name); 
    } 

und in den Adaptern onCreateViewHolder

@Override 
public ModelHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_models_card_view_item, parent, false); 
    return new ModelHolder(view); 
}