Android:使用 Retrofit 获取不同的对象列表数据

Posted

技术标签:

【中文标题】Android:使用 Retrofit 获取不同的对象列表数据【英文标题】:Android: Fetch Different Object List Data Using Retrofit 【发布时间】:2020-07-17 12:33:00 【问题描述】:

我正在尝试使用 Retrofit 获取不同类型的列表数据。 我已经制作了一个列表并在上面放了数据。

谁能建议我如何获取不同类型的模型数据?我有当我尝试将对象列表放入自定义模型列表时出现此错误:

java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to .....

模型类

public class WorkType 

    @SerializedName("type")
    @Expose
    private String type;
    @SerializedName("worklist")
    @Expose
    private List<Object> worklist = null;

    /**
     * No args constructor for use in serialization
     * 
     */
    public WorkType() 
    

    /**
     * 
     * @param worklist
     * @param type
     */
    public WorkType(String type, List<Object> worklist) 
        super();
        this.type = type;
        this.worklist = worklist;
    

    public String getType() 
        return type;
    

    public void setType(String type) 
        this.type = type;
    

    public List<Object> getWorkList() 
        return worklist;
    

    public void setWorkList(List<Object> worklist) 
        this.worklist = worklist;
    


改造界面

@FormUrlEncoded
@POST("worklist")
Call<ArrayList<WorkType>> worklist(
    @Field("teamid") String teamID
);

我发出 API 请求的片段

public class WorkTypeListFragment extends Fragment 
    private FragmentWorkTypeListBinding binding;
    private LoadingDialog loadingDialog;
    private Context context;
    public WorkTypeListFragment() 
        // Required empty public constructor
    

    @Override
    public void onAttach(@NonNull Context context) 
        super.onAttach(context);
        this.context = context;
    

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 
        // Inflate the layout for this fragment

        binding = DataBindingUtil.inflate(inflater,R.layout.fragment_work_type_list,container,false);

        init();

        String teamID = getActivity().getIntent().getStringExtra("teamid");
        fetchClientDetails("team1");

        return binding.getRoot();
    

    private void init() 
        loadingDialog = new LoadingDialog(getActivity());
    

    private void fetchClientDetails(String teamID)
        loadingDialog.startLoadingDialog(); // Added Loading Screen


        Call<ArrayList<WorkType>> call = RetrofitClient
                .getInstance()
                .getRetrofitApi()
                .worklist(teamID);

        call.enqueue(new Callback<ArrayList<WorkType>>() 
            @Override
            public void onResponse(Call<ArrayList<WorkType>> call, Response<ArrayList<WorkType>> response) 
                try
                    if(response.code() == 200)

                        ArrayList<WorkType> workTypeArrayList = response.body();
                        //Log.d("TAG", "onResponse: "+workTypeArrayList.get(1).getWorkList().get(0).getClientname());

                        assert workTypeArrayList != null;
                        bindDataToView(workTypeArrayList);

                     else 
                        Toast.makeText(getContext(), "Response Code is no 200", Toast.LENGTH_SHORT).show();
                        loadingDialog.dismissDialog();
                    

                catch(Exception e)
                    e.printStackTrace();
                
            

            @Override
            public void onFailure(Call<ArrayList<WorkType>> call, Throwable t) 
                Toast.makeText(getContext(), "Something Went wrong! Please try again later!", Toast.LENGTH_SHORT).show();
                loadingDialog.dismissDialog();
            

        );

    

    private void bindDataToView(ArrayList<WorkType> workTypeArrayList) 

        WorkTypesAdapter adapter = new WorkTypesAdapter(context,workTypeArrayList);
        binding.workTypeRv.setLayoutManager(new LinearLayoutManager(context));
        binding.workTypeRv.setAdapter(adapter);
    

RecyclearView 适配器类

