简体   繁体   English

RecyclerView 未显示从 API 获取的数据

[英]RecyclerView not showing data fetched from API

Im creating an app that shows user recipe based on ingredient they have using SpoonAcular API The app fetched the ingredient user currently have on Firebase Realtime Database and using the data to fetch the recipe.我正在创建一个应用程序,该应用程序根据他们使用SpoonAcular API的成分显示用户食谱 该应用程序获取了用户当前在 Firebase 实时数据库上拥有的成分,并使用数据来获取食谱。 I've created all the adapter needed to fetch the data but the app not showing the recyclerView as its should.我已经创建了获取数据所需的所有适配器,但应用程序没有按应有的方式显示 recyclerView。 Here's my code这是我的代码

RequestManager.java RequestManager.java

public class RequestManager {

    Context context;
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://api.spoonacular.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    public RequestManager(Context context){
        this.context = context;
    }

    public void getRecipeByIngredient(RecipeByIngredientListener listener, List <String> IngredientList){
        CallRecipeByIngredient callRecipeByIngredient = retrofit.create(CallRecipeByIngredient.class);


        Call <List<RecipeIngredResponse>> call = callRecipeByIngredient.callRecipeByIngredient(context.getString(R.string.API), IngredientList, "20");
        call.enqueue(new Callback<List<RecipeIngredResponse>>() {
            @Override
            public void onResponse(Call<List<RecipeIngredResponse>> call, Response<List<RecipeIngredResponse>> response) {
                if(!response.isSuccessful()){
                    listener.didError(response.message());
                    return;
                }
                listener.didFetch(response.body(), response.message());
            }

            @Override
            public void onFailure(Call<List<RecipeIngredResponse>> call, Throwable t) {
                listener.didError(t.getMessage());
            }
        });
    }

    private interface CallRecipeByIngredient{
        @GET("recipes/findByIngredients")
        Call<List<RecipeIngredResponse>> callRecipeByIngredient(
                @Query("apiKey") String apiKey,
                @Query("ingredients") List <String> Ingredient,
                @Query("number") String number
        );
    }
}

RecipeByIngredientListener RecipeByIngredientListener

public interface RecipeByIngredientListener {
    void didFetch(List<RecipeIngredResponse> response, String message);
    void didError(String message);
}

RecipeByIngredientAdapter RecipeByIngredientAdapter

public class RecipeByIngredientAdapter extends RecyclerView.Adapter<RecipeByIngredientViewHolder> {

    Context context;
    List<RecipeIngredResponse> list;

    public RecipeByIngredientAdapter(Context context, List<RecipeIngredResponse> list) {
        this.context = context;
        this.list = list;
    }

    @NonNull
    @Override
    public RecipeByIngredientViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new RecipeByIngredientViewHolder(LayoutInflater.from(context).inflate(R.layout.list_recipebyingred , parent, false));
    }

    @SuppressLint("SetTextI18n")
    @Override
    public void onBindViewHolder(@NonNull RecipeByIngredientViewHolder holder, int position) {
        holder.recipeName.setText(list.get(position).title);
        holder.missedIngred.setText(list.get(position).missedIngredientCount + " Missed Ingredient");
        holder.likes.setText(list.get(position).likes + " Likes");
        Picasso.get().load(list.get(position).image).into(holder.recipeImage);
    }

    @Override
    public int getItemCount() {
        return list.size();
    }
}

class RecipeByIngredientViewHolder extends RecyclerView.ViewHolder{

    ImageView recipeImage;
    TextView recipeName, missedIngred, likes;

    public RecipeByIngredientViewHolder(@NonNull View itemView) {
        super(itemView);

        recipeImage = itemView.findViewById(R.id.recipeImage);
        recipeName = itemView.findViewById(R.id.recipeName);
        missedIngred = itemView.findViewById(R.id.missedIngred);
        likes = itemView.findViewById(R.id.likes);
    }
}

Home.java (Fragment)首页.java(片段)

RandomRecipeAdapter randomRecipeAdapter;
RequestManager manager;
RecyclerView recyclerView, recyclerFromYourFridge;
RecipeByIngredientAdapter recipeByIngredientAdapter;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    // Inflate the layout for this fragment
    View v =  inflater.inflate(R.layout.fragment_home, container, false);

    manager = new RequestManager(getContext());
    manager.getRandomRecipe(randomRecipeResponseListener);

    recyclerFromYourFridge = (RecyclerView) v.findViewById(R.id.recyclerFromYourFridge);
    //get ingredient from database
    List<String> Ingredient =  new ArrayList<>();
    FirebaseAuth mAuth = FirebaseAuth.getInstance();
    String currentUser = mAuth.getCurrentUser().getUid();
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("Ingredient").child(currentUser);
    reference.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DataSnapshot> task) {
            if(task.isSuccessful()){
                for (DataSnapshot userSnapshot : task.getResult().getChildren()){
                    Ingredient.add(userSnapshot.getKey());
                }
            }
        }
    });

    manager.getRecipeByIngredient(recipeByIngredientListener , Ingredient);

    recyclerView = (RecyclerView) v.findViewById(R.id.randomRecipeRecycler);
    return v;

}

private final RecipeByIngredientListener recipeByIngredientListener = new RecipeByIngredientListener() {
    @Override
    public void didFetch(List<RecipeIngredResponse> response, String message) {

        recyclerFromYourFridge.setHasFixedSize(true);
        recyclerFromYourFridge.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
        recipeByIngredientAdapter = new RecipeByIngredientAdapter(getContext(), response);
        recyclerFromYourFridge.setAdapter(recipeByIngredientAdapter);
    }

    @Override
    public void didError(String message) {
        Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
    }
};

Pretty sure there's nothing wrong with the app fetching ingredient from Firebase cause i've tested it and the api capable to get recipe by using ArrayList.很确定应用程序从 Firebase 获取成分没有任何问题,因为我已经对其进行了测试,并且 api 能够通过使用 ArrayList 获取配方。 Is there anything wrong with this code?这段代码有什么问题吗?

The issue is because calls to the Firebase database are asynchronous, if you call the value outside of addOnCompleteListener can be empty问题是因为对 Firebase 数据库的调用是异步的,如果调用 addOnCompleteListener 之外的值可以为空

Change the reference.get().addOnCompleteListener to:将 reference.get().addOnCompleteListener 更改为:

reference.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DataSnapshot> task) {
        if(task.isSuccessful()){
            List<String> Ingredient =  new ArrayList<>();
            for (DataSnapshot userSnapshot : task.getResult().getChildren()){
                Ingredient.add(userSnapshot.getKey());
            }
            manager.getRecipeByIngredient(recipeByIngredientListener , Ingredient);
        }
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM