RecyclerView不会每次都正确显示数据

时间:2016-03-24 07:11:52

标签: android android-recyclerview recyclerview-layout

在recyclerview中,有时它会在第一次执行时显示输出,有时它会在第二次或第三次显示输出......最糟糕的是,有时它根本不显示任何数据。我从中获取数据的链接工作正常。有人能告诉我我在哪里犯错误。     我已经看到了关于这个问题的另一个答案,但对我没有用!

这是适配器代码

    private LayoutInflater inflater;
    Context context;
    List<Data> dataArray;

    public RecyclerViewAdapter(Context context, List<Data> dataArray) {
        this.dataArray = dataArray;
        this.context = context;
        inflater = LayoutInflater.from(context);
    }


    @Override
    public RecyclerViewAdapter.CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview, null);
        //View view = inflater.inflate(R.layout.cardview, parent, false);
        CustomViewHolder holder = new CustomViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(CustomViewHolder holder, int position) {
        Data current = dataArray.get(position);
        //holder.image.setImageResource(current.Limage);
        holder.textView1.setText(current.heading);
        holder.textView2.setText(current.date);
        holder.textView3.setText(current.brief);

    }

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

    public static class CustomViewHolder extends RecyclerView.ViewHolder {
        //ImageView image;
        TextView textView1, textView2, textView3;

        public CustomViewHolder(View itemView) {
            super(itemView);
            // image = (ImageView)itemView.findViewById(R.id.Limage);
            textView1 = (TextView) itemView.findViewById(R.id.heading);
            textView2 = (TextView) itemView.findViewById(R.id.date);
            textView3 = (TextView) itemView.findViewById(R.id.brief);


        }
    }

这是我的JSON课程

    Context context;
    public static List<Data> dataArray = new ArrayList<>();


    public JSONAsync(Context context) {
        this.context = context;
        dataArray.clear();

    }

    @Override
    protected Boolean doInBackground(String... params) {

        try {
            return downloadUrl(params[0]);
        } catch (IOException e) {
            return false;
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    public boolean downloadUrl(String myurl) throws IOException, JSONException {
        InputStream is = null;
        int response;

        try {
            URL url = new URL(myurl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.connect();
            response = conn.getResponseCode();
            is = conn.getInputStream();
            if (response == 200) {
                String responseBody = convertToString(conn.getInputStream());
                JSONArray jArray = new JSONArray(responseBody);

                //  JSONArray jArray = new JSONArray(is);
                for (int i = 0; i < jArray.length(); i++) {
                    JSONObject jobj = jArray.getJSONObject(i);
                    Data data = new Data();
                    data.setId(jobj.getInt("id"));
                    data.setHeading(jobj.getString("heading"));
                    data.setBrief(jobj.getString("brief"));
                    data.setDate(jobj.getString("date"));
                    dataArray.add(data);
                }
            recyclerViewAdapter.notifyDataSetChanged();
                return true;
            } else return false;

        } finally {
            if (is != null) {
                is.close();
            }
        }

    }

    public String convertToString(InputStream is) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line).append("\n");
            }
        } catch (IOException e) {
        } finally {
            try {
                is.close();
            } catch (IOException e) {
            }
        }

        return sb.toString();
    }

    @Override
    protected void onPostExecute(Boolean result) {

        if (result == false) {
            Toast.makeText(context, "Unable to fetch data from server", Toast.LENGTH_SHORT).show();
        }
    }

这是我正在显示数据的活动代码

    Toolbar toolbar;
    public RecyclerView recyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //overridePendingTransition(R.anim.fadein, R.anim.fadeout);
        setContentView(R.layout.activity_main_news);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        // Get Request
        String url = "MY URL NOT SHOWING HERE INTENTIONALLY";
        new JSONAsync(getApplicationContext()).execute(url);

        // Initializing the Recycler View and its layout
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter(MainNews.this, JSONAsync.dataArray);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(recyclerViewAdapter);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerViewAdapter.notifyDataSetChanged();
        //recyclerView.setHasFixedSize(true);
    }

这是我正在使用的XML布局

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/Relative"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFD4CBCB"
    tools:context="admin.myproject.MainNews">

    <include layout="@layout/toolbar" />

    <LinearLayout
        android:id="@+id/Linear1"
        style="@style/AlertDialog.AppCompat.Light"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/toolbar"
        android:orientation="vertical"
        android:layout_centerHorizontal="true">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:focusable="true"
            android:text="Main Section"
            android:textIsSelectable="true"
            android:textSize="30dp" />
    </LinearLayout>

    <View
        android:id="@+id/view"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_below="@id/Linear1"
        android:background="@android:color/darker_gray" />

    <android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/view" />

