【问题标题】:Recyclerview json data binding has failedRecyclerview json数据绑定失败
【发布时间】:2018-01-31 20:31:16
【问题描述】:

我正在尝试将 JSON 数据绑定到 recyclerView,但数据似乎没有绑定到 RecyclerView。 令人惊讶的是,当我敬酒时,我看到它是可用的。可能是什么问题?

 private void parseJson(String  result){

        try {
            if (result!=null) {
                String resultTostring = "" + result;
                JSONObject obj = new JSONObject(resultTostring).getJSONObject("ScheduleResource");
                JSONArray arr = obj.getJSONArray("Schedule");
                itemList = new ArrayList<>();
                for (int i = 0; i < arr.length(); i++)
                {
                    String DepartureAirport = arr.getJSONObject(i).getJSONObject("Flight").getJSONObject("Departure").getString("AirportCode");
                    String ArrivalAirport = arr.getJSONObject(i).getJSONObject("Flight").getJSONObject("Arrival").getString("AirportCode");
                    String Duration = arr.getJSONObject(i).getJSONObject("TotalJourney").getString("Duration");
                    String DepartureTime = arr.getJSONObject(i).getJSONObject("Flight").getJSONObject("Departure").getJSONObject("ScheduledTimeLocal").getString("DateTime");
                    String ArrivalTime = arr.getJSONObject(i).getJSONObject("Flight").getJSONObject("Arrival").getJSONObject("ScheduledTimeLocal").getString("DateTime");
                    String Stops = arr.getJSONObject(i).getJSONObject("Flight").getJSONObject("Details").getJSONObject("Stops").getString("StopQuantity");

                    FlightModel model = new FlightModel();
                    model.setDepartureAirport(DepartureAirport);
                    model.setArrivalAirport(ArrivalAirport);
                    model.setDuration(Duration);
                    model.setDeparturTimee(DepartureTime);
                    model.setArrivalTime(ArrivalTime);
                    model.setStops(Stops);
                    model.Stops= Stops;


                    itemList.add(model);



                    Toast.makeText(FlightListActivity.this, "DEPT : " + DepartureAirport + " Arrival " + ArrivalAirport+
                            " Duration : " + Duration + " Dept time : "+ DepartureTime+" Arr Time "+ ArrivalTime
                            +" Stops "+ Stops, Toast.LENGTH_LONG).show();



                }

                // Setup and Handover data to recyclerview

                final FlightAdapter adapter = new FlightAdapter(FlightListActivity.this, itemList);
                flights_rv.setAdapter(adapter);
                flights_rv.setLayoutManager(new LinearLayoutManager(FlightListActivity.this));
            }
            else{
                Toast.makeText(FlightListActivity.this,Config.POOR_NETWORK_CONNECTION, Toast.LENGTH_LONG).show();


            }
        }
        catch (JSONException r){
            System.out.println("ERROR PROB : "+  r);
            //  Toast.makeText(ListOfFlights.this,"ERROR PROB : "+ r,Toast.LENGTH_LONG).show();

        }

    }

在我的适配器中,我附加了布局,该布局将具有列表中数据的外观,并且我的 POJO 类 已设置为同时具有 getter 和 setter,但是当我尝试将 adapter 附加到 RecyclerView 时,数据没有绑定为什么?

编辑

我的适配器类

public class FlightAdapter  extends RecyclerView.Adapter<FlightHolder>  {


    private List<FlightModel> itemList= Collections.emptyList();
    private Context context;

    public FlightAdapter(Context context,List<FlightModel> itemList) {

        this.context = context;
        this.itemList = itemList;
    }

    @Override
    public FlightHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {

        View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.new_details, parent, false);
        FlightHolder rcv = new FlightHolder(layoutView, context);
        return rcv;
    }

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

        final FlightModel sr = itemList.get(position);
        final String DepartureAirport = sr.getDepartureAirport();
        final String ArrivalAirport = sr.getArrivalAirport();
        final String Duration = sr.getDuration();
        final String DepartureTime = sr.getDeparturTimee();
        final String ArrivalTime = sr.getArrivalTime();
        final String Stops = sr.getStops();
        final String DirectFlight = sr.getDirectFlights();

        holder.from_txt.setText(DepartureAirport);
        holder.to_txt.setText(ArrivalAirport);
        holder.duration_txt.setText(Duration);
        holder.depature_txt.setText(DepartureTime);
        holder.arrival_txt.setText(ArrivalTime);
        holder.stops_txt.setText(Stops);
        holder.dept_txt.setText(DepartureAirport);
        holder.arr_txt.setText(ArrivalAirport);


        holder.root.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
              //  Intent i = new Intent(FlightAdapter.this.context, DetailsLocalLeader.class);
              //  context.startActivity(i);


            }
        });


    }

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

}

有关更多信息,以下是该项目的链接: https://github.com/huxaiphaer/FlightsApp/blob/master/app/src/main/java/adapter/FlightAdapter.java

