Я пытался заставить вид переработчика работать с модернизацией. Кажется, я извлекаю JSON-файл из метода getRecipes (), и мои журналы показывают, что некоторые данные есть.

Однако, когда я вызываю свой метод getRecipes () из onCreate (), что-то идет не так. Когда я проверяю, содержит ли мой массив recipeList результаты JSON в onCreate, он говорит, что он пуст. Почему это происходит, если мои журналы в методе getRecipes () показывают, что данные есть ...?

Не уверен, если это проблема с моим представлением переработчика или что я делаю с модернизацией, или что-то еще. Пытались несколько дней, чтобы понять, поэтому любой совет будет принята с благодарностью.

JSON https://d17h27t6h515a5.cloudfront.net/topher/2017/May/ 59121517_baking / baking.json

public class ItemListActivity extends AppCompatActivity {

private boolean mTwoPane;
public static final String LOG_TAG = "myLogs";
public static List<Recipe> recipeList = new ArrayList<>();


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getRecipes();
    setContentView(R.layout.activity_item_list);

    getRecipes();

    //Logging to check that recipeList contains data

    if(recipeList.isEmpty()){
        Log.d(LOG_TAG, "Is empty");
    }else {
        Log.d(LOG_TAG, "Is not empty");
    }

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    toolbar.setTitle(getTitle());

    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.item_list);
    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
    recyclerView.setLayoutManager(layoutManager);

    SimpleItemRecyclerViewAdapter simpleItemRecyclerViewAdapter = new SimpleItemRecyclerViewAdapter(recipeList);

    recyclerView.setAdapter(simpleItemRecyclerViewAdapter);

    if (findViewById(R.id.item_detail_container) != null) {

        mTwoPane = true;
    }

}


public void getRecipes(){

    String ROOT_URL = "https://d17h27t6h515a5.cloudfront.net/topher/2017/May/59121517_baking/";

    Retrofit RETROFIT = new Retrofit.Builder()
            .baseUrl(ROOT_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    RecipeService service = RETROFIT.create(RecipeService.class);

    Call<List<Recipe>> call = service.getMyJson();
    call.enqueue(new Callback<List<Recipe>>() {
        @Override
        public void onResponse(Call<List<Recipe>> call, Response<List<Recipe>> response) {
            Log.d(LOG_TAG, "Got here");
            if (!response.isSuccessful()) {
                Log.d(LOG_TAG, "No Success");
            }

            Log.d(LOG_TAG, "Got here");

            recipeList = response.body();

            //Logging to check data is there
            Log.v(LOG_TAG, "LOGS" + recipeList.size());

            for (int i = 0; i < recipeList.size(); i++) {
                String newString = recipeList.get(i).getName();

                Ingredients[] ingredients = recipeList.get(i).getIngredients();
                for(int j = 0; j < ingredients.length; j++){
                    Log.d(LOG_TAG, ingredients[j].getIngredient());
                }

                Steps[] steps = recipeList.get(i).getSteps();
                for(int k = 0; k < steps.length; k++){
                    Log.d(LOG_TAG, steps[k].getDescription());
                }

                Log.d(LOG_TAG, newString);


            }


        }

        @Override
        public void onFailure(Call<List<Recipe>> call, Throwable t) {
            Log.e("getRecipes throwable: ", t.getMessage());
            t.printStackTrace();

        }
    });


}



public class SimpleItemRecyclerViewAdapter
        extends RecyclerView.Adapter<SimpleItemRecyclerViewAdapter.ViewHolder> {

    private final List<Recipe> mValues;

    public SimpleItemRecyclerViewAdapter(List<Recipe> items) {
        mValues = items;
    }

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

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {

        holder.mItem = mValues.get(position);
        holder.mContentView.setText(mValues.get(position).getName());

        holder.mView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mTwoPane) {
                    Bundle arguments = new Bundle();
                    arguments.putString(ItemDetailFragment.ARG_ITEM_ID, holder.mItem.getId());
                    ItemDetailFragment fragment = new ItemDetailFragment();
                    fragment.setArguments(arguments);
                    getSupportFragmentManager().beginTransaction()
                            .replace(R.id.item_detail_container, fragment)
                            .commit();
                } else {
                    Context context = v.getContext();
                    Intent intent = new Intent(context, ItemDetailActivity.class);
                    intent.putExtra(ItemDetailFragment.ARG_ITEM_ID, holder.mItem.getId());

                    context.startActivity(intent);
                }
            }
        });
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder {
        public  View mView;
        public  TextView mContentView;
        public Recipe mItem;


        public ViewHolder(View view) {
            super(view);
            mView = view;
            mContentView = (TextView) view.findViewById(R.id.content);

        }

        @Override
        public String toString() {
            return super.toString() + " '" + mContentView.getText() + "'";
        }
    }
}

RecipeService

public interface RecipeService {
@GET("baking.json")
Call<List<Recipe>> getMyJson();}

Модели

Рецепт приготовления