</RelativeLayout>

有几种活动使用相同的模式......有时候,它会显示所描述的数据,而另一些则显示数据。     任何帮助都将受到高度赞赏。

编辑: 在使用了recyclerViewAdapter.notifyDataSetChanged()后,我得到了NPE。有关如何获得此方法的rif的任何建议。

添加notifyDataSetChanged()后完成LogCat:

  

致命异常:AsyncTask#1                                                                    处理:admin.myproject,PID:27693                                                                    java.lang.RuntimeException:执行doInBackground()时发生错误                                                                        在android.os.AsyncTask $ 3.done(AsyncTask.java:309)                                                                        在java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)                                                                        at java.util.concurrent.FutureTask.setException(FutureTask.java:223)                                                                        在java.util.concurrent.FutureTask.run(FutureTask.java:242)                                                                        在android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:234)                                                                        在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)                                                                        at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:588)                                                                        在java.lang.Thread.run(Thread.java:818)                                                                     引发者:java.lang.NullPointerException:尝试在空对象引用上调用虚方法'void admin.myproject.RecyclerViewAdapter.notifyDataSetChanged()'                                                                        at admin.myproject.JSONAsync.downloadUrl(JSONAsync.java:76)                                                                        at admin.myproject.JSONAsync.doInBackground(JSONAsync.java:40)                                                                        at admin.myproject.JSONAsync.doInBackground(JSONAsync.java:23)                                                                        在android.os.AsyncTask $ 2.call(AsyncTask.java:295)                                                                        在java.util.concurrent.FutureTask.run(FutureTask.java:237)                                                                        在android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:234)                                                                        在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)                                                                        at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:588)                                                                        在java.lang.Thread.run(Thread.java:818)

2 个答案:

答案 0 :(得分:4)

将适配器设置为循环视图。

LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
RecycleViewAdapter adapter = new RecycleViewAdapter(list);
recycleView.setLayoutManager(layoutManager);
recycleView.setHasFixedSize(true);
recycleView.setAdapter(adapter);

然后在每次向dataArray或List use

添加值时,在Async任务中
adapter.notifyItemInserted(list.size());

在执行异步任务之前为循环视图设置适配器。

答案 1 :(得分:0)

当您从Json获取数据时,必须在AsyncTask的postExecute中设置适配器,使其看起来像

And here is my JSON class


Context context;
public static List<Data> dataArray = new ArrayList<>();


public JSONAsync(Context context) {
    this.context = context;
    dataArray.clear();

}

@Override
protected Boolean doInBackground(String... params) {

    try {
        return downloadUrl(params[0]);
    } catch (IOException e) {
        return false;
    } catch (JSONException e) {
        e.printStackTrace();
    }

    return null;
}

public boolean downloadUrl(String myurl) throws IOException, JSONException {
    InputStream is = null;
    int response;

    try {
        URL url = new URL(myurl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.connect();
        response = conn.getResponseCode();
        is = conn.getInputStream();
        if (response == 200) {
            String responseBody = convertToString(conn.getInputStream());
            JSONArray jArray = new JSONArray(responseBody);

            //  JSONArray jArray = new JSONArray(is);
            for (int i = 0; i < jArray.length(); i++) {
                JSONObject jobj = jArray.getJSONObject(i);
                Data data = new Data();
                data.setId(jobj.getInt("id"));
                data.setHeading(jobj.getString("heading"));
                data.setBrief(jobj.getString("brief"));
                data.setDate(jobj.getString("date"));
                dataArray.add(data);
            }
            return true;
        } else return false;

    } finally {
        if (is != null) {
            is.close();
        }
    }

}

public String convertToString(InputStream is) {
    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();
    String line = null;
    try {
        while ((line = reader.readLine()) != null) {
            sb.append(line).append("\n");
        }
    } catch (IOException e) {
    } finally {
        try {
            is.close();
        } catch (IOException e) {
        }
    }

    return sb.toString();
}

@Override
protected void onPostExecute(Boolean result) {

    if (result == false) {
        Toast.makeText(context, "Unable to fetch data from server", Toast.LENGTH_SHORT).show();
    }else{
    recyclerViewAdapter = new RecyclerViewAdapter(MainNews.this,     JSONAsync.dataArray);
    recyclerView.setAdapter(recyclerViewAdapter);
         }
}