使用AsyncTaskLoader在recyclerview中显示JSON中的数据

时间:2017-06-06 22:16:24

标签: android json asynctaskloader

请我尝试在我的recyclerview中发布JSON数据。我正在使用AsyncTaskLoader,但屏幕上没有显示任何内容。 我已经从JSON记录了我需要的数据,以确认我得到了正确的解析,然后它们出现了。我还记录了要显示的对象数组,它们也显示在logcat中,它只是我的应用程序的屏幕,不显示任何数据。我正在使用带有2个片段的视图寻呼机,这两个问题都是一样的。 这是我的FragmentActivity,由于问题是相同的,我将只发布一个

public class TechNewsFragment extends Fragment {
private SwipeRefreshLayout mSwipeRefreshLayout;
private TextView mErrorMessage;
private NewsAdapter mNewsAdapter;
ArrayList<News> news;
NetworkInfo info;
//    The Loader takes in a bundle
Bundle sourceBundle = new Bundle();

private final String LOG_TAG = MainActivity.class.getSimpleName();

private static final String TECH_NEWS_QUERY_URL = "query";
private static final String TECH_NEWS_SOURCE = "techcrunch";
private static final int TECH_NEWS_LOADER = 22;

private RecyclerView mRecyclerView;


public TechNewsFragment() {
    // Required empty public constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_news, container, false);
    mErrorMessage = (TextView) view.findViewById(R.id.tv_error_message);
    mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view_main);
    mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeRefresh);

    mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));


    getActivity().getSupportLoaderManager().initLoader(TECH_NEWS_LOADER, null, new NewsDataLoader());

    mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            Log.v(LOG_TAG, "Refreshing");
            restartLoader();
            mSwipeRefreshLayout.setColorSchemeResources(
                    R.color.colorPrimary,
                    R.color.colorPrimaryDark);
        }
    });

    return view;
}

private boolean isConnected(){
    ConnectivityManager cm = (ConnectivityManager) getActivity()
            .getSystemService(CONNECTIVITY_SERVICE);

    info = cm.getActiveNetworkInfo();

    return info != null && info.isConnectedOrConnecting();
}

private int anyRandomInt(Random random) {
    return random.nextInt();
}

private void restartLoader() {
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            URL techNewsUrl = TechNetworkUtils.buildUrl(TECH_NEWS_SOURCE);
            sourceBundle.putString(TECH_NEWS_QUERY_URL, techNewsUrl.toString());

            Random random = new Random();
            int uniqueId = anyRandomInt(random); //Generates a new ID for each loader call;

//                    sourceBundle.putString("query", s);]

            LoaderManager loaderManager = getActivity().getSupportLoaderManager();

            if (loaderManager.getLoader(TECH_NEWS_LOADER) == null) {
                loaderManager.initLoader(uniqueId, sourceBundle, new NewsDataLoader());
            } else {
                loaderManager.restartLoader(TECH_NEWS_LOADER, sourceBundle, new
                        NewsDataLoader());
            }
        }
    }, 5000);
    mSwipeRefreshLayout.setRefreshing(false);
    Log.v(LOG_TAG, "Finished refreshing");
}

private void showErrorScreen(){
    mErrorMessage.setVisibility(View.VISIBLE);
    mRecyclerView.setVisibility(View.INVISIBLE);
    mErrorMessage.setText(getString(R.string.internet_error));
}

`public class NewsDataLoader implements LoaderManager.LoaderCallbacks<ArrayList<News>> {
    @Override
    public Loader<ArrayList<News>> onCreateLoader(int id, final Bundle args) {
        if (isConnected()){
            mErrorMessage.setVisibility(View.INVISIBLE);
            mRecyclerView.setVisibility(View.VISIBLE);
            return new AsyncTaskLoader<ArrayList<News>>(getActivity()) {
                ArrayList<News> mNewsData;

                @Override
                protected void onStartLoading() {
                    super.onStartLoading();
                    if (mNewsData != null){
                        deliverResult(mNewsData);
                    }else{
                        forceLoad();
                        mSwipeRefreshLayout.setRefreshing(true);
                    }
                }

                @Override
                public ArrayList<News> loadInBackground() {
                    try {
                        ArrayList<News> news = TechNetworkUtils.parseJSON(TECH_NEWS_SOURCE);
                        return news;
                    } catch (IOException e) {
                        e.printStackTrace();
                        return null;
                    }
                }

                public void deliverResult(ArrayList<News> data) {
                    mNewsData = data;
                    super.deliverResult(data);
                }
            };
        }else{
            showErrorScreen();
            return null;
        }
    }

    @Override
    public void onLoadFinished(Loader<ArrayList<News>> loader, ArrayList<News> data) {
        mSwipeRefreshLayout.setRefreshing(false);
        if (null == data) {
            showErrorScreen();
        } else {
            mErrorMessage.setVisibility(View.INVISIBLE);
            mRecyclerView.setVisibility(View.VISIBLE);
            if (news != null) {
//                    news.clear();
                news.addAll(data);
                mNewsAdapter = new NewsAdapter(news);
                mRecyclerView.setAdapter(mNewsAdapter);
                mNewsAdapter.notifyDataSetChanged();
            } else {
                news = data;
            }
            Log.i(LOG_TAG + "  this is the data", data.toString());        
// Array of objects shows in the log
        }
    }

    @Override
    public void onLoaderReset(Loader<ArrayList<News>> loader) {
//            loader.forceLoad();
    }

}

}`