【问题讨论】:

标签: android json android-recyclerview


【解决方案1】:

首先,让某人检查您的代码结构。阅读并理解 Java 标准命名约定。为您的应用程序使用设计模式,可能是 MVP。使用 Gson 库为您解析 JSON 数据。

要回答您的问题,我会说您的 JSON 结构存在缺陷。您的代码输出此错误

错误问题:org.json.JSONException:org.json.JSONArray 类型的 Flight 中的值“SOME_LONG_JSON”无法转换为 JSONObject

这意味着您正在尝试将 JSONArray 解析为 JSONObject。在Schedule 数组中,有第 9 个条目应该是 JSONObject(如前 8 个条目所示)。但是,它是一个 JSONArray。

所以,前 8 个条目是这样的:

{
    "Departure": {},
    "Arrival": {},
    "MarketingCarrier": {},
    "Equipment": {},
    "Details": {}
}

而且,第 9 个条目是这样的:

[
    {
        "Departure": {},
        "Arrival": {},
        "MarketingCarrier": {},
        "Equipment": {},
        "Details": {}
    },
    {
        "Departure": {},
        "Arrival": {},
        "MarketingCarrier": {},
        "Equipment": {},
        "Details": {}
    }
]

这就是为什么你在 try-catch 块中得到这个解析异常的原因。所以,你可以这样做来检查你的对象是像parseJson(String result)这样的JSONArray还是JSONObject:

Object departureObject = arr.getJSONObject(i).getJSONObject("Flight").get("Departure");
if (departureObject instanceof JSONObject) {

    String departureAirport = ((JSONObject) departureObject).getString("Airport");
}
else if (departureObject instanceof JSONArray) {

    JSONArray departures = (JSONArray) departureObject;

    // use for-loop here to get data from array
}

但是,说真的,将 POJO 与 Gson 一起使用并简化解析过程。此外,如果您可以控制 API 的工作方式,请尝试仅保留一种类型的对象。如果它应该是一个列表,最好是一个列表,即使没有项目或者有一个或多个。

试试这些东西,它可能会解决这个问题,但我对此表示怀疑。我认为你会面临更多的解析问题。完成后联系我。

另外,如果你尝试解析服务器接收到的所有 JSON,你会发现它甚至不完整。看your JSON data的结尾。

【讨论】:

  • 我也可以在 github 上提交 PR,但我认为你应该自己尝试。
  • @Lutaaya - Rupinderjeet 是正确的。问题是由于来自at的数据不一致。请检查对象是 JSONArray 还是 JSONObject。我已经修复它并且工作正常。分享您的电子邮件,我将发送工作代码。但是尝试将 POJO 与 Gson 一起使用并简化解析过程。
  • @rupinderjeet,服务器收到的 JSON 是完整的,Log.x 有限制,因此它不会记录完整的数据。只需将其设置为 textview 你会发现数据是完整的。
  • 谢谢你们所有人,你们确实是伟大的开发者
  • @Lutaaya - 我丢了一封电子邮件。谢谢。 - rupinderjeet - 没问题,
【解决方案2】:

为您的适配器尝试这样的事情:

public class FlightAdapter  extends RecyclerView.Adapter<FlightAdapter.MyViewHolder>  {

    private List<FlightModel> mItemList;
    private Context context;

    public class MyViewHolder extends RecyclerView.ViewHolder {
        //TODO: Add all your views and the types hear!
        Public TextView mTvName;

        public MyViewHolder(View v){
            super(v);
            //TODO: add here for each view in your row
            mTvName = (TextView)v.findViewById(R.id.tvName);
        }
    }


    public FlightAdapter(Context context,List<FlightModel> itemList) {
        this.context = context;
        this.mItemList = itemList;
    }


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


    @Override
    public void onBindViewHolder(FlightHolder holder, int position) {
        FlightModel model = mItemList.get(position);

        //TODO: Add for each view and data point!!
        String name = model.getName();
        holder.mTvName.setText(name);

        holder.layoutView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
              //  Intent i = new Intent(FlightAdapter.this.context, DetailsLocalLeader.class);
              //  context.startActivity(i);


            }
        });


    }

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

}

免责声明!

我是在文本编辑器中输入的,因此可能存在一些语法错误或拼写错误。如果您有任何问题,请告诉我。

【讨论】:

  • 你好@Barns,我不知道为什么它拒绝了我尝试了所有可能的方法,但它拒绝了
  • 什么被拒绝。错误在哪里?方法?上课?
  • 好吧,没有发生错误,但活动没有显示任何内容,这意味着 RecyclerView 未设置为数据,但如果您不介意并浏览该链接,我认为一切都是正确的
  • 令人惊讶的是,在我的代码中,我放置了一个 toast 以查看 JSON 数据是否可用,toast 显示数据可用
猜你喜欢
  • 1970-01-01
  • 2012-09-09
  • 2013-02-05
  • 2014-10-19
  • 2019-08-26
  • 2019-05-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多