使用Retrofit从API加载JSON数据并在Recyclerview中填充它

时间:2016-11-08 15:32:53

标签: android json android-recyclerview retrofit2

调试时一切似乎都运行正常,我正如我预期的那样得到JSON响应,但它没有填充到我的recyclerview,给出

E/RecyclerView: No adapter attached; skipping layout

任何信息如何解决这个问题?

这就是我的API的样子

{
    "list": [
        {
            "id": 1,
            "name_en": "Project Management",
            "name_ar": ""
        },
        {
            "id": 2,
            "name_en": "Quality Management",
            "name_ar": ""
        },
        {
            "id": 3,
            "name_en": "IT Service Management",
            "name_ar": ""
        },
        {
            "id": 4,
            "name_en": "IT Security",
            "name_ar": ""
        },
        {
            "id": 5,
            "name_en": "IT Audit",
            "name_ar": ""
        },
        {
            "id": 6,
            "name_en": "Operating Systems",
            "name_ar": ""
        },
        {
            "id": 7,
            "name_en": "Networks",
            "name_ar": ""
        },
        {
            "id": 8,
            "name_en": "Virtualization and Cloud",
            "name_ar": ""
        },
        {
            "id": 9,
            "name_en": "Web App and Programming",
            "name_ar": ""
        },
        {
            "id": 10,
            "name_en": "Design an Special Effects",
            "name_ar": ""
        },
        {
            "id": 11,
            "name_en": "Business Productivity Tools",
            "name_ar": ""
        },
        {
            "id": 12,
            "name_en": "Certified Business Professional",
            "name_ar": ""
        },
        {
            "id": 13,
            "name_en": "Diploma Courses",
            "name_ar": ""
        }
    ]
}

JSONResponse Class

public class JSONResponse {

    private CategoryModel[] list;

    public CategoryModel[] getCategories() {
        return list;
    }
}

请求界面

public interface RequestInterface {

    @GET("projects/newhorizons/api/categories")
    Call<JSONResponse> getJSON();
}

ModelClass

public class CategoryModel {
    private int id;
    private String name_en;
    private String name_ar;
    private String categoryImage;

    public int getId() {
        return id;
    }

    public String getName_en() {
        return name_en;
    }

    public String getName_ar() {
        return name_ar;
    }

    public String getCategoryImage() {
        return categoryImage;
    }
}

AdapterClass

public class CategoryAdapter extends RecyclerView.Adapter<CategoryView> {

    private ArrayList<CategoryModel> categoryModels;

    public CategoryAdapter(ArrayList<CategoryModel> categoryModels) {
        this.categoryModels = categoryModels;

}

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

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

        //holder.categoryImage.setImageResource(categoryModels.get(position).getCategoryImage());
        holder.categoryName.setText(categoryModels.get(position).getName_en());
    }


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

MainActivity

public class MainActivity extends AppCompatActivity {

    private RecyclerView categoriesView;
    private ArrayList<CategoryModel> courseCategories;
    private CategoryAdapter myCategoryAdapter;

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



        initViews();

        CategoryItemDecoration decoration= new CategoryItemDecoration(this,R.dimen.item_offset);
        categoriesView.addItemDecoration(decoration);

        //Intent intent = new Intent(this, LoginActivity.class);
        //startActivity(intent);



    }

    private void initViews(){

        loadJSON();

        categoriesView = (RecyclerView) findViewById(R.id.categories_grid);
        categoriesView.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main,menu);
        return super.onCreateOptionsMenu(menu);

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        int id = item.getItemId();
        return id == R.id.action_settings || super.onOptionsItemSelected(item);


    }

    private void loadJSON(){
        OkHttpClient.Builder client = new OkHttpClient.Builder();
        client.readTimeout(60, TimeUnit.SECONDS);
        client.connectTimeout(60, TimeUnit.SECONDS);
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://combal.net")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        RequestInterface requestInterface = retrofit.create(RequestInterface.class);
        Call<JSONResponse> call = requestInterface.getJSON();
        call.enqueue(new Callback<JSONResponse>() {

            @Override
            public void onResponse(Call<JSONResponse> call, Response<JSONResponse> response) {

                int statusCode = response.code();

                //relieve the categories here
                JSONResponse jsonResponse = response.body();
                courseCategories = new ArrayList<>(Arrays.asList(jsonResponse.getCategories()));
                myCategoryAdapter = new CategoryAdapter(courseCategories);
                categoriesView.setAdapter(myCategoryAdapter);

            }

            @Override
            public void onFailure(Call<JSONResponse> call, Throwable t) {

                Log.d("Error",t.getMessage());

            }
        });

    }
}

这是我的CategoryView类

public class CategoryView extends RecyclerView.ViewHolder{

       public ImageView categoryImage;
       public TextView categoryName;

public CategoryView(View itemView) {
        super(itemView);
        categoryImage = (ImageView) itemView.findViewById(R.id.category_image);
        categoryName = (TextView) itemView.findViewById(R.id.category_name);

        }
}

1 个答案:

答案 0 :(得分:0)

你的代码调用onResponse()方法中的适配器,该方法在backround线程上运行。 UI元素只在主线程上运行,即UIThread,这里你需要主线程上的调用适配器,即使用runOnUIThread(Runnable r)方法。

 @Override
        public void onResponse(Call<JSONResponse> call, 
        Response<JSONResponse> response) {

            int statusCode = response.code();

            //relieve the categories here
            JSONResponse jsonResponse = response.body();
            courseCategories = new ArrayList<>(Arrays.asList(jsonResponse.getCategories()));

          MyActivity.this.runOnUiThread(new Runnable() {
        @Override
        public void run() {
                  myCategoryAdapter = new CategoryAdapter(courseCategories);
            categoriesView.setAdapter(myCategoryAdapter);

        }
    });
        }