这是我的适配器类

public class NewsAdapter extends 
RecyclerView.Adapter<NewsAdapter.NewsHolder> {

//    Variable used to reference the model
private ArrayList<News> mNews = new ArrayList<>();

//    NewsHolder class that extends the ViewHolder
public static class NewsHolder extends RecyclerView.ViewHolder{
    private TextView mNewsTextView;
    private TextView mTimeStampTextView;

//   Constructor to set the views
    public NewsHolder(View itemView){
        super(itemView);
        mNewsTextView = (TextView) itemView.findViewById(R.id.news_tv);
        mTimeStampTextView = (TextView) itemView.findViewById(R.id.time_tv);
    }
}

//    Constructor to set the adapter
public NewsAdapter(ArrayList<News> news){
    mNews = news;
}

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

@Override
public void onBindViewHolder(NewsHolder holder, int position) {
    holder.mNewsTextView.setText(mNews.get(position).getNews());
    holder.mTimeStampTextView.setText(mNews.get(position).getTime());
}

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

这是解析JSON并处理网络连接的类

public class TechNetworkUtils {

private static final String LOG_TAG = MainActivity.class.getSimpleName();

public static ArrayList<News> parseJSON(String source) throws IOException {
    URL url = buildUrl(source);
    String jsonResult = getResponseFromHttpUrl(url);

    ArrayList<News> news = new ArrayList<>();

    try{
        JSONObject jsonObject = new JSONObject(jsonResult);
        JSONArray jsonArray = jsonObject.getJSONArray("articles");

        if (jsonArray != null){
            for (int i = 0; i < jsonArray.length(); i++){
                JSONObject article = jsonArray.getJSONObject(i);
                String title = article.getString("title");
                String time = article.getString("publishedAt");
                news.add(new News(title, time));
                Log.i(LOG_TAG, title);
                Log.i(LOG_TAG, time);
            }
        }

    }catch (JSONException | NullPointerException e){
        e.printStackTrace();
        return null;
    }
    return news;
}

public static URL buildUrl(String techNewsSource){
    final String TECH_NEWS_BASE_URL = "https://newsapi.org/v1/articles";
    final String PARAM_SOURCE = "source";
    final String PARAM_SORT_BY = "sortBy";
    final String latest = "latest";
    final String PARAM_API_KEY = "apiKey";
    final String KEY = "3431d57e51a04c1d967e2eb96c99fd1a";

    Uri builtUri = Uri.parse(TECH_NEWS_BASE_URL).buildUpon()
            .appendQueryParameter(PARAM_SOURCE, techNewsSource)
            .appendQueryParameter(PARAM_SORT_BY, latest)
            .appendQueryParameter(PARAM_API_KEY, KEY)
            .build();

    Log.i(LOG_TAG, builtUri.toString());

    URL url = null;
    try{
        url = new URL(builtUri.toString());
    }catch (MalformedURLException e){
        e.printStackTrace();
    }
    return url;
}


public static String getResponseFromHttpUrl(URL url) throws IOException{
    HttpURLConnection urlConnection = null;
    String newsJsonStr = null;
    BufferedReader reader = null;

    try{
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setReadTimeout(15000);
        urlConnection.setConnectTimeout(10000);
        urlConnection.setRequestMethod("GET");
        urlConnection.setDoOutput(false);
        urlConnection.setDoInput(true);
        urlConnection.connect();

        InputStream inputStream = urlConnection.getInputStream();
        StringBuffer buffer = new StringBuffer();
        if(inputStream == null){
            return null;
        }

        reader = new BufferedReader(new InputStreamReader(inputStream));

        String line;
        while ((line = reader.readLine()) != null){
            buffer.append(line + "\n");
        }

        if (buffer.length() == 0){
            return null;
        }

        newsJsonStr = buffer.toString();

    }catch(IOException e){
        Log.e(LOG_TAG, "Error fetching data", e);
        return null;
    }finally{
        if (urlConnection != null){
            urlConnection.disconnect();
        }
        if (reader != null){
            try{
                reader.close();
            }catch (IOException e){
                Log.e(LOG_TAG, "Error closing stream", e);
            }
        }
    }
    return newsJsonStr;
}
}

这是我的pojo课程

public class News {
private String mNews;
private String mTime;

public News(String news, String time){
    mNews = news;
    mTime = time;
}

public String getNews() {
    return mNews;
}

public String getTime() {
    return mTime;
}
}`

这是我的list_item_layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">


<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/title_frame">

    <TextView
        android:padding="16dp"
        android:layout_width="match_parent"
        android:layout_height="64dp"
        android:id="@+id/news_tv"
        tools:text="Get exciting news here"/>

</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end">

    <TextView
        android:id="@+id/time_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingBottom="8dp"
        android:paddingRight="16dp"
        tools:text="12:00pm"/>
</FrameLayout>

</LinearLayout>

这是我的log.i

  /*  06-06 21:35:25.834 1092-1092/com.ire.blogbot E/dalvikvm: Could not 
 find 
class 'android.graphics.drawable.RippleDrawable', referenced from method 
android.support.v7.widget.AppCompatImageHelper.hasOverlappingRendering
06-06 21:35:25.834 1092-1092/com.ire.blogbot W/dalvikvm: VFY: unable to 
resolve instanceof 146 (Landroid/graphics/drawable/RippleDrawable;) in 
Landroid/support/v7/widget/AppCompatImageHelper;
06-06 21:35:25.922 1092-1106/com.ire.blogbot I/MainActivity: 
https://newsapi.org/v1/articles?source=entertainment-
weekly&sortBy=top&apiKey=3431d57e51a04c1d967e2eb96c99fd1a
06-06 21:35:25.934 1092-1107/com.ire.blogbot I/MainActivity: 
https://newsapi.org/v1/articles?
source=techcrunch&sortBy=latest&apiKey=3431d57e51a04c1d967e2eb96c99fd1a
06-06 21:35:26.042 1092-1092/com.ire.blogbot W/EGL_genymotion: 
eglSurfaceAttrib not implemented
06-06 21:35:26.226 376-423/system_process I/ActivityManager: Displayed 
com.ire.blogbot/.activity.MainActivity: +606ms
06-06 21:35:26.270 376-449/system_process I/qtaguid: Failed write_ctrl(s 0 
10021) res=-1 errno=1
06-06 21:35:26.270 376-449/system_process W/NetworkManagementSocketTagger: 
setKernelCountSet(10021, 0) failed with errno -1
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: How can tech 
companies treat their contractors better?
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: 2017-06-
06T21:19:28Z
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: Audi is the 
first to test autonomous vehicles in New York
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: 2017-06-
06T20:58:34Z
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: Bragi’s Dash 
Pro is a sophisticated and smart AirPods alternative
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: 2017-06-
06T20:05:41Z
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: As the Surface 
line courts creatives, Apple pushes back with the iMac and iPad Pro
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: 2017-06-
06T20:04:19Z
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: What Silicon 
Valley can learn from Lebanon’s women in tech
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: 2017-06-
06T20:00:53Z
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: Matt Mitchell 
of CryptoHarlem is building an open source tool to help organizations 
prepare for data breaches
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: 2017-06-
06T19:29:04Z
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: Pinterest 
raises $150M at a $12.3B valuation as it makes a full press into 
visual search
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: 2017-06-
06T19:27:05Z
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: Tulip, the app 
platform for manufacturers, picks up $13 million from NEA
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: 2017-06-
06T18:45:34Z
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: Take a look at 
these first pictures of Fisker’s $130K EMotion electric car
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: 2017-06-
06T18:27:57Z
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: iOS 11 will 
help you free up storage on your iPhone through personalized suggestions
06-06 21:35:27.182 1092-1107/com.ire.blogbot I/MainActivity: 2017-06-
06T18:22:33Z
06-06 21:35:27.182 1092-1092/com.ire.blogbot 
I/MainActivity  this is the data: [com.ire.blogbot.model.News@536e8250, 
com.ire.blogbot.model.News@536e65c0, com.ire.blogbot.model.News@536d157c, 
com.ire.blogbot.model.News@536e80ec, com.ire.blogbot.model.News@536e80f8, 
com.ire.blogbot.model.News@536e8104, com.ire.blogbot.model.News@536e8110, 
com.ire.blogbot.model.News@536e811c, com.ire.blogbot.model.News@536e8128, 
com.ire.blogbot.model.News@536e8134]
06-06 21:35:27.202 1092-1106/com.ire.blogbot I/MainActivity: 
{"status":"ok","source":"entertainment-weekly","sortBy":"top","articles":
[{"author":null,"title":"The Zodiac Killer: How a first-time filmmaker 
attempted to catch the serial 
murderer","description":null,"url":"http://zodiactruecrime.ew.com/","urlT
oImage":null,"publishedAt":null},{"author":"Maureen Lee Lenker","title":"Sam 
Smith teases return to the recording studio with
new photos","description":"","url":"http://ew.com/music/2017/06/06/sam-
smith-teases-new- 
album/","urlToImage":"http://i0.wp.com/ewedit.files.wordpress.com/2017/06/g
ettyimages-521740878.jpg?
 crop=0px%2C82px%2C2700px%2C1418px&resize=1200%2C630&ssl=1","publishedAt":"2
017-06-06T21:22:08Z"},{"author":"Marisa Marcellino","title":"Highest-
grossing 
Broadway shows of  
all time","description":"","url":"http://ew.com/theater/2017/06/06/highest-
grossing-broadway-shows-of-all-
 time/","urlToImage":"http://i1.wp.com/ewedit.files.wordpress.com/2017/03/li
onking.jpg?
 crop=0px%2C42px%2C2700px%2C1419px&resize=1200%2C630&ssl=1","publishedAt":"2
017-06-06T19:52:02Z"},{"author":"Kyle Fowle","title":"'House of Cards' 
Recap: 
How Far Is Claire Willing to Go to Secure the 
Presidency?","description":"With threats forming all around them, Frank and 
Claire take violent action to secure their 
legacy","url":"http://ew.com/recap/house-of-cards-season-5-episode-
 12/","urlToImage":"http://i0.wp.com/ewedit.files.wordpress.com/2017/06/hoc_
512_unit_01846r.jpg?
 crop=3px%2C105px%2C2699px%2C1418px&resize=1200%2C630&ssl=1","publishedAt":"
2017-06-06T19:49:12Z"},{"author":"Nivea Serrao","title":"Selena Gomez 
responds 
to ’13 Reasons Why’ controversy","description":"'This is happening every 
day'","url":"http://ew.com/tv/2017/06/06/selena-gomez-13-reasons-why-
controversy-
 2/","urlToImage":"http://i1.wp.com/ewedit.files.wordpress.com/2017/04/13rw_
113_01153r.jpg?
 crop=0px%2C53px%2C2700px%2C1418px&resize=1200%2C630&ssl=1","publishedAt":"2
017-06-06T19:45:59Z"},{"author":"Ruth Kinane","title":"‘Hollywood Game 
Night’ 
teaser: ‘This Is Us,’ ‘Veep,’ ‘Walking Dead’ casts ready 
for battle","description":"Jane Lynch returns to 
host","url":"http://ew.com/tv/2017/06/06/hollywood-game-night-teaser-this-
is-us-veep-walking-dead-
 casts/","urlToImage":"http://i1.wp.com/ewedit.files.wordpress.com/2017/06/h
ollywoodgame.jpg?
 crop=0px%2C21px%2C2700px%2C1419px&resize=1200%2C630&ssl=1","publishedAt":"2
017-06-06T19:30:49Z"},{"author":"Joey Nolfi","title":"Watch Jerry Seinfeld 
refuse a hug from Kesha","description":"\"I don't know who that was... I 
wish her the best,\" the 63-year-old 
said","url":"http://ew.com/news/2017/06/06/jerry-seinfeld-kesha-
 hug/","urlToImage":"http://i0.wp.com/ewedit.files.wordpress.com/2017/06/sei
nfeldkesha.jpg?
 crop=0px%2C13px%2C3200px%2C1681px&resize=1200%2C630&ssl=1","publishedAt":"2
017-06-06T19:05:57Z"},{"author":"Maureen Lee Lenker","title":"Tonys 2017: 
Watch 
performances from this year’s Best 
 Musical nominees","description":"","url":"http://ew.com/theater/2017/06/06/
tonys-2017-nominations-best-musical-
 performances/","urlToImage":"http://i2.wp.com/ewedit.files.wordpress.com/20
17/0
6/deh-ben-platt-4449-photo.jpg?
 crop=0px%2C382px%2C2700px%2C1419px&resize=1200%2C630&ssl=1","publishedAt":"
2017
-06-06T19:00:59Z"},{"author":"Ray Rahman","title":"‘Broad City’ returns 
under a ‘cloud of doom,’ stars tease","description":"Plus: RuPaul makes a 
'f---ing titillating' and 'godlike' 
cameo","url":"http://ew.com/tv/2017/06/06/broad-city-season-4-
 winter/","urlToImage":"http://i2.wp.com/ewedit.files.wordpress.com/2017/06/
broadcity.jpg?
 crop=0px%2C87px%2C2700px%2C1419px&resize=1200%2C630&ssl=1","publishedAt":"2
017-06-06T18:56:12Z"},{"author":"Nivea Serrao","title":"How ‘The Moth’
podcast 
turned storytelling into a 
 worldwide movement","description":"","url":"http://ew.com/podcasts/2017/06/
06/the-moth-podcast-20th-
 anniversary/","urlToImage":"http://i1.wp.com/ewedit.files.wordpress.com/201
7/06/gettyimages-530299778.jpg?
crop=0px%2C18px%2C1800px%2C945px&resize=1200%2C630","publishedAt":"2017-
06-06T18:48:15Z"}]}
06-06 21:35:33.406 376-386/system_process I/ActivityManager: No longer want 
com.android.exchange (pid 870): hidden #16
06-06 21:41:36.890 55-55/? W/Genyd: Can't parse request
06-06 21:41:36.958 376-466/system_process I/ClipboardService: Got clipboard 
for user=0
06-06 21:41:36.958 376-466/system_process I/ClipboardService: Got clipboard 
for user=0
06-06 21:41:36.958 376-389/system_process I/ClipboardService: Got clipboard 
for user=0
06-06 21:41:36.958 376-389/system_process I/ClipboardService: Got clipboard 
for user=0
06-06 21:41:36.958 376-389/system_process I/ClipboardService: Got clipboard 
for user=0
06-06 21:41:37.158 376-466/system_process I/ClipboardService: Got clipboard 
for user=0
06-06 21:41:37.158 376-466/system_process I/ClipboardService: Got clipboard 
for user=0
06-06 21:41:37.162 376-389/system_process I/ClipboardService: Got clipboard 
for user=0
06-06 21:41:37.162 376-389/system_process I/ClipboardService: Got clipboard 
for user=0
06-06 21:41:37.162 376-389/system_process I/ClipboardService: Got clipboard 
for user=0

我需要在启动应用程序时自动显示数据,并在调用onSwipeRefreshLayout时刷新。

1 个答案:

答案 0 :(得分:0)

我已经运行了你的项目而我没有收到你从logcat发布的错误,而是我在这行代码中得到了NullPointerException

String techNewsUrlString = args.getString(TECH_NEWS_QUERY_URL);

所以我将args替换为您的sourceBundle并修复了错误:

String techNewsUrlString = sourceBundle.getString(TECH_NEWS_QUERY_URL);

第二个问题出在您的fragment_news xml代码中。您的TextView占用了所有空间而Recyclerview没有空间,所以我做了一些更改:

  <?xml version="1.0" encoding="utf-8"?>
 <android.support.v4.widget.SwipeRefreshLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:id="@+id/swipeRefresh"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:paddingBottom="@dimen/activity_vertical_margin"
 android:paddingLeft="@dimen/activity_horizontal_margin"
 android:paddingRight="@dimen/activity_horizontal_margin"
 android:paddingTop="@dimen/activity_vertical_margin">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/tv_error_message"
    android:text="Oops! Couldn't connect to a network"
    android:gravity="center"
    android:layout_margin="32dp"
    android:textSize="16sp"
    android:fontFamily="monospace"
    android:visibility="invisible"/>
<android.support.v7.widget.RecyclerView
    android:id="@+id/recycler_view_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
 </RelativeLayout>
</android.support.v4.widget.SwipeRefreshLayout>

您的项目现在应该可以使用。