I am working with YouTube Data API and fetching data using JSON Retrofit in RecyclerView. The data consists of list of videos from a channel which also includes live videos.
The URL for the channel is:
https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=UCJekW1Vj5fCVEGdye_mBN6Q&maxResults=50&order=date&key=[YOUR_API_KEY] .
I am trying to sort the data in RecyclerView in such a way that the live videos comes at the top of list and rest of the videos are sorted according to the date. The adapter for RecyclerView is as follows:
public class AdapterHome extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<VideoYT> videoList;
public
AdapterHome(Context context, List<VideoYT> videoList) {
this.context = context;
this.videoList = videoList;
}
class YoutubeHolder extends RecyclerView.ViewHolder {
ImageView thumbnail;
TextView judul, tanggal;
public YoutubeHolder(#NonNull View itemView) {
super(itemView);
thumbnail = itemView.findViewById(R.id.iv_thumbnail);
judul = itemView.findViewById(R.id.tv_judul);
tanggal = itemView.findViewById(R.id.tv_tglUpdate);
}
public void setData(final VideoYT data) {
final String getJudul = data.getSnippet().getTitle();
String getTgl = data.getSnippet().getPublishedAt();
String getThumb = data.getSnippet().getThumbnails().getMedium().getUrl();
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(context, YTPlayerActivity.class);
i.putExtra("video_id", data.getId().getVideoId());
i.putExtra("video_title", getJudul);
context.startActivity(i);
}
});
judul.setText(getJudul);
tanggal.setText(getTgl);
Picasso.get()
.load(getThumb)
// .placeholder(R.mipmap.ic_gujrati)
.fit()
.centerCrop()
.into(thumbnail, new Callback() {
#Override
public void onSuccess() {
Log.d(TAG, "Thumbnail berhasil ditampilkan");
}
#Override
public void onError(Exception e) {
Log.e(TAG, "Thumbnail error: ", e);
}
});
}
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.row_item_home, parent, false);
return new YoutubeHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
VideoYT videoYT = videoList.get(position);
YoutubeHolder yth = (YoutubeHolder) holder;
yth.setData(videoYT);
}
#Override
public int getItemCount() {
return videoList.size();
}
}
The default sorting order doesn't provide any option for this. Can somebody guide me is it possible or not?
The JSON data format for this search is as follows:
{
"kind": "youtube#searchResult",
"etag": "BARItyEvlwxiMQCYVni5-wa94N0",
"id": {
"kind": "youtube#video",
"videoId": "C51KWXknpd8"
},
"snippet": {
"publishedAt": "2020-10-23T11:33:46Z",
"channelId": "UCJekW1Vj5fCVEGdye_mBN6Q",
"title": "SAMAA News Live | Samaa TV Live | 24/7 Pakistan News Live Headlines, Bulletins & Press Conferences",
"description": "samaalive #pakistannewslive #livenews LIVE STREAM SAMAA TV 24/7 | live streaming on YouTube | Headlines , Bulletins, Special & Exclusive Coverage Stay ...",
"thumbnails": {
"default": {
"url": "https://i.ytimg.com/vi/C51KWXknpd8/default_live.jpg",
"width": 120,
"height": 90
},
"medium": {
"url": "https://i.ytimg.com/vi/C51KWXknpd8/mqdefault_live.jpg",
"width": 320,
"height": 180
},
"high": {
"url": "https://i.ytimg.com/vi/C51KWXknpd8/hqdefault_live.jpg",
"width": 480,
"height": 360
}
},
"channelTitle": "SAMAA TV",
**"liveBroadcastContent": "live",**
"publishTime": "2020-10-23T11:33:46Z"
}
},
{
"kind": "youtube#searchResult",
"etag": "3qQo96hAKuvzR1yqmOX2RRwm0fg",
"id": {
"kind": "youtube#video",
"videoId": "JSUmX2wgwwk"
},
"snippet": {
"publishedAt": "2020-10-23T11:20:53Z",
"channelId": "UCJekW1Vj5fCVEGdye_mBN6Q",
"title": "Samaa Headlines 4pm | Muhammad Zubair Jhoot bolne ke mahir hain - Shibili Faraz",
"description": "samaanewslive #breakingnews #pakistannewslive Stay up-to-date on the major news making headlines across Pakistan on SAMAA TV's top of the hour ...",
"thumbnails": {
"default": {
"url": "https://i.ytimg.com/vi/JSUmX2wgwwk/default.jpg",
"width": 120,
"height": 90
},
"medium": {
"url": "https://i.ytimg.com/vi/JSUmX2wgwwk/mqdefault.jpg",
"width": 320,
"height": 180
},
"high": {
"url": "https://i.ytimg.com/vi/JSUmX2wgwwk/hqdefault.jpg",
"width": 480,
"height": 360
}
},
"channelTitle": "SAMAA TV",
"liveBroadcastContent": "none",
"publishTime": "2020-10-23T11:20:53Z"
}
},
Your issue boils down to having a custom comparator for the VideoYT class (defined, for example, within the class AdapterHome itself):
public static Comparator<VideoYT> myComparator =
new Comparator<VideoYT>() {
#Override
public int compare(VideoYT a, VideoYT b) {
boolean aLive = a.getSnippet().getLiveBroadcastContent() == "live";
boolean bLive = b.getSnippet().getLiveBroadcastContent() == "live";
if (aLive == bLive)
return b.getSnippet().getPublishedAt().compareTo(
a.getSnippet().getPublishedAt());
else
return aLive ? -1 : +1;
}
};
Then using this comparator for sorting videoList in the constructor of AdapterHome:
public
AdapterHome(Context context, List<VideoYT> videoList) {
this.context = context;
Collections.sort(videoList, myComparator);
this.videoList = videoList;
}
Depending on a wider context of your program (which your sample code above doesn't show), you may also need (want?) to have videoList not modified within that constructor. Then, instead of sorting the videoList itself, make a copy of it and sort that copy:
public
AdapterHome(Context context, List<VideoYT> videoList) {
this.context = context;
this.videoList = new ArrayList<>(videoList);
Collections.sort(this.videoList, myComparator);
}
Related
I have to show my JSON response in a recycler view using card view with use of volley library .My JSON response is something like
{
"id": 87,
"parent_id": 0,
"shipping": {
"first_name": "JPbrajesh",
"last_name": "kumar",
},
"payment_method": "COD",
"line_items": [
{
"id": 16,
"name": "abc",
"price": 85
},
{
"id": 17,
"name": "zxc",
"price": 38
},
{
"id": 18,
"name": "asd",
"price": 136
}
],
"tax_lines": [],
"shipping_lines": [
{
"id": 19,
}
],
"fee_lines": [],
"_links": {
"self": [
{
"href": "https://example.com/wp-json/wc/v2/orders/87"
}
],
"collection": [
{
"href": "https://example.com/wp-json/wc/v2/orders"
}
]
}
}
`i have to show (Line_items) in a recycler view using volley Library.Please provide some related steps.Thankyou in advance for kind support.
You can first create a class LineItem as model for lineitems.
Then in the activity where you want the data to be used, create a list of line items and fill that list with data from you json object.
create a layout for that lineitem
create an adapter class
declare the adapter and pass it the list and then attach the adapter to the recyclerview.
Something like this:
ProductCategory class
package com.pesabay.pesabay;
/**
* Created by Valentin_Kavakure on 20-Jun-17.
*/
public class ProductCategory {
private int id,niveau,order,premier,nbrProduits;
private String name;
private String image;
public ProductCategory() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ProductCategory(int id) {
this.id = id;
}
public int getId() {
return id;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
}
Then the layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardElevation="6dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dp">
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="150dp"
app:srcCompat="#drawable/bluebg" />
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v7.widget.CardView>
The adapter:
public class CatGridAdapter extends RecyclerView.Adapter<CatGridAdapter.ViewHolder> {
private List<ProductCategory> categoryList;
private Context context;
private RecyclerViewClickListener recyclerViewClickListener;
public void setRecyclerViewClickListener(RecyclerViewClickListener recyclerViewClickListener) {
this.recyclerViewClickListener = recyclerViewClickListener;
}
public CatGridAdapter(List<ProductCategory> categoryList, Context context) {
this.categoryList = categoryList;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(context).inflate(R.layout.category_grid_layout,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.title.setText(categoryList.get(position).getName());
}
#Override
public int getItemCount() {
return categoryList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;TextView title;
public ViewHolder(final View itemView) {
super(itemView);
title=(TextView)itemView.findViewById(R.id.title);
imageView=(ImageView)itemView.findViewById(R.id.image);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (recyclerViewClickListener!=null) {
recyclerViewClickListener.recyclerViewItemClicked(v, getAdapterPosition());
}
}
});
}
}
}
And the in my activity:
recyclerView=(RecyclerView)findViewById(R.id.recycler_data);
categoryList=new ArrayList<>();
catGridAdapter=new CatGridAdapter(categoryList,CategoryGrid.this);
pg=(ProgressBar)findViewById(R.id.pg);
catGridAdapter.setRecyclerViewClickListener(new RecyclerViewClickListener() {
#Override
public void recyclerViewItemClicked(View view, int position) {
/* some code*/
});
gridLayoutManager=new GridLayoutManager(CategoryGrid.this,2);
recyclerView.setLayoutManager(gridLayoutManager);
recyclerView.setAdapter(catGridAdapter);
Volley is the library for request the information. When Volley succeed, you get this this JSON response. After that, you need to parse Line_items and pass them to the RecyclerView Adapter.
Hope it helps.
Hi Dear Developers,
I hope all of you doing great I am developing Android News app where I have used bottom navigation drawer combination with fragments. When I click each items json not displaying I have used Retrofit for network call.
below MainActivity.java file
public class MainActivity extends BottomBarHolderActivity implements AllJazeeraFragment.OnFragmentInteractionListener, BBCFragment.OnFragmentInteractionListener, CNNFragment.OnFragmentInteractionListener, CBCNewsFragment.OnFragmentInteractionListener {
// private ApiService apiService;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
NavigationPage page1 = new NavigationPage("AllJazeera", ContextCompat.getDrawable(this, R.drawable.alljazeera), AllJazeeraFragment.newInstance());
NavigationPage page2 = new NavigationPage("Support", ContextCompat.getDrawable(this, R.drawable.bbc_icon), CNNFragment.newInstance());
NavigationPage page3 = new NavigationPage("Billing", ContextCompat.getDrawable(this, R.drawable.cnn_icon), AllJazeeraFragment.newInstance());
NavigationPage page4 = new NavigationPage("Profile", ContextCompat.getDrawable(this, R.drawable.cbc_icon), CBCNewsFragment.newInstance());
List<NavigationPage> navigationPages = new ArrayList<>();
navigationPages.add(page1);
navigationPages.add(page2);
navigationPages.add(page3);
navigationPages.add(page4);
super.setupBottomBarHolderActivity(navigationPages);
}
public void onClicked() {
Toast.makeText(this, "Clicked!", Toast.LENGTH_SHORT).show();
}
}
below my AllJazeeraFragment class
where I have implemented network call using retrofit
public class AllJazeeraFragment extends Fragment {
public NewsAdapter adapter;
public Article articleList;
RecyclerView recyclerView;
private AllJazeeraFragment.OnFragmentInteractionListener listener;
public static AllJazeeraFragment newInstance() {
return new AllJazeeraFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.alljazeera_fragment, container, false);
NewsInterface apiService = NewsClient.getApiService();
Call <Article> call = apiService.getAllJazeera();
call.enqueue(new Callback <Article>() {
#Override
public void onResponse(Call <Article> call, Response <Article> response) {
articleList = response.body();
recyclerView = rootView.findViewById(R.id.recycler_view);
adapter = new NewsAdapter((List<Article>) articleList);
RecyclerView.LayoutManager eLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(eLayoutManager);
recyclerView.setAdapter(adapter);
}
#Override
public void onFailure(Call <Article> call, Throwable t) {
}
});
return rootView;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof AllJazeeraFragment.OnFragmentInteractionListener) {
listener = (AllJazeeraFragment.OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString() + " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
public interface OnFragmentInteractionListener {
}
}
below my alljazeera_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:id="#+id/recycler_view"
android:scrollbars="vertical"
android:layout_height="wrap_content"/>
</LinearLayout>
below my BBCFragment.java file
public class BBCFragment extends Fragment {
private OnFragmentInteractionListener listener;
Article articleList;
RecyclerView recyclerView;
NewsAdapter adapter;
public static BBCFragment newInstance() {
return new BBCFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.bbc_fragment, container, false);
NewsInterface apiService = NewsClient.getApiService();
Call <Article> call = apiService.getBBC();
call.enqueue(new Callback <Article>() {
#Override
public void onResponse(Call<Article> call, Response <Article> response) {
articleList = response.body();
recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
adapter = new NewsAdapter((List<Article>) articleList);
RecyclerView.LayoutManager eLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(eLayoutManager);
recyclerView.setAdapter(adapter);
}
#Override
public void onFailure(Call<Article> call, Throwable t) {
}
});
return rootView;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
listener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString() + " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
public interface OnFragmentInteractionListener {
}
}
below bbc_fragment.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:id="#+id/recycler_view"
android:scrollbars="vertical"
android:layout_height="wrap_content"/>
</LinearLayout>
below my interface where I am calling ending points
public interface NewsInterface {
#GET("v2/top-headlines?sources=al-jazeera-english&apiKey=a5cc70bd52c9436785557878f4aa49e1")
Call <Article> getAllJazeera();
#GET("v2/top-headlines?sources=cbc-news&apiKey=a5cc70bd52c9436785557878f4aa49e1")
Call <Article> getCbC();
#GET("v2/top-headlines?sources=bbc-news&apiKey=a5cc70bd52c9436785557878f4aa49e1")
Call <Article> getBBC();
#GET("v2/top-headlines?sources=cnn&apiKey=a5cc70bd52c9436785557878f4aa49e1")
Call <Article> getCNN();
}
below news client class
public class NewsClient {
public static final String BASE_URL = "https://newsapi.org/";
/**
* Get Retrofit Instance
*/
private static Retrofit getRetrofitInstance() {
return new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
/**
* Get API Service
*
* #return API Service
*/
public static NewsInterface getApiService() {
return getRetrofitInstance().create(NewsInterface.class);
}
}
below json response from api
{
"status": "ok",
"totalResults": 9,
"articles": [
{
"source": {
"id": "al-jazeera-english",
"name": "Al Jazeera English"
},
"author": "Al Jazeera",
"title": "Former Maldives leader Gayoom freed on bail a week after election",
"description": "Former president's release came a week after half-brother Abdulla Yameen lost the presidential election.",
"url": "http://www.aljazeera.com/news/2018/09/maldives-leader-gayoom-freed-bail-week-election-180930150231895.html",
"urlToImage": "https://www.aljazeera.com/mritems/Images/2018/9/30/367ab1ceb832482b9db0c4b22cadf2f5_18.jpg",
"publishedAt": "2018-09-30T16:48:00Z",
"content": "Former Maldives president Maumoon Abdul Gayoom has been released on bail a week after his estranged half-brother Abdulla Yameen was defeated in a presidential election. Gayoom, the Indian Ocean island nation's longest-serving leader, and his legislator son Fa… [+2862 chars]"
},
{
"source": {
"id": "al-jazeera-english",
"name": "Al Jazeera English"
},
"author": "Faras Ghani",
"title": "Why are humans killing 100 million sharks every year?",
"description": "Increasing consumption of shark fin soup and illegal fishing may lead to extinction of certain species, experts warn.",
"url": "http://www.aljazeera.com/news/2018/09/humans-killing-100-million-sharks-year-180923150037790.html",
"urlToImage": "https://www.aljazeera.com/mritems/Images/2018/9/23/1ebd7c07e6dc49b095a58fe7c849a872_18.jpg",
"publishedAt": "2018-09-30T14:02:00Z",
"content": "Humans kill an estimated 100 million sharks annually and experts have warned that certain species face extinction if the trend continues. Consumption of shark fin soup, primarily in China and Vietnam, is the biggest reason behind the massive figure, contribut… [+6786 chars]"
},
{
"source": {
"id": "al-jazeera-english",
"name": "Al Jazeera English"
},
"author": "Al Jazeera",
"title": "Real Madrid football club honours Palestine activist Ahed Tamimi",
"description": "Palestinian activist, who spent eight months in Israeli prison, is welcomed at Bernabeu stadium by the football club.",
"url": "http://www.aljazeera.com/news/2018/09/real-madrid-football-club-honours-palestine-activist-ahed-tamimi-180930100616622.html",
"urlToImage": "https://www.aljazeera.com/mritems/Images/2018/9/30/fa170d306f5d41a5bafbef373f20da1b_18.jpg",
"publishedAt": "2018-09-30T12:09:00Z",
"content": "Palestinian activist Ahed Tamimi, whose arrest last year drew international condemnation, has been honoured by Spanish football club Real Madrid after she was released from Israeli prison. The 17-year-old was arrested in December 2017 after a video of her sla… [+2066 chars]"
},
{
"source": {
"id": "al-jazeera-english",
"name": "Al Jazeera English"
},
"author": "Sheetal Dhir",
"title": "It's time to speak about the economic cost of sexual assault",
"description": "The Kavanaugh scandal is an opportunity to finally talk about the economic toll sexual assault takes on our society.",
"url": "http://www.aljazeera.com/indepth/opinion/time-speak-economic-cost-sexual-assault-180930071453246.html",
"urlToImage": "https://www.aljazeera.com/mritems/Images/2018/9/30/1cf27079db8745d0b2995f820445b739_18.jpg",
"publishedAt": "2018-09-30T11:45:00Z",
"content": "I recently did a straw poll of the women in my life and realised that I know more survivors of sexual assault than I do mothers. The national statistics are staggering - according to the National Sexual Violence Resource Center, \"one in three women in the US … [+9518 chars]"
},
{
"source": {
"id": "al-jazeera-english",
"name": "Al Jazeera English"
},
"author": "Anumeha Yadav",
"title": "In Jharkhand, a tribal assertion met with fierce police crackdown",
"description": "Authorities say they are legally acquiring land to be used for 'development' projects, but villagers tell another story.",
"url": "http://www.aljazeera.com/indepth/features/jharkhand-tribal-assertion-met-fierce-police-crackdown-180929223820429.html",
"urlToImage": "https://www.aljazeera.com/mritems/Images/2018/9/28/619b6054917b46e3ac4f6813f60fe3cd_18.jpg",
"publishedAt": "2018-09-30T07:41:00Z",
"content": "Jharkhand, India: It was dusk in Uduburu, the time that farmers usually return home after working in the paddy fields, but the hamlet in the eastern Indian state of Jharkhand was deserted. The village square was empty and the mud huts were locked. After darkn… [+13300 chars]"
},
{
"source": {
"id": "al-jazeera-english",
"name": "Al Jazeera English"
},
"author": "Shereena Qazi",
"title": "How Afghanistan fell in love with cricket",
"description": "Cricket was imported by Afghan refugees from Pakistan, banned by the Taliban and finally embraced by government.",
"url": "http://www.aljazeera.com/news/2018/09/afghanistan-fell-love-cricket-180928141048315.html",
"urlToImage": "https://www.aljazeera.com/mritems/Images/2018/9/28/f7c2ddb6514642a7bb60e29ea3b6a37c_18.jpg",
"publishedAt": "2018-09-30T06:47:00Z",
"content": "Afghanistan recently ended its 2018 Asia Cup journey in Dubai with a series of impressive performances, filling Afghans at home with joy. With victories against Sri Lanka and Bangladesh, a tie against India and a competitive effort against Pakistan, the team … [+5118 chars]"
},
{
"source": {
"id": "al-jazeera-english",
"name": "Al Jazeera English"
},
"author": "Al Jazeera",
"title": "Indonesia: Rescuers search for survivors after quake, tsunami",
"description": "Rescuers rushing to reach people trapped by the quake and tsunami that has killed over 400 people in Palu city alone.",
"url": "http://www.aljazeera.com/news/2018/09/indonesia-rescuers-search-survivors-quake-tsunami-180930052755793.html",
"urlToImage": "https://www.aljazeera.com/mritems/Images/2018/9/30/59c2bcfc48a046f78ae30a9548511fcc_18.jpg",
"publishedAt": "2018-09-30T06:44:00Z",
"content": "Rescue teams in Indonesia have struggled to reach communities devastated by a major earthquake and tsunami on Sulawesi island, with a toll of more than 400 killed expected to rise sharply as contact is restored with remote areas. Amid the levelled trees, over… [+3207 chars]"
},
{
"source": {
"id": "al-jazeera-english",
"name": "Al Jazeera English"
},
"author": "Charlotte Mitchell",
"title": "Six months to go until Brexit: All you need to know",
"description": "Will Brexit definitely happen? Is a trade deal expected? What will happen to migrants? How will the economy be affected?",
"url": "http://www.aljazeera.com/news/2018/09/months-brexit-180923173227311.html",
"urlToImage": "https://www.aljazeera.com/mritems/Images/2018/9/28/e45c2ba07b944276b369e3fe291bf21b_18.jpg",
"publishedAt": "2018-09-29T08:17:00Z",
"content": "Britain is due to leave the EU in six months' time, at 23:00 GMT on March 29, 2019. Here are five things to know: 1. Will Brexit definitely happen? The UK government remains committed to reaching an agreement with the EU before negotiations end in March, howe… [+9323 chars]"
},
{
"source": {
"id": "al-jazeera-english",
"name": "Al Jazeera English"
},
"author": "James Rippingale",
"title": "The toll of burying Grenfell's dead",
"description": "For those who cared for the living and the dead after the Grenfell Tower fire, the struggle for justice continues.",
"url": "http://www.aljazeera.com/indepth/features/toll-burying-grenfell-dead-180926072155075.html",
"urlToImage": "https://www.aljazeera.com/mritems/Images/2018/9/28/faafdfc4216b47bbb86282cf33fca7df_18.jpg",
"publishedAt": "2018-09-29T06:40:00Z",
"content": "\"I'd never heard of Grenfell before. I didn't think there were that many Muslims in Chelsea,\" exclaims Abu Mumin, 48, of Eden Care, a Muslim end-of-life support charity run from a compact, green and white-walled Whitechapel office. It's a frantic Monday and t… [+9655 chars]"
}
]
}
below my NewsAdapter class
public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.NewsViewHolder> {
private List<Article> articleList;
public NewsAdapter(List<Article> articleList) {
this.articleList = articleList;
}
#NonNull
#Override
public NewsViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.
from(viewGroup.getContext()).
inflate(R.layout.news_item, viewGroup, false);
return new NewsViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull NewsViewHolder newsViewHolder, int i) {
Article article = articleList.get(i);
newsViewHolder.articleAuthor.setText(article.getAuthor());
newsViewHolder.articleTitle.setText(article.getTitle());
newsViewHolder.articleDescription.setText(article.getDescription());
Picasso.get().load(article.getUrlToImage()).into(newsViewHolder.articleImage);
}
#Override
public int getItemCount() {
return articleList.size();
}
public final static class NewsViewHolder extends RecyclerView.ViewHolder {
// TextView articleAuthor, articleTitle, articleDescription, articleUrl;
// ImageView articleImage;
#BindView(R.id.article_Image)
ImageView articleImage;
#BindView(R.id.article_Author)
TextView articleAuthor;
#BindView(R.id.article_Title)
TextView articleTitle;
#BindView(R.id.article_Description)
TextView articleDescription;
#BindView(R.id.article_Url)
TextView articleUrl;
public NewsViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
below my Article model class
public class Article {
#SerializedName("source")
#Expose
private Source source;
#SerializedName("author")
#Expose
private String author;
#SerializedName("title")
#Expose
private String title;
#SerializedName("description")
#Expose
private String description;
#SerializedName("url")
#Expose
private String url;
#SerializedName("urlToImage")
#Expose
private String urlToImage;
#SerializedName("publishedAt")
#Expose
private String publishedAt;
#SerializedName("content")
#Expose
private String content;
public Source getSource() {
return source;
}
public void setSource(Source source) {
this.source = source;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrlToImage() {
return urlToImage;
}
public void setUrlToImage(String urlToImage) {
this.urlToImage = urlToImage;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
You have created your model class incorrectly, first of all you will need one more model class like this
ArticleResponse.java
public class ArticleResponse {
#SerializedName("status")
#Expose
private String status;
#SerializedName("totalResults")
#Expose
private Integer totalResults;
#SerializedName("articles")
#Expose
private List<Article> articles = null;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Integer getTotalResults() {
return totalResults;
}
public void setTotalResults(Integer totalResults) {
this.totalResults = totalResults;
}
public List<Article> getArticles() {
return articles;
}
public void setArticles(List<Article> articles) {
this.articles = articles;
}
}
Now change this public Article articleList; to this public
ArrayList<Article> articleList=new ArrayList();
Now change your network call like this
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.alljazeera_fragment, container, false);
NewsInterface apiService = NewsClient.getApiService();
Call <ArticleResponse> call = apiService.getAllJazeera();
call.enqueue(new Callback <ArticleResponse>() {
#Override
public void onResponse(Call <ArticleResponse> call, Response <ArticleResponse> response) {
articleList = new ArrayList<>(response.body().getArticles());
recyclerView = rootView.findViewById(R.id.recycler_view);
adapter = new NewsAdapter(articleList);
RecyclerView.LayoutManager eLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(eLayoutManager);
recyclerView.setAdapter(adapter);
}
#Override
public void onFailure(Call <ArticleResponse> call, Throwable t) {
}
});
return rootView;
}
Now change interface also like this
#GET("v2/top-headlines?sources=al-jazeera-english&apiKey=a5cc70bd52c9436785557878f4aa49e1")
Call <ArticleResponse> getAllJazeera();
#GET("v2/top-headlines?sources=cbc-news&apiKey=a5cc70bd52c9436785557878f4aa49e1")
Call <ArticleResponse> getCbC();
#GET("v2/top-headlines?sources=bbc-news&apiKey=a5cc70bd52c9436785557878f4aa49e1")
Call <ArticleResponse> getBBC();
#GET("v2/top-headlines?sources=cnn&apiKey=a5cc70bd52c9436785557878f4aa49e1")
Call <ArticleResponse> getCNN();
I see many issues with your code.
Your json has a list of articles. But your Call <Article> getAllJazeera() api returns a <Article> instead of <List<Article>>. In fact you should have a ArticleListResponse sort of model that contains a list of articles and other fields in your json such as
"status": "ok",
"totalResults": 9,
Another issue I see is that your retrofit success callback you are doing
adapter = new NewsAdapter((List<Article>) articleList);
even though articleList is not even List<Article>. You create an Article variable and try to cast it to a list.
You need to make all these changes and then your code might work.
In my app I have got some json data from url. I have deserialize those data in controller class. Now I want to show those image into recyclerview.This recyclerview will be shown in detail activity. I have devided the relative layout into two part. First half is for information and the second half is for a recyclerview. I tried with the follwing code. The problem is I am very new in android developing and I am not getting the correct logic of doing this. I have explained in detail below-
Here is my model class
public class NewsModel {
#Expose
private String id;
#Expose
private String title;
#Expose
private List<AppImage> appImages;
public List<AppImage> getAppImages() {
return appImages;
}
public void setAppImages(List<AppImage> appImages) {
this.appImages = appImages;
}
}
The AppImageClass is
public class AppImage {
#Expose
private String _id;
#Expose
private String alt;
#Expose
private String src;
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
public String getAlt() {
return alt;
}
public void setAlt(String alt) {
this.alt = alt;
}
public String getSrc() {
return src;
}
public void setSrc(String src) {
this.src = src;
}
}
The adapter class is
public class NewsImageAdapter extends RecyclerView.Adapter<NewsImageAdapter.ImageHolder> {
private Context context;
private List<NewsModel> imageObject;
public NewsImageAdapter(Context context, List<NewsModel> imageObject) {
this.context = context;
this.imageObject = imageObject;
}
#Override
public ImageHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.newsdetail_image_row,parent,false);
return new ImageHolder(view);
}
#Override
public void onBindViewHolder(ImageHolder holder, int position) {
final NewsModel currentImage=imageObject.get(position);
for (int i = 0; i < currentImage.getAppImages().size() ; i++)
{
AppImage appImage = currentImage.getAppImages().get(i);
Picasso.with(holder.itemView.getContext()).load(appImage.getSrc()).into( holder.images[i] ); }
Picasso.with(holder.itemView.getContext());
}
#Override
public int getItemCount() {
return imageObject.size();
}
public class ImageHolder extends RecyclerView.ViewHolder {
public ImageView images;
public ImageHolder(View itemView) {
super(itemView);
images= itemView.findViewById(R.id.news_image);
}
}
}
In Deatil activity
public class DetailNews extends AppCompatActivity {
private List<NewsModel> newsObject;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_detail);
setUpUIViews();
//newsObject=getAllImageList();
}
private void setUpUIViews() {
recyclerView = (RecyclerView)findViewById(R.id.image_list);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(DetailNews.this);
recyclerView.setLayoutManager(layoutManager);
adapter = new NewsImageAdapter(this,newsObject );
recyclerView.setAdapter(adapter);
}
private List<NewsImageModel> getAllImageList() {
//how to set image here?
return images;
}
The json data looks like this
[
{ "id": "5925280ec925a9a6dd5173bb",
"title": "Headline",
"appImages": [
{
"alt": "",
"src": "source1",
"_id": "12213"
},
{
"alt": "",
"src": "source2",
"_id": "fdgdg"
},
{
"alt": "",
"src": "source3",
"_id": "fdfdfdf"
},
{
"alt": "",
"src": "source4",
"_id": "599d9018daf57d002c100ffa"
},
{
"alt": "",
"src": "source5",
"_id": "f7879"
}
],
},
{ "id": "5925280ec925a9a6dd5173bb",
"title": "Headline",
"appImages": [
{
"alt": "",
"src": "source1",
"_id": "12213"
},
{
"alt": "",
"src": "source2",
"_id": "fdgdg"
},
{
"alt": "",
"src": "source3",
"_id": "fdfdfdf"
},
{
"alt": "",
"src": "source4",
"_id": "599d9018daf57d002c100ffa"
},
{
"alt": "",
"src": "source5",
"_id": "f7879"
}
],
},
]
You should use one "raw/item" for each image. You don't need use "Picasso" to load the images, you can use something like:
In your RecyclerView.Adapter
.
.
.
#Override
public void onBindViewHolder(ViewHolderCustom viewHolder, final int position) {
viewHolder.setImage("imageUrl");
}
static class ViewHolderCustom extends RecyclerView.ViewHolder{
private final ImageView imageViewPhotoUrl;
ViewHolderCustom(View v) {
super(v);
imageViewPhotoUrl = (ImageView) v.findViewById(R.id.iv_photo_url);
}
void setImage(String photo) {
if (photo != null && !photo.isEmpty())
new DownloadImageTask(imageViewPhotoUrl)
.execute(photo);
}
}
.
.
.
Your DownloadImageTask:
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
private ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urlDisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urlDisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
if (result != null)
bmImage.setImageBitmap(result);
}
}
I want to load data from server and show in my application (RecyclerView), for this job, when the application starts it shows 10 posts and when scrolling recyclerView show another post .
I write below codes but when get other 10 posts, not show loading layout! I want when get other 10 posts, first show loading layout then show other 10 posts!
For connect to internet I use Retrofit v2 and for custom Endless methos for recyclerView I use this class : EndLess Class
My Activity codes:
public class Category_page extends AppCompatActivity implements ConnectivityReceiver.ConnectivityReceiverListener {
private static final long RIPPLE_DURATION = 250;
private Toolbar toolbar;
private TextView toolbar_title;
private ImageView toolbar_menuImage;
private Button categoryCheckNet_button;
private RelativeLayout root;
private CategoryAdapter mAdapter;
private RecyclerView cat_recyclerView;
private LinearLayoutManager mLayoutManager;
private RelativeLayout loadLayout, checkNetLayout;
private String catTitle = "";
private Integer catID;
private Bundle bundle;
private int pageCount = 1;
private Context context;
private List<R_CatModel> models;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.category_page);
// Hide StatusBar color
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
// Initializing
context = Category_page.this;
toolbar = (Toolbar) findViewById(R.id.category_toolbar);
cat_recyclerView = (RecyclerView) findViewById(R.id.category_recycler);
toolbar_title = (TextView) toolbar.findViewById(R.id.toolbar_pages_title);
mLayoutManager = new LinearLayoutManager(this);
root = (RelativeLayout) findViewById(R.id.category_root);
loadLayout = (RelativeLayout) findViewById(R.id.category_empty_layout);
checkNetLayout = (RelativeLayout) findViewById(R.id.category_checkInternet_layout);
categoryCheckNet_button = (Button) checkNetLayout.findViewById(R.id.checkNet_button);
// Toolbar
setSupportActionBar(toolbar);
if (toolbar != null) {
getSupportActionBar().setTitle("");
}
// Receive Data
bundle = getIntent().getExtras();
catID = bundle.getInt("categoryID");
if (bundle != null) {
catTitle = bundle.getString("categoryTitle");
}
if (catTitle != null) {
toolbar_title.setText(catTitle);
}
// Load Data
loadData();
// Load Progress
loadLayout.setVisibility(View.VISIBLE);
// Menu
View guillotineMenu = LayoutInflater.from(this).inflate(R.layout.menu_layout, null);
root.addView(guillotineMenu);
toolbar_menuImage = (ImageView) toolbar.findViewById(R.id.toolbar_pages_logo);
new GuillotineAnimation.GuillotineBuilder(guillotineMenu, guillotineMenu.findViewById(R.id.menu_layout_image), toolbar_menuImage)
.setStartDelay(RIPPLE_DURATION)
.setActionBarViewForAnimation(toolbar)
.setClosedOnStart(true)
.build();
// RecyclerView
cat_recyclerView.setLayoutManager(mLayoutManager);
cat_recyclerView.setHasFixedSize(true);
cat_recyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(mLayoutManager) {
#Override
public void onLoadMore(int current_page) {
Retrofit_ApiInterface apiInterface = Retrofit_ApiClient.getClient().create(Retrofit_ApiInterface.class);
Call<R_CatModelResponse> call = apiInterface.getCatMoreResponse(catID, current_page);
call.enqueue(new Callback<R_CatModelResponse>() {
#Override
public void onResponse(Call<R_CatModelResponse> call, Response<R_CatModelResponse> response) {
if (response != null) {
mAdapter.addNewItem(response.body().getCat_posts());
//loadLayout.setVisibility(View.GONE);
} else {
//loadLayout.setVisibility(View.VISIBLE);
Toast.makeText(Category_page.this, "Error 2", Toast.LENGTH_SHORT).show();
TastyToast.makeText(context, "خطایی رخ داده است", TastyToast.LENGTH_LONG, TastyToast.ERROR);
}
}
#Override
public void onFailure(Call<R_CatModelResponse> call, Throwable t) {
}
});
}
});
}
private void loadData() {
boolean isConnected = ConnectivityReceiver.isConnected();
retrofitData(isConnected);
}
private void retrofitData(boolean isConnect) {
if (isConnect) {
Retrofit_ApiInterface apiInterface = Retrofit_ApiClient.getClient().create(Retrofit_ApiInterface.class);
Call<R_CatModelResponse> call = apiInterface.getCatResponse(catID);
call.enqueue(new Callback<R_CatModelResponse>() {
#Override
public void onResponse(Call<R_CatModelResponse> call, Response<R_CatModelResponse> response) {
if (response != null) {
models = response.body().getCat_posts();
mAdapter = new CategoryAdapter(context, cat_recyclerView, models);
cat_recyclerView.setAdapter(mAdapter);
loadLayout.setVisibility(View.GONE);
} else {
//loadLayout.setVisibility(View.VISIBLE);
Toast.makeText(Category_page.this, "Error 2", Toast.LENGTH_SHORT).show();
TastyToast.makeText(context, "خطایی رخ داده است", TastyToast.LENGTH_LONG, TastyToast.ERROR);
}
checkNetLayout.setVisibility(View.GONE);
}
#Override
public void onFailure(Call<R_CatModelResponse> call, Throwable t) {
//loadLayout.setVisibility(View.VISIBLE);
//TastyToast.makeText(context, "لطفا برنامه را مجددا باز کنید", TastyToast.LENGTH_LONG, TastyToast.ERROR);
Toast.makeText(Category_page.this, "Error 2", Toast.LENGTH_SHORT).show();
//Cat_EmptyLayout.setVisibility(View.VISIBLE);
Log.e("CatResponseError", "Error : " + t);
}
});
} else {
//loadLayout.setVisibility(View.GONE);
checkNetLayout.setVisibility(View.VISIBLE);
if (mAdapter != null) {
mAdapter.clear();
cat_recyclerView.setAdapter(mAdapter);
}
categoryCheckNet_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
loadData();
}
});
}
}
public void post_back(View view) {
onBackPressed();
}
#Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}
#Override
protected void onResume() {
super.onResume();
// register connection status listener
MyApplication.getInstance().setConnectivityListener(this);
}
#Override
public void onNetworkConnectionChanged(boolean isConnected) {
retrofitData(isConnected);
}
}
My Adapter codes:
public class CategoryAdapter extends RecyclerView.Adapter {
private List<R_CatModel> mDateSet;
private Context mContext;
private final int VIEW_ITEM = 1;
private final int VIEW_PROG = 0;
// The minimum amount of items to have below your current scroll position
// before loading more.
private int visibleThreshold = 10;
private int lastVisibleItem, totalItemCount;
private boolean loading;
private OnLoadMoreListener onLoadMoreListener;
public CategoryAdapter(Context context, RecyclerView recyclerView, List<R_CatModel> dataSet) {
this.mContext = context;
this.mDateSet = dataSet;
if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView
.getLayoutManager();
recyclerView
.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView,
int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
totalItemCount = linearLayoutManager.getItemCount();
lastVisibleItem = linearLayoutManager
.findLastVisibleItemPosition();
if (!loading
&& totalItemCount <= (lastVisibleItem + visibleThreshold)) {
// End has been reached
// Do something
if (onLoadMoreListener != null) {
onLoadMoreListener.onLoadMore();
}
loading = true;
}
}
});
}
}
#Override
public int getItemViewType(int position) {
return mDateSet.get(position) != null ? VIEW_ITEM : VIEW_PROG;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder vh;
if (viewType == VIEW_ITEM) {
View v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.post_card_layout, parent, false);
vh = new DataViewHolder(v);
} else {
View v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.progressbar_item, parent, false);
vh = new ProgressViewHolder(v);
}
return vh;
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof DataViewHolder) {
((DataViewHolder) holder).main_post_title.setText(Html.fromHtml(mDateSet.get(position).getTitle()));
Glide.with(mContext)
.load(mDateSet.get(position).getThumbnail_images().getMedium().getUrl())
.placeholder(R.drawable.post_image)
.crossFade()
.override(600, 350)
.into(((DataViewHolder) holder).main_post_image);
((DataViewHolder) holder).main_post_content.setText(Html.fromHtml(mDateSet.get(position).getContent()));
// Convert Date ////////
String date = mDateSet.get(position).getDate();
String[] parts = date.split(" ");
String datePart = parts[0];
String timePart = parts[1];
int year;
int month;
int day;
String[] dateParts = datePart.split("-");
year = Integer.parseInt(dateParts[0]);
month = Integer.parseInt(dateParts[1]);
day = Integer.parseInt(dateParts[2]);
JalaliCalendar.YearMonthDate georgianDate = new JalaliCalendar.YearMonthDate(year, month, day);
JalaliCalendar.YearMonthDate JalaliDate = JalaliCalendar.gregorianToJalali(georgianDate);
String jalaliDateTime = JalaliDate.toString();
((DataViewHolder) holder).main_dateTime.setText(jalaliDateTime);
////////////////////////
((DataViewHolder) holder).main_author.setText(Html.fromHtml(mDateSet.get(position).getCatAuthor().getAuthorName()));
((DataViewHolder) holder).main_author.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
R_CatModel model = mDateSet.get(position);
v.getContext().startActivity(new Intent(v.getContext(), Profile_page.class));
//.putExtra("author", model.getAuthor())
//.putExtra("authorID", model.getAuthorID())
//.putExtra("authorStatus", model.getAuthorStatus()));
}
});
((DataViewHolder) holder).main_category.setText(Html.fromHtml(String.valueOf(mDateSet.get(position).getCategories().get(0).getCatTitle())));
((DataViewHolder) holder).main_category.setTextColor(mContext.getResources().getColor(R.color.colorAccent));
((DataViewHolder) holder).main_post_image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int pos = holder.getPosition();
R_CatModel model = mDateSet.get(pos);
v.getContext().startActivity(new Intent(v.getContext(), PostShow_page.class)
.putExtra("title", model.getTitle())
.putExtra("image", model.getThumbnail())
.putExtra("content", model.getContent())
.putExtra("dateTime", model.getDate())
//.putExtra("author", model.getAuthor())
.putExtra("category", model.getTitle()));
}
});
} else {
((ProgressViewHolder) holder).progressBar.setVisibility(View.VISIBLE);
}
}
public void setLoaded() {
loading = false;
}
#Override
public int getItemCount() {
return mDateSet.size();
}
public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) {
this.onLoadMoreListener = onLoadMoreListener;
}
public void remove(int position) {
mDateSet.remove(position);
notifyItemRemoved(position);
}
public void clear() {
mDateSet.clear();
notifyDataSetChanged();
}
public void addNewItem(List<R_CatModel> newContent) {
int start = this.mDateSet.size();//contents is a List of your items initialize it your constructor
int end = newContent.size();
mDateSet.addAll(newContent);
notifyItemRangeInserted(start + 1, end);
}
public void add(List<R_CatModel> models) {
mDateSet.addAll(models);
notifyDataSetChanged();
}
public void update(List<R_CatModel> models) {
mDateSet.clear();
mDateSet.addAll(models);
notifyDataSetChanged();
}
public class DataViewHolder extends RecyclerView.ViewHolder {
private TextView main_post_title, main_post_content, main_dateTime, main_author, main_category;
private ImageView main_post_image;
public DataViewHolder(final View itemView) {
super(itemView);
main_post_title = (TextView) itemView.findViewById(R.id.post_content_title);
main_post_image = (ImageView) itemView.findViewById(R.id.post_picture_image);
main_post_content = (TextView) itemView.findViewById(R.id.post_content_text);
main_dateTime = (TextView) itemView.findViewById(R.id.post_date_text);
main_author = (TextView) itemView.findViewById(R.id.post_name_text);
main_category = (TextView) itemView.findViewById(R.id.post_category_text);
}
}
public static class ProgressViewHolder extends RecyclerView.ViewHolder {
public AVLoadingIndicatorView progressBar;
public ProgressViewHolder(View v) {
super(v);
progressBar = (AVLoadingIndicatorView) v.findViewById(R.id.avloadingIndicatorView);
}
}
}
My Json :
{
"status": "ok",
"count": 9,
"pages": 3,
"category": {
"id": 1,
"slug": "%d8%b3%d8%b1%da%af%d8%b1%d9%85%db%8c",
"title": "\u0633\u0631\u06af\u0631\u0645\u06cc",
"description": "\u062a\u0648\u06cc \u0627\u06cc\u0646 \u06a9\u0644\u0648\u0646\u06cc \u0647\u0645\u0647 \u0686\u06cc\u0632 \u0648\u0627\u0633\u0647 \u0633\u0631\u06af\u0631\u0645 \u0628\u0648\u062f\u0646 \u0647\u0633\u062a. \u067e\u0633 \u0628\u062f\u0648 \u0628\u0631\u0648 \u062a\u0648\u0634",
"parent": 0,
"post_count": 29
},
"posts": [{
"id": 85,
"type": "post",
"slug": "%d8%b9%d9%86%d9%88%d8%a7%d9%86-%d8%b3%d9%88%d9%85-%d8%a8%d8%b1%d8%a7%db%8c-%d8%b1%d9%81%d8%b1%d8%b4",
"url": "http:\/\/tellfa.com\/tafrihgah\/?p=85",
"status": "publish",
"title": "\u0639\u0646\u0648\u0627\u0646 \u0633\u0648\u0645 \u0628\u0631\u0627\u06cc \u0631\u0641\u0631\u0634",
"title_plain": "\u0639\u0646\u0648\u0627\u0646 \u0633\u0648\u0645 \u0628\u0631\u0627\u06cc \u0631\u0641\u0631\u0634",
"content": "<p>\u062f\u06cc\u06af\u0647 \u0639\u0635\u0628\u0627\u0646\u06cc \u0634\u062f\u0645\u060c \u0686\u0631\u0627 \u0631\u0641\u0631\u0634 \u0646\u0645\u06cc\u06a9\u0646\u0647! :#<\/p>\n",
"excerpt": "<p>\u062f\u06cc\u06af\u0647 \u0639\u0635\u0628\u0627\u0646\u06cc \u0634\u062f\u0645\u060c \u0686\u0631\u0627 \u0631\u0641\u0631\u0634 \u0646\u0645\u06cc\u06a9\u0646\u0647! :#<\/p>\n",
"date": "2016-04-20 15:02:26",
"modified": "2016-04-20 15:02:26",
"categories": [{
"id": 1,
"slug": "%d8%b3%d8%b1%da%af%d8%b1%d9%85%db%8c",
"title": "\u0633\u0631\u06af\u0631\u0645\u06cc",
"description": "\u062a\u0648\u06cc \u0627\u06cc\u0646 \u06a9\u0644\u0648\u0646\u06cc \u0647\u0645\u0647 \u0686\u06cc\u0632 \u0648\u0627\u0633\u0647 \u0633\u0631\u06af\u0631\u0645 \u0628\u0648\u062f\u0646 \u0647\u0633\u062a. \u067e\u0633 \u0628\u062f\u0648 \u0628\u0631\u0648 \u062a\u0648\u0634",
"parent": 0,
"post_count": 29
}],
"tags": [],
"author": {
"id": 1,
"slug": "tellfa",
"name": "\u0645\u062d\u0645\u062f",
"first_name": "",
"last_name": "",
"nickname": "\u0645\u062d\u0645\u062f",
"url": "http:\/\/codesaz.com",
"description": "\u0627\u06cc\u0646 \u0632\u0646\u062f\u06af\u06cc \u0646\u0627\u0645\u0647 \u0645\u0646 \u0627\u0633\u062a",
"avatar": "76"
},
"comments": [],
"attachments": [{
"id": 86,
"url": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024.jpg",
"slug": "wallpapersmania_vol119-024",
"title": "[WallpapersMania]_vol119-024",
"description": "",
"caption": "",
"parent": 85,
"mime_type": "image\/jpeg",
"images": {
"full": {
"url": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024.jpg",
"width": 1680,
"height": 1050
},
"thumbnail": {
"url": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024-150x150.jpg",
"width": 150,
"height": 150
},
"medium": {
"url": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024-300x188.jpg",
"width": 300,
"height": 188
},
"medium_large": {
"url": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024-768x480.jpg",
"width": 768,
"height": 480
}
}
}],
"comment_count": 0,
"comment_status": "open",
"thumbnail": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024-150x150.jpg",
"custom_fields": {},
"thumbnail_size": "thumbnail",
"thumbnail_images": {
"full": {
"url": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024.jpg",
"width": 1680,
"height": 1050
},
"thumbnail": {
"url": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024-150x150.jpg",
"width": 150,
"height": 150
},
"medium": {
"url": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024-300x188.jpg",
"width": 300,
"height": 188
},
"medium_large": {
"url": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024-768x480.jpg",
"width": 768,
"height": 480
}
}
}
How can I show loading layout when get other 10 posts?
create a layout for loadmore with the progressbar in activity layout and set its visibility to gone , now setVisibility of your loadMore layout to visible programmatically inside public void onLoadMore(int current_page) method and set it back to gone in the response of your webservice(in onResponse and onFailure methods)
load_more.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/load_more"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#AA000000"
android:gravity="center"
android:visibility="gone"
android:padding="5dp">
<ProgressBar
android:id="#+id/more_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/more_progress"
android:padding="5dp"
android:text="Loading results..."
android:textColor="#ffffff"
android:textSize="#dimen/medium_text_size" />
</RelativeLayout>
In your activity xml file include load_more like -
listing_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:background="#color/listing_background"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycleView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="#dimen/medium_text_size"
android:gravity="center"
android:id="#+id/noListFound"
android:textColor="#color/orange"
android:text="No List found Please click here to add a new one"
android:visibility="gone"
android:padding="#dimen/header_margin"/>
</RelativeLayout>
<include layout="#layout/load_more"/>
</LinearLayout>
BaseLoadMoreActivity.java
public abstract class BaseLoadMoreActivity extends Activity {
#BindView(R.id.recycleView)
RecyclerView recyclerView;
#BindView(R.id.load_more)
RelativeLayout loadMore;
private LinearLayoutManager ll;
private int page = 1;
private boolean isNoData = false;
private boolean isLoading = false;
private RecyclerView.OnScrollListener scrollListener = new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (dy > 0) //check for scroll down
{
int visibleItemCount = ll.getChildCount();
int totalItemCount = ll.getItemCount();
int pastVisiblesItems = ll.findFirstVisibleItemPosition();
if (!isLoading && !isNoData) {
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
loadMore.setVisibility(View.VISIBLE);
page++;
LoadMoreList();
isLoading = true;
}
}
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ll = new LinearLayoutManager(this);
ll.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(ll);
recyclerView.addOnScrollListener(scrollListener);
}
public abstract void LoadMoreList();
}
Now extends your category_page.java with BaseLoadMoreActivity and change code
#Override
public void LoadMoreList() {
boolean isConnected = ConnectivityReceiver.isConnected();
retrofitData(isConnected);
}
private void retrofitData(boolean isConnect) {
if (isConnect) {
Retrofit_ApiInterface apiInterface = Retrofit_ApiClient.getClient().create(Retrofit_ApiInterface.class);
Call<R_CatModelResponse> call = apiInterface.getCatResponse(catID);
call.enqueue(new Callback<R_CatModelResponse>() {
#Override
public void onResponse(Call<R_CatModelResponse> call, Response<R_CatModelResponse> response) {
if (response != null) {
models = response.body().getCat_posts();
mAdapter = new CategoryAdapter(context, cat_recyclerView, models);
cat_recyclerView.setAdapter(mAdapter);
loadMore.setVisibility(View.GONE);
isLoading = false;
} else {
loadMore.setVisibility(View.GONE);
isLoading = false;
Toast.makeText(Category_page.this, "Error 2", Toast.LENGTH_SHORT).show();
TastyToast.makeText(context, "خطایی رخ داده است", TastyToast.LENGTH_LONG, TastyToast.ERROR);
}
checkNetLayout.setVisibility(View.GONE);
}
#Override
public void onFailure(Call<R_CatModelResponse> call, Throwable t) {
loadMore.setVisibility(View.GONE);
isLoading = false;
//TastyToast.makeText(context, "لطفا برنامه را مجددا باز کنید", TastyToast.LENGTH_LONG, TastyToast.ERROR);
Toast.makeText(Category_page.this, "Error 2", Toast.LENGTH_SHORT).show();
//Cat_EmptyLayout.setVisibility(View.VISIBLE);
Log.e("CatResponseError", "Error : " + t);
}
});
} else {
loadMore.setVisibility(View.GONE);
isLoading = false;
checkNetLayout.setVisibility(View.VISIBLE);
if (mAdapter != null) {
mAdapter.clear();
cat_recyclerView.setAdapter(mAdapter);
}
categoryCheckNet_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
loadData();
}
});
}
}
Please remove code of finding recycleView and setting layout manager of it from
category_page.java as we did it in BaseLoadMoreActivity otherwise code will not work.
I have just provided code for sample. Hope it will help you...
You didn't implement the getItemViewType and getItemCount correctly:
#Override
public int getItemViewType(int position) {
if (position < mDataSet.size()) {
return VIEW_ITEM;
}
return VIEW_PROG;
}
and
#Override
public int getItemCount() {
return mDateSet.size() + 1;
}
additionally replace the notifyItemRangeInserted(start + 1, end); with notifyDataSetChanged(); in addNewItem
EDIT
keep a boolean private boolean hasMore = true in your adapter and edit the getItemCount() like this:
#Override
public int getItemCount() {
if (hasMore)
return mDateSet.size() + 1;
else
return mDataSet.size();
}
You'll have two cases:
1. If you know from your previous response that there aren't anymore items you can load, set your hasMore = false .
2. If you don't know that, then in your Activity when you get the response in onLoadMore if response== null || response.body() == null || response.body().getCat_posts().size() == 0 set hasMore = false.
It all depends on the response you get from the server
Edit
in your adapter add a method
public void setHasMore(boolean hasMore) {
this.hasMore = hasMore;
}
in the onLoadMore
call.enqueue(new Callback<R_CatModelResponse>() {
#Override
public void onResponse(Call<R_CatModelResponse> call, Response<R_CatModelResponse> response) {
if (response != null) {
adapter.setHasMore(response.body().getPages() !=current_page+1)
mAdapter.addNewItem(response.body().getCat_posts());
//loadLayout.setVisibility(View.GONE);
} else {
//loadLayout.setVisibility(View.VISIBLE);
Toast.makeText(Category_page.this, "Error 2", Toast.LENGTH_SHORT).show();
TastyToast.makeText(context, "خطایی رخ داده است", TastyToast.LENGTH_LONG, TastyToast.ERROR);
}
}
#Override
public void onFailure(Call<R_CatModelResponse> call, Throwable t) {
}
});
I want load data from server and show into my application (RecyclerView), for this job when start application i show 10 posts and when scrolling recyclerView show another posts . I write below codes but when get 10 posts not load other posts!
My Json :
{
"status": "ok",
"count": 9,
"pages": 3,
"category": {
"id": 1,
"slug": "%d8%b3%d8%b1%da%af%d8%b1%d9%85%db%8c",
"title": "\u0633\u0631\u06af\u0631\u0645\u06cc",
"description": "\u062a\u0648\u06cc \u0627\u06cc\u0646 \u06a9\u0644\u0648\u0646\u06cc \u0647\u0645\u0647 \u0686\u06cc\u0632 \u0648\u0627\u0633\u0647 \u0633\u0631\u06af\u0631\u0645 \u0628\u0648\u062f\u0646 \u0647\u0633\u062a. \u067e\u0633 \u0628\u062f\u0648 \u0628\u0631\u0648 \u062a\u0648\u0634",
"parent": 0,
"post_count": 29
},
"posts": [{
"id": 85,
"type": "post",
"slug": "%d8%b9%d9%86%d9%88%d8%a7%d9%86-%d8%b3%d9%88%d9%85-%d8%a8%d8%b1%d8%a7%db%8c-%d8%b1%d9%81%d8%b1%d8%b4",
"url": "http:\/\/tellfa.com\/tafrihgah\/?p=85",
"status": "publish",
"title": "\u0639\u0646\u0648\u0627\u0646 \u0633\u0648\u0645 \u0628\u0631\u0627\u06cc \u0631\u0641\u0631\u0634",
"title_plain": "\u0639\u0646\u0648\u0627\u0646 \u0633\u0648\u0645 \u0628\u0631\u0627\u06cc \u0631\u0641\u0631\u0634",
"content": "<p>\u062f\u06cc\u06af\u0647 \u0639\u0635\u0628\u0627\u0646\u06cc \u0634\u062f\u0645\u060c \u0686\u0631\u0627 \u0631\u0641\u0631\u0634 \u0646\u0645\u06cc\u06a9\u0646\u0647! :#<\/p>\n",
"excerpt": "<p>\u062f\u06cc\u06af\u0647 \u0639\u0635\u0628\u0627\u0646\u06cc \u0634\u062f\u0645\u060c \u0686\u0631\u0627 \u0631\u0641\u0631\u0634 \u0646\u0645\u06cc\u06a9\u0646\u0647! :#<\/p>\n",
"date": "2016-04-20 15:02:26",
"modified": "2016-04-20 15:02:26",
"categories": [{
"id": 1,
"slug": "%d8%b3%d8%b1%da%af%d8%b1%d9%85%db%8c",
"title": "\u0633\u0631\u06af\u0631\u0645\u06cc",
"description": "\u062a\u0648\u06cc \u0627\u06cc\u0646 \u06a9\u0644\u0648\u0646\u06cc \u0647\u0645\u0647 \u0686\u06cc\u0632 \u0648\u0627\u0633\u0647 \u0633\u0631\u06af\u0631\u0645 \u0628\u0648\u062f\u0646 \u0647\u0633\u062a. \u067e\u0633 \u0628\u062f\u0648 \u0628\u0631\u0648 \u062a\u0648\u0634",
"parent": 0,
"post_count": 29
}],
"tags": [],
"author": {
"id": 1,
"slug": "tellfa",
"name": "\u0645\u062d\u0645\u062f",
"first_name": "",
"last_name": "",
"nickname": "\u0645\u062d\u0645\u062f",
"url": "http:\/\/codesaz.com",
"description": "\u0627\u06cc\u0646 \u0632\u0646\u062f\u06af\u06cc \u0646\u0627\u0645\u0647 \u0645\u0646 \u0627\u0633\u062a",
"avatar": "76"
},
"comments": [],
"attachments": [{
"id": 86,
"url": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024.jpg",
"slug": "wallpapersmania_vol119-024",
"title": "[WallpapersMania]_vol119-024",
"description": "",
"caption": "",
"parent": 85,
"mime_type": "image\/jpeg",
"images": {
"full": {
"url": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024.jpg",
"width": 1680,
"height": 1050
},
"thumbnail": {
"url": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024-150x150.jpg",
"width": 150,
"height": 150
},
"medium": {
"url": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024-300x188.jpg",
"width": 300,
"height": 188
},
"medium_large": {
"url": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024-768x480.jpg",
"width": 768,
"height": 480
}
}
}],
"comment_count": 0,
"comment_status": "open",
"thumbnail": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024-150x150.jpg",
"custom_fields": {},
"thumbnail_size": "thumbnail",
"thumbnail_images": {
"full": {
"url": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024.jpg",
"width": 1680,
"height": 1050
},
"thumbnail": {
"url": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024-150x150.jpg",
"width": 150,
"height": 150
},
"medium": {
"url": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024-300x188.jpg",
"width": 300,
"height": 188
},
"medium_large": {
"url": "http:\/\/tellfa.com\/tafrihgah\/wp-content\/uploads\/2016\/04\/WallpapersMania_vol119-024-768x480.jpg",
"width": 768,
"height": 480
}
}
}
Api Interface codes:
public interface Retrofit_ApiInterface {
// For load more category
#GET("?json=get_category_posts")
Call<R_CatModelResponse> getCatMoreResponse(#Query("id") Integer id, #Query("page") Integer page);
}
Adapter codes:
public class CategoryAdapter extends RecyclerView.Adapter {
private List<R_CatModel> mDateSet;
private Context mContext;
private final int VIEW_ITEM = 1;
private final int VIEW_PROG = 0;
// The minimum amount of items to have below your current scroll position
// before loading more.
private int visibleThreshold = 10;
private int lastVisibleItem, totalItemCount;
private boolean loading;
private OnLoadMoreListener onLoadMoreListener;
public CategoryAdapter(Context context, RecyclerView recyclerView, List<R_CatModel> dataSet) {
this.mContext = context;
this.mDateSet = dataSet;
if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView
.getLayoutManager();
recyclerView
.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView,
int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
totalItemCount = linearLayoutManager.getItemCount();
lastVisibleItem = linearLayoutManager
.findLastVisibleItemPosition();
if (!loading
&& totalItemCount <= (lastVisibleItem + visibleThreshold)) {
// End has been reached
// Do something
if (onLoadMoreListener != null) {
onLoadMoreListener.onLoadMore();
}
loading = true;
}
}
});
}
}
#Override
public int getItemViewType(int position) {
return mDateSet.get(position) != null ? VIEW_ITEM : VIEW_PROG;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder vh;
if (viewType == VIEW_ITEM) {
View v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.post_card_layout, parent, false);
vh = new DataViewHolder(v);
} else {
View v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.progressbar_item, parent, false);
vh = new ProgressViewHolder(v);
}
return vh;
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof DataViewHolder) {
((DataViewHolder) holder).main_post_title.setText(Html.fromHtml(mDateSet.get(position).getTitle()));
Glide.with(mContext)
.load(mDateSet.get(position).getThumbnail_images().getMedium().getUrl())
.placeholder(R.drawable.post_image)
.crossFade()
.override(600, 350)
.into(((DataViewHolder) holder).main_post_image);
((DataViewHolder) holder).main_post_content.setText(Html.fromHtml(mDateSet.get(position).getContent()));
// Convert Date ////////
String date = mDateSet.get(position).getDate();
String[] parts = date.split(" ");
String datePart = parts[0];
String timePart = parts[1];
int year;
int month;
int day;
String[] dateParts = datePart.split("-");
year = Integer.parseInt(dateParts[0]);
month = Integer.parseInt(dateParts[1]);
day = Integer.parseInt(dateParts[2]);
JalaliCalendar.YearMonthDate georgianDate = new JalaliCalendar.YearMonthDate(year, month, day);
JalaliCalendar.YearMonthDate JalaliDate = JalaliCalendar.gregorianToJalali(georgianDate);
String jalaliDateTime = JalaliDate.toString();
((DataViewHolder) holder).main_dateTime.setText(jalaliDateTime);
////////////////////////
((DataViewHolder) holder).main_author.setText(Html.fromHtml(mDateSet.get(position).getCatAuthor().getAuthorName()));
((DataViewHolder) holder).main_author.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
R_CatModel model = mDateSet.get(position);
v.getContext().startActivity(new Intent(v.getContext(), Profile_page.class));
//.putExtra("author", model.getAuthor())
//.putExtra("authorID", model.getAuthorID())
//.putExtra("authorStatus", model.getAuthorStatus()));
}
});
((DataViewHolder) holder).main_category.setText(Html.fromHtml(String.valueOf(mDateSet.get(position).getCategories().get(0).getCatTitle())));
((DataViewHolder) holder).main_category.setTextColor(mContext.getResources().getColor(R.color.colorAccent));
((DataViewHolder) holder).main_post_image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int pos = holder.getPosition();
R_CatModel model = mDateSet.get(pos);
v.getContext().startActivity(new Intent(v.getContext(), PostShow_page.class)
.putExtra("title", model.getTitle())
.putExtra("image", model.getThumbnail())
.putExtra("content", model.getContent())
.putExtra("dateTime", model.getDate())
//.putExtra("author", model.getAuthor())
.putExtra("category", model.getTitle()));
}
});
} else {
((ProgressViewHolder) holder).progressBar.setVisibility(View.VISIBLE);
}
}
public void setLoaded() {
loading = false;
}
#Override
public int getItemCount() {
return mDateSet.size();
}
public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) {
this.onLoadMoreListener = onLoadMoreListener;
}
public void remove(int position) {
mDateSet.remove(position);
notifyItemRemoved(position);
}
public void clear() {
mDateSet.clear();
notifyDataSetChanged();
}
public void add(List<R_CatModel> models) {
mDateSet.addAll(models);
notifyDataSetChanged();
}
public void update(List<R_CatModel> models) {
mDateSet.clear();
mDateSet.addAll(models);
notifyDataSetChanged();
}
public class DataViewHolder extends RecyclerView.ViewHolder {
private TextView main_post_title, main_post_content, main_dateTime, main_author, main_category;
private ImageView main_post_image;
public DataViewHolder(final View itemView) {
super(itemView);
main_post_title = (TextView) itemView.findViewById(R.id.post_content_title);
main_post_image = (ImageView) itemView.findViewById(R.id.post_picture_image);
main_post_content = (TextView) itemView.findViewById(R.id.post_content_text);
main_dateTime = (TextView) itemView.findViewById(R.id.post_date_text);
main_author = (TextView) itemView.findViewById(R.id.post_name_text);
main_category = (TextView) itemView.findViewById(R.id.post_category_text);
}
}
public static class ProgressViewHolder extends RecyclerView.ViewHolder {
public AVLoadingIndicatorView progressBar;
public ProgressViewHolder(View v) {
super(v);
progressBar = (AVLoadingIndicatorView) v.findViewById(R.id.avloadingIndicatorView);
}
}
}
Activity and Retrofit codes:
public class Category_page extends AppCompatActivity implements ConnectivityReceiver.ConnectivityReceiverListener {
private static final long RIPPLE_DURATION = 250;
private Toolbar toolbar;
private TextView toolbar_title;
private ImageView toolbar_menuImage;
private Button categoryCheckNet_button;
private RelativeLayout root;
private CategoryAdapter mAdapter;
private RecyclerView cat_recyclerView;
private LinearLayoutManager mLayoutManager;
private RelativeLayout loadLayout, checkNetLayout;
private String catTitle = "";
private Integer catID;
private Bundle bundle;
private int pageCount = 1;
private Context context;
private List<R_CatModel> models;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.category_page);
// Hide StatusBar color
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
// Initializing
context = Category_page.this;
toolbar = (Toolbar) findViewById(R.id.category_toolbar);
cat_recyclerView = (RecyclerView) findViewById(R.id.category_recycler);
toolbar_title = (TextView) toolbar.findViewById(R.id.toolbar_pages_title);
mLayoutManager = new LinearLayoutManager(this);
root = (RelativeLayout) findViewById(R.id.category_root);
loadLayout = (RelativeLayout) findViewById(R.id.category_empty_layout);
checkNetLayout = (RelativeLayout) findViewById(R.id.category_checkInternet_layout);
categoryCheckNet_button = (Button) checkNetLayout.findViewById(R.id.checkNet_button);
// Toolbar
setSupportActionBar(toolbar);
if (toolbar != null) {
getSupportActionBar().setTitle("");
}
// Receive Data
bundle = getIntent().getExtras();
catID = bundle.getInt("categoryID");
if (bundle != null) {
catTitle = bundle.getString("categoryTitle");
}
if (catTitle != null) {
toolbar_title.setText(catTitle);
}
// Load Data
loadData();
// Load Progress
loadLayout.setVisibility(View.VISIBLE);
// Menu
View guillotineMenu = LayoutInflater.from(this).inflate(R.layout.menu_layout, null);
root.addView(guillotineMenu);
toolbar_menuImage = (ImageView) toolbar.findViewById(R.id.toolbar_pages_logo);
new GuillotineAnimation.GuillotineBuilder(guillotineMenu, guillotineMenu.findViewById(R.id.menu_layout_image), toolbar_menuImage)
.setStartDelay(RIPPLE_DURATION)
.setActionBarViewForAnimation(toolbar)
.setClosedOnStart(true)
.build();
// RecyclerView
cat_recyclerView.setLayoutManager(mLayoutManager);
cat_recyclerView.setHasFixedSize(true);
// Load More data
if (mAdapter != null) {
mAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {
#Override
public void onLoadMore() {
models.add(null);
mAdapter.notifyItemInserted(models.size() - 1);
retrofitMoreData();
}
});
}
}
private void loadData() {
boolean isConnected = ConnectivityReceiver.isConnected();
retrofitData(isConnected);
}
private void retrofitData(boolean isConnect) {
if (isConnect) {
Retrofit_ApiInterface apiInterface = Retrofit_ApiClient.getClient().create(Retrofit_ApiInterface.class);
Call<R_CatModelResponse> call = apiInterface.getCatResponse(catID);
call.enqueue(new Callback<R_CatModelResponse>() {
#Override
public void onResponse(Call<R_CatModelResponse> call, Response<R_CatModelResponse> response) {
if (response != null) {
models = response.body().getCat_posts();
mAdapter = new CategoryAdapter(context, cat_recyclerView, models);
cat_recyclerView.setAdapter(mAdapter);
loadLayout.setVisibility(View.GONE);
} else {
//loadLayout.setVisibility(View.VISIBLE);
Toast.makeText(Category_page.this, "Error 2", Toast.LENGTH_SHORT).show();
TastyToast.makeText(context, "خطایی رخ داده است", TastyToast.LENGTH_LONG, TastyToast.ERROR);
}
checkNetLayout.setVisibility(View.GONE);
}
#Override
public void onFailure(Call<R_CatModelResponse> call, Throwable t) {
//loadLayout.setVisibility(View.VISIBLE);
//TastyToast.makeText(context, "لطفا برنامه را مجددا باز کنید", TastyToast.LENGTH_LONG, TastyToast.ERROR);
Toast.makeText(Category_page.this, "Error 2", Toast.LENGTH_SHORT).show();
//Cat_EmptyLayout.setVisibility(View.VISIBLE);
Log.e("CatResponseError", "Error : " + t);
}
});
} else {
//loadLayout.setVisibility(View.GONE);
checkNetLayout.setVisibility(View.VISIBLE);
if (mAdapter != null) {
mAdapter.clear();
cat_recyclerView.setAdapter(mAdapter);
}
categoryCheckNet_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
loadData();
}
});
}
}
public void retrofitMoreData() {
if (models.size() > 0) {
mAdapter.remove(models.size() - 1);
mAdapter.notifyItemRemoved(models.size());
mAdapter.setLoaded();
}
mAdapter.add(models);
mAdapter.notifyDataSetChanged();
pageCount++;
Retrofit_ApiInterface apiInterface = Retrofit_ApiClient.getClient().create(Retrofit_ApiInterface.class);
Call<R_CatModelResponse> call = apiInterface.getCatMoreResponse(catID, pageCount);
call.enqueue(new Callback<R_CatModelResponse>() {
#Override
public void onResponse(Call<R_CatModelResponse> call, Response<R_CatModelResponse> response) {
if (response != null) {
models = response.body().getCat_posts();
mAdapter = new CategoryAdapter(context, cat_recyclerView, models);
cat_recyclerView.setAdapter(mAdapter);
//loadLayout.setVisibility(View.GONE);
} else {
//loadLayout.setVisibility(View.VISIBLE);
Toast.makeText(Category_page.this, "Error 2", Toast.LENGTH_SHORT).show();
TastyToast.makeText(context, "خطایی رخ داده است", TastyToast.LENGTH_LONG, TastyToast.ERROR);
}
}
#Override
public void onFailure(Call<R_CatModelResponse> call, Throwable t) {
}
});
}
How can i edit my above codes for set lazyLoader ? Please Help me, I really need thi. Thanks all <3
Update : Why does not anyone help me? :(
For loading page ten by ten in Retrofit following structure would be helpful:
1- First of all I recommend use this to make your request cleaner.
2- Instead of implementing onScrollListener use EndlessRecyclerView it's much more better.
3- In onLoadMore(page) (assume using EndlessRecyclerView) call your webService something like bellow:
#Override
public void onLoadMore(int page) {
callWebservice(page);
}
4- In your onResponse add new Items to your adapter:
#Override
public void onResponse(Call<YOUR_OBJECT> call, Response<YOUR_OBJECT> response) {
adapter.addNewItem(response.body());
}
5- Your addNewItem in your Adapter would be like:
public void addNewItem(List<YOUR_OBJECT> newContent) {
int start = this.contents.size();//contents is a List of your items initialize it your constructor
int end = newContent.size();
contents.addAll(newContent);
notifyItemRangeInserted(start + 1, end);
}