public class Recipe{

private Ingredients[] ingredients;

private String id;

private String servings;

private String name;

private String image;

private Steps[] steps;

public Ingredients[] getIngredients ()
{
    return ingredients;
}

public void setIngredients (Ingredients[] ingredients)
{
    this.ingredients = ingredients;
}

public String getId ()
{
    return id;
}

public void setId (String id)
{
    this.id = id;
}

public String getServings ()
{
    return servings;
}

public void setServings (String servings)
{
    this.servings = servings;
}

public String getName ()
{
    return name;
}

public void setName (String name)
{
    this.name = name;
}

public String getImage ()
{
    return image;
}

public void setImage (String image)
{
    this.image = image;
}

public Steps[] getSteps ()
{
    return steps;
}

public void setSteps (Steps[] steps)
{
    this.steps = steps;
}

@Override
public String toString()
{
    return "[ingredients = "+ingredients+", id = "+id+", servings = "+servings+", name = "+name+", image = "+image+", steps = "+steps+"]";
}}

Ингредиенты

public class Ingredients{
private String measure;

private String ingredient;

private String quantity;

public String getMeasure ()
{
    return measure;
}

public void setMeasure (String measure)
{
    this.measure = measure;
}

public String getIngredient ()
{
    return ingredient;
}

public void setIngredient (String ingredient)
{
    this.ingredient = ingredient;
}

public String getQuantity ()
{
    return quantity;
}

public void setQuantity (String quantity)
{
    this.quantity = quantity;
}

@Override
public String toString()
{
    return "[measure = "+measure+", ingredient = "+ingredient+", quantity = "+quantity+"]";
}}

Меры

public class Steps{

private String id;
     private String shortDescription;

    private String description;

    private String videoURL;

    private String thumbnailURL;

    public String getId ()
    {
        return id;
    }

    public void setId (String id)
    {
        this.id = id;
    }

    public String getShortDescription ()
    {
        return shortDescription;
    }

    public void setShortDescription (String shortDescription)
    {
        this.shortDescription = shortDescription;
    }

    public String getDescription ()
    {
        return description;
    }

    public void setDescription (String description)
    {
        this.description = description;
    }

    public String getVideoURL ()
    {
        return videoURL;
    }

    public void setVideoURL (String videoURL)
    {
        this.videoURL = videoURL;
    }

    public String getThumbnailURL ()
    {
        return thumbnailURL;
    }

    public void setThumbnailURL (String thumbnailURL)
    {
        this.thumbnailURL = thumbnailURL;
    }

    @Override
    public String toString()
    {
        return "[id = "+id+", shortDescription = "+shortDescription+", description = "+description+", videoURL = "+videoURL+", thumbnailURL = "+thumbnailURL+"]";
    }}

Бревна

https://gist.github.com/2triggers/12b6eeb32ed8909ab50bbadd4742d7f7

1
Rogerto 21 Окт 2017 в 00:16

3 ответа

Лучший ответ

Это потому, что вы отправляете список рецептов в адаптер до того, как он будет заполнен, после того, как вы отправляете список рецептов в пустой адаптер, вы заполняете свой список рецептов из метода getRecipes, вы можете задаться вопросом, объявили ли вы метод getRecipes еще до вы присваиваете список рецептов адаптеру, так что почему он пустой, да, но факт в том, что ваш getRecipes работает в фоновом потоке, поэтому даже до того, как ваш список рецептов будет заполнен, ваше назначение адаптера происходит в основном потоке, поэтому вы в основном назначаете пустой список, Единственное, что вы можете сделать, это уведомить адаптер при изменении данных или когда список рецептов заполнен данными из метода getRecipe.

Когда вы назначаете recipelist = response.body сразу после этого, вы можете уведомить адаптер

Или переместить эти две строки

SimpleItemRecyclerViewAdapter simpleItemRecyclerViewAdapter = new SimpleItemRecyclerViewAdapter(recipeList);
recyclerView.setAdapter(simpleItemRecyclerViewAdapter);

Сразу после

 recipelist = response.body;

В методе getRecipes

0
Abhilash Reddy 20 Окт 2017 в 21:42

Он всегда будет пустым, потому что эта строка будет выполняться до получения ответа от сервера.

if(recipeList.isEmpty()){
         Log.d(LOG_TAG, "Is empty");
    }else {
        Log.d(LOG_TAG, "Is not empty");
    }

Лучше вызывать это после этой строки recipeList = response.body ();

SimpleItemRecyclerViewAdapter simpleItemRecyclerViewAdapter = new SimpleItemRecyclerViewAdapter(recipeList);

        recyclerView.setAdapter(simpleItemRecyclerViewAdapter);

        if (findViewById(R.id.item_detail_container) != null) {

            mTwoPane = true;
        }
1
Thientvse 21 Окт 2017 в 02:28

Попробуйте создать конструктор со всеми атрибутами из вашего Recipe.class

Например: public Ingredients (Строковая мера, Строковые ингредиенты, Строковое количество) {this.measure = measure; this.ingredients = ингредиенты; this.quantity = количество}

Сделайте то же самое во всех классах, где составляют ваш объект списка.

0
Bruno Cardoso 20 Окт 2017 в 22:18