public class WorkTypesAdapter extends RecyclerView.Adapter<WorkTypesAdapter.ViewHolder> 

    private Context mCtx;
    private List<WorkType> workTypeList;
    private final static int survey = 1;
    private final static int service = 2;
    private final static int maintain = 3;

    public WorkTypesAdapter(Context mCtx, List<WorkType> modelServiceList) 
        this.mCtx = mCtx;
        this.workTypeList = modelServiceList;
    

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
        LayoutInflater inflater = LayoutInflater.from(mCtx);
        View view = inflater.inflate(R.layout.layout_worktype, null);
        return new ViewHolder(view);
    

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

        WorkType currentWorkType  = workTypeList.get(position);
        String modelClass = currentWorkType.getType();
        List<Object> objectList = currentWorkType.getWorkList();

        switch (modelClass)
            /*case "survey":
                List<SurveyWorkList> surveyWorkLists = new ArrayList<>();
                for (Object object : objectList) 
                    surveyWorkLists.add((SurveyWorkList) object);

                    holder.workType.setText(currentWorkType.getType());
                    holder.workTypeCount.setText(surveyWorkLists.size());

                

                break;*/
            case "service":
                List<ServiceWorkList> serviceWorkLists = new ArrayList<>();
                for (Object object : objectList) 
                    serviceWorkLists.add((ServiceWorkList) object);
                

                /*holder.workType.setText(currentWorkType.getType());
                holder.workTypeCount.setText(serviceWorkLists.size());*/
                break;
            /*case "maintain":
                List<MaintainWorkList> maintainWorkLists = new ArrayList<>();
                for (Object object : objectList) 
                    maintainWorkLists.add((MaintainWorkList) object);
                

                holder.workType.setText(currentWorkType.getType());
                holder.workTypeCount.setText(maintainWorkLists.size());
                break;*/

            default:
                //Do nothing

        

        /*holder.workType.setText(modelService.getType());
        holder.workTypeCount.setText(workTypeList.size());*/
    

    @Override
    public int getItemCount() 
        return workTypeList.size();
    

    public class ViewHolder extends RecyclerView.ViewHolder

        TextView workType, workTypeCount;

        public ViewHolder(@NonNull View itemView) 
            super(itemView);

            workType = itemView.findViewById(R.id.work_type_tv);
            workTypeCount = itemView.findViewById(R.id.work_type_count_tv);
        
    

API 响应

[
    
        "type": "survey",
        "worklist": []
    ,
    
        "type": "service",
        "worklist": [
            
                "serviceid": "HS2020031613054318",
                "clientid": "R2020031612594874",
                "clientname": "********",
                "companyname": "",
                "membership": "",
                "phone": [
                    "*********"
                ],
                "**************",
                "account": 2,
                "slot": "morning",
                "orderstatus": "Completed",
                "orderstatuscode": "8",
                "remarks": ""
            
        ]
    ,
    
        "type": "maintain",
        "worklist": []
    
]

测量和维护会有不同的参数。

【问题讨论】:

【参考方案1】:

我找到了答案。 首先,你必须创建一个模型类:

@SerializedName("contents")
@Expose
private JsonElement contents = null;

在我的 API 中,我得到了一个元素类型。所以你知道你必须以哪种类型解析数据。假设您有三种类型。所以我们将创建一个 Type 对象:

switch(type)
    case 1:
        Type type = new TypeToken<ArrayList<Banner>>() 
                .getType();
               
        ArrayList<Banner> bannerList = new Gson().fromJson(baseModel.getContents(), type);

【讨论】:

以上是关于Android:使用 Retrofit 获取不同的对象列表数据的主要内容,如果未能解决你的问题,请参考以下文章

android之Retrofit使用

Android Studio - 使用 retrofit2 从 restdb 获取信息

无法在 Retrofit 2.0 android 中获取 json 字符串作为响应

Android 使用Retrofit获取JSON数据

Android - 获取错误“无法使用Retrofit构建实例(尽管至少存在一个创建)”

如何将 AsyncTask 转换为 Retrofit 以从 Android 中的 WCF Webservice 获取数据