-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
392 additions
and
13 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
107 changes: 107 additions & 0 deletions
107
app/src/main/java/com/sab99r/recyclerview_loadmore/MainActivity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,120 @@ | ||
package com.sab99r.recyclerview_loadmore; | ||
|
||
import android.content.Context; | ||
import android.support.v7.app.AppCompatActivity; | ||
import android.os.Bundle; | ||
import android.support.v7.widget.LinearLayoutManager; | ||
import android.support.v7.widget.RecyclerView; | ||
import android.util.Log; | ||
import android.widget.Toast; | ||
|
||
import com.sab99r.recyclerview_loadmore.network.MoviesApi; | ||
import com.sab99r.recyclerview_loadmore.network.ServiceGenerator; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import retrofit2.Call; | ||
import retrofit2.Callback; | ||
import retrofit2.Response; | ||
|
||
public class MainActivity extends AppCompatActivity { | ||
|
||
RecyclerView recyclerView; | ||
List<MovieModel> movies; | ||
MoviesAdapter adapter; | ||
MoviesApi api; | ||
String TAG = "MainActivity - "; | ||
Context context; | ||
|
||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
setContentView(R.layout.activity_main); | ||
context = this; | ||
recyclerView = (RecyclerView) findViewById(R.id.recycler_view); | ||
movies = new ArrayList<>(); | ||
|
||
adapter = new MoviesAdapter(this, movies); | ||
adapter.setLoadMoreListener(new MoviesAdapter.OnLoadMoreListener() { | ||
@Override | ||
public void onLoadMore() { | ||
|
||
recyclerView.post(new Runnable() { | ||
@Override | ||
public void run() { | ||
int index = movies.size() - 1; | ||
loadMore(index); | ||
} | ||
}); | ||
//Calling loadMore function in Runnable to fix the | ||
// java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling error | ||
} | ||
}); | ||
recyclerView.setHasFixedSize(true); | ||
recyclerView.setLayoutManager(new LinearLayoutManager(context)); | ||
recyclerView.addItemDecoration(new VerticalLineDecorator(2)); | ||
recyclerView.setAdapter(adapter); | ||
|
||
api = ServiceGenerator.createService(MoviesApi.class); | ||
load(0); | ||
} | ||
|
||
private void load(int index){ | ||
Call<List<MovieModel>> call = api.getMovies(index); | ||
call.enqueue(new Callback<List<MovieModel>>() { | ||
@Override | ||
public void onResponse(Call<List<MovieModel>> call, Response<List<MovieModel>> response) { | ||
if(response.isSuccessful()){ | ||
movies.addAll(response.body()); | ||
adapter.notifyDataChanged(); | ||
}else{ | ||
Log.e(TAG," Response Error "+String.valueOf(response.code())); | ||
} | ||
} | ||
|
||
@Override | ||
public void onFailure(Call<List<MovieModel>> call, Throwable t) { | ||
Log.e(TAG," Response Error "+t.getMessage()); | ||
} | ||
}); | ||
} | ||
|
||
private void loadMore(int index){ | ||
|
||
//add loading progress view | ||
movies.add(new MovieModel("load")); | ||
adapter.notifyItemInserted(movies.size()-1); | ||
|
||
Call<List<MovieModel>> call = api.getMovies(index); | ||
call.enqueue(new Callback<List<MovieModel>>() { | ||
@Override | ||
public void onResponse(Call<List<MovieModel>> call, Response<List<MovieModel>> response) { | ||
if(response.isSuccessful()){ | ||
|
||
//remove loading view | ||
movies.remove(movies.size()-1); | ||
|
||
List<MovieModel> result = response.body(); | ||
if(result.size()>0){ | ||
//add loaded data | ||
movies.addAll(result); | ||
}else{//result size 0 means there is no more data available at server | ||
adapter.setMoreDataAvailable(false); | ||
//telling adapter to stop calling load more as no more server data available | ||
Toast.makeText(context,"No More Data Available",Toast.LENGTH_LONG).show(); | ||
} | ||
adapter.notifyDataChanged(); | ||
//should call the custom method adapter.notifyDataChanged here to get the correct loading status | ||
}else{ | ||
Log.e(TAG," Load More Response Error "+String.valueOf(response.code())); | ||
} | ||
} | ||
|
||
@Override | ||
public void onFailure(Call<List<MovieModel>> call, Throwable t) { | ||
Log.e(TAG," Load More Response Error "+t.getMessage()); | ||
} | ||
}); | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
app/src/main/java/com/sab99r/recyclerview_loadmore/MovieModel.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.sab99r.recyclerview_loadmore; | ||
|
||
import java.io.Serializable; | ||
|
||
/** | ||
* Created by sab99r | ||
*/ | ||
public class MovieModel implements Serializable{ | ||
String title; | ||
String rating; | ||
String type; | ||
|
||
public MovieModel(String type) { | ||
this.type = type; | ||
} | ||
} |
117 changes: 117 additions & 0 deletions
117
app/src/main/java/com/sab99r/recyclerview_loadmore/MoviesAdapter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package com.sab99r.recyclerview_loadmore; | ||
|
||
import android.content.Context; | ||
import android.support.v7.widget.RecyclerView; | ||
import android.view.LayoutInflater; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
import android.widget.TextView; | ||
import java.util.List; | ||
|
||
/** | ||
* Created by sab99r | ||
*/ | ||
public class MoviesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { | ||
|
||
public final int TYPE_MOVIE = 0; | ||
public final int TYPE_LOAD = 1; | ||
|
||
static Context context; | ||
List<MovieModel> movies; | ||
OnLoadMoreListener loadMoreListener; | ||
boolean isLoading = false, isMoreDataAvailable = true; | ||
|
||
/* | ||
* isLoading - to set the remote loading and complete status to fix back to back load more call | ||
* isMoreDataAvailable - to set whether more data from server available or not. | ||
* It will prevent useless load more request even after all the server data loaded | ||
* */ | ||
|
||
|
||
public MoviesAdapter(Context context, List<MovieModel> movies) { | ||
this.context = context; | ||
this.movies = movies; | ||
} | ||
|
||
@Override | ||
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { | ||
LayoutInflater inflater = LayoutInflater.from(context); | ||
if(viewType==TYPE_MOVIE){ | ||
return new MovieHolder(inflater.inflate(R.layout.row_movie,parent,false)); | ||
}else{ | ||
return new LoadHolder(inflater.inflate(R.layout.row_load,parent,false)); | ||
} | ||
} | ||
|
||
@Override | ||
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { | ||
|
||
if(position>=getItemCount()-1 && isMoreDataAvailable && !isLoading && loadMoreListener!=null){ | ||
isLoading = true; | ||
loadMoreListener.onLoadMore(); | ||
} | ||
|
||
if(getItemViewType(position)==TYPE_MOVIE){ | ||
((MovieHolder)holder).bindData(movies.get(position)); | ||
} | ||
//No else part needed as load holder doesn't bind any data | ||
} | ||
|
||
@Override | ||
public int getItemViewType(int position) { | ||
if(movies.get(position).type.equals("movie")){ | ||
return TYPE_MOVIE; | ||
}else{ | ||
return TYPE_LOAD; | ||
} | ||
} | ||
|
||
@Override | ||
public int getItemCount() { | ||
return movies.size(); | ||
} | ||
|
||
/* VIEW HOLDERS */ | ||
|
||
static class MovieHolder extends RecyclerView.ViewHolder{ | ||
TextView tvTitle; | ||
TextView tvRating; | ||
public MovieHolder(View itemView) { | ||
super(itemView); | ||
tvTitle=(TextView)itemView.findViewById(R.id.title); | ||
tvRating=(TextView)itemView.findViewById(R.id.rating); | ||
} | ||
|
||
void bindData(MovieModel movieModel){ | ||
tvTitle.setText(movieModel.title); | ||
tvRating.setText("Rating "+movieModel.rating); | ||
} | ||
} | ||
|
||
static class LoadHolder extends RecyclerView.ViewHolder{ | ||
public LoadHolder(View itemView) { | ||
super(itemView); | ||
} | ||
} | ||
|
||
public void setMoreDataAvailable(boolean moreDataAvailable) { | ||
isMoreDataAvailable = moreDataAvailable; | ||
} | ||
|
||
/* notifyDataSetChanged is final method so we can't override it | ||
call adapter.notifyDataChanged(); after update the list | ||
*/ | ||
public void notifyDataChanged(){ | ||
notifyDataSetChanged(); | ||
isLoading = false; | ||
} | ||
|
||
|
||
interface OnLoadMoreListener{ | ||
void onLoadMore(); | ||
} | ||
|
||
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) { | ||
this.loadMoreListener = loadMoreListener; | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
app/src/main/java/com/sab99r/recyclerview_loadmore/VerticalLineDecorator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.sab99r.recyclerview_loadmore; | ||
|
||
import android.graphics.Rect; | ||
import android.support.v7.widget.RecyclerView; | ||
import android.view.View; | ||
|
||
/** | ||
* Created by sab99r | ||
*/ | ||
public class VerticalLineDecorator extends RecyclerView.ItemDecoration { | ||
private int space=0; | ||
|
||
public VerticalLineDecorator(int space) { | ||
this.space = space; | ||
} | ||
|
||
@Override | ||
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { | ||
|
||
if(parent.getChildAdapterPosition(view) == 0) | ||
outRect.top = space; | ||
|
||
outRect.bottom = space; | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
app/src/main/java/com/sab99r/recyclerview_loadmore/network/MoviesApi.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.sab99r.recyclerview_loadmore.network; | ||
|
||
import com.sab99r.recyclerview_loadmore.MovieModel; | ||
|
||
import java.util.List; | ||
import retrofit2.Call; | ||
import retrofit2.http.GET; | ||
import retrofit2.http.Query; | ||
/** | ||
* Created by sab99r | ||
*/ | ||
public interface MoviesApi { | ||
@GET("movies.php") | ||
Call<List<MovieModel>> getMovies(@Query("index") int index); | ||
} |
29 changes: 29 additions & 0 deletions
29
app/src/main/java/com/sab99r/recyclerview_loadmore/network/ServiceGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package com.sab99r.recyclerview_loadmore.network; | ||
|
||
import java.util.concurrent.TimeUnit; | ||
import okhttp3.OkHttpClient; | ||
import retrofit2.Retrofit; | ||
import retrofit2.converter.gson.GsonConverterFactory; | ||
/** | ||
* Created by sab99r | ||
*/ | ||
public class ServiceGenerator { | ||
|
||
public static <S> S createService(Class<S> serviceClass) { | ||
|
||
OkHttpClient httpClient=new OkHttpClient.Builder() | ||
.connectTimeout(30, TimeUnit.SECONDS) | ||
.readTimeout(30, TimeUnit.SECONDS) | ||
.writeTimeout(30, TimeUnit.SECONDS) | ||
.build(); | ||
|
||
Retrofit retrofit = new Retrofit.Builder() | ||
.baseUrl("http://www.sab99r.com/demos/api/") | ||
.addConverterFactory(GsonConverterFactory.create()) | ||
.client(httpClient).build(); | ||
|
||
return retrofit.create(serviceClass); | ||
|
||
} | ||
|
||
} |
Oops, something went wrong.