I have an activity that lags (quite severely) when it's started. The lag usually lasts for under a second, but it's noticeable and I don't want it to be.
I'm not sure what's causing it to lag, but I need to fix it so that it's smooth as butter when it's loading.
Here is the activity:
public class ProfileActivity extends AppCompatActivity {
private CoordinatorLayout coordinatorLayout;
private RecyclerView recyclerView;
private LinearLayoutManager layoutManager;
private SwipeRefreshLayout swipeRefreshLayout;
private EndlessRecyclerViewScrollListener scrollListener;
private int userId;
private User user;
private List<Object> data = new ArrayList<>();
protected UserAdapter userAdapter;
private TextView username, userNumPosts;
private ImageView userBackground, userColor, userIcon;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
// Get userId from intent
userId = getIntent().getExtras().getInt("userId");
// Check if the user is in realm db
user = getRealm().where(User.class)
.equalTo("id", userId)
.findFirst();
// Make status bar black
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.parseColor("#000000"));
}
if (getSupportActionBar() != null) {
// Change toolbar color to the user's chosen color
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(Color.parseColor("#" + user.getColor())));
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
coordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinatorLayout);
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
swipeRefreshLayout.setRefreshing(true);
username = (TextView) findViewById(R.id.username);
userNumPosts = (TextView) findViewById(R.id.userNumPosts);
userBackground = (ImageView) findViewById(R.id.userBackground);
userColor = (ImageView) findViewById(R.id.userColor);
userIcon = (ImageView) findViewById(R.id.userIcon);
username.setText(user.getUsername());
userNumPosts.setText(user.getNumPosts());
userColor.setBackgroundColor(Color.parseColor("#" + user.getColor()));
// Add the user icon
Glide.with(this)
.load(user.getIcon())
.into(userIcon);
// Add the user background
Glide.with(this)
.load(user.getBackgroundImage())
.into(userBackground);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setNestedScrollingEnabled(false);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
userAdapter = new UserAdapter(this, data);
recyclerView.setAdapter(userAdapter);
userAdapter.setUserAdapterListener(new UserAdapter.UserAdapterListener() {
#Override
public void onRequestRefresh() {
swipeRefreshLayout.setRefreshing(true);
getUserData(1);
}
});
scrollListener = new EndlessRecyclerViewScrollListener(layoutManager) {
#Override
public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
getUserData(page);
}
};
recyclerView.addOnScrollListener(scrollListener);
getUserData(1);
}
public void getUserData(final int page) {
ApiInterface apiService = ApiClient.createService(ApiInterface.class, userAuthToken);
Call<BasicResponse> call = apiService.getUserData(userId, page);
call.enqueue(new Callback<BasicResponse>() {
#Override
public void onResponse(Call<BasicResponse> call, Response<BasicResponse> response) {
if (response.isSuccessful()) {
// Show the data
List<Message> messageData = response.body().getData();
data.addAll(messageData);
userAdapter.notifyDataSetChanged();
}
swipeRefreshLayout.setRefreshing(false);
}
#Override
public void onFailure(Call<BasicResponse> call, Throwable t) {
//
}
});
}
}
What could be causing my activity to lag when it's being loaded? Should I be putting all of my main code in onCreate()?
You have too much process in onCreate(). try to move some method to onResume(). In other words, you are blocking your UI with your data processing. Then, in layout, please minimized the use of nested layout. If the layout have to many children, the app will render it slower. Also consider designing/loading your UI before the data. This would allow your user to see something, even if its not complete.
P/s : Consider moving your Data/Process to an AsyncTask. or Thread
I have look for solution too, this is worked for me
overridePendingTransition(0,0);
before starting the lagging activity.
Related
In my app there is an activity that when it opens it should display data in a RecyclerView. The data is stored in a collection in Firestore but unfortunately it is only working for API 21, 22 and 23, everything above is not displaying the data (see screenshots). Also sometimes it is not showing the data on the first time the user opens the activity, only when he opens it a second time or logs out and in again (in API 21). Is this something that is known or is there something with my code? Or is there a better way to display the data of a collection in a RecyclerView?
I also noticed a strange behavior:
When I add an EditText to the layout without doing anything with it in the activity, when the user clicks on the EditText, the desired documents are then displayed as they should be. On the emulator running API 21, the data shows without having to click on the EditText, so the mentioned behavior applies for API greater 24. Can someone explain this behavior?
Any help is much appreciated!
I followed this tutorial where everything works fine:
https://www.youtube.com/watch?v=lAGI6jGS4vs
My app only targets API starting at 21.
Here is my activity with the RecyclerView:
public class PrizeGameActivity extends AppCompatActivity {
private Toolbar mToolbar;
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference prizesRef = db.collection("Prizes");
private PrizeGameAdapter prizeGameAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_prize_game);
// Sets the custom toolbar as ActionBar
mToolbar = findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
setUpRecyclerView();
}
private void setUpRecyclerView() {
Query query = prizesRef.orderBy("text",Query.Direction.ASCENDING);
FirestoreRecyclerOptions<Prizes> options = new FirestoreRecyclerOptions.Builder<Prizes>()
.setQuery(query, Prizes.class)
.build();
prizeGameAdapter = new PrizeGameAdapter(options);
RecyclerView recyclerView = findViewById(R.id.recycler_view_prize_game);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(prizeGameAdapter);
prizeGameAdapter.startListening();
}
#Override
protected void onStart() {
super.onStart();
if(prizeGameAdapter != null)
{
prizeGameAdapter.startListening();
}
}
#Override
protected void onStop() {
super.onStop();
if(prizeGameAdapter != null)
{
prizeGameAdapter.startListening();
}
}
// Makes a left to right animation when user clicks the back button of the toolbar
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return false;
}
// Makes a right left animation when clicking the back button
#Override
public void finish() {
super.finish();
overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
}
}
Here is my Adapter:
public class PrizeGameAdapter extends FirestoreRecyclerAdapter<Prizes, PrizeGameAdapter.PrizeGameHolder> {
public PrizeGameAdapter(#NonNull FirestoreRecyclerOptions<Prizes> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull PrizeGameHolder holder, int position, #NonNull Prizes model) {
holder.textViewPrizeGame.setText(model.getText());
}
#NonNull
#Override
public PrizeGameHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listitem_prize_game,parent, false);
return new PrizeGameHolder(view);
}
class PrizeGameHolder extends RecyclerView.ViewHolder {
TextView textViewPrizeGame;
public PrizeGameHolder(#NonNull View itemView) {
super(itemView);
textViewPrizeGame = itemView.findViewById(R.id.listitem_text_view_prize_game);
}
}
}
And here is my prizes class:
public class Prizes {
public Prizes (){
}
public String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Prizes(String text) {
this.text = text;
}
}
I managed to get the desired result by adding a OnCompleteListener and then set up the RecyclerView. Here is the code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_prize_game);
Query query = prizesRef.orderBy("text",Query.Direction.ASCENDING);
FirestoreRecyclerOptions<Prizes> options = new FirestoreRecyclerOptions.Builder<Prizes>()
.setQuery(query, Prizes.class)
.build();
prizeGameAdapter = new PrizeGameAdapter(options);
query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if(task.isSuccessful()){
setUpRecyclerView();
}else {
}
}
});
}
private void setUpRecyclerView() {
RecyclerView recyclerView = findViewById(R.id.recycler_view_prize_game);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(prizeGameAdapter);
prizeGameAdapter.startListening();
}
#Override
protected void onStart() {
super.onStart();
if(prizeGameAdapter != null)
{
prizeGameAdapter.startListening();
}
}
#Override
protected void onStop() {
super.onStop();
if(prizeGameAdapter != null)
{
prizeGameAdapter.startListening();
}
}
I am trying to make a layout with recyclerview something like the video. I made a recyclerview which update list after certain interval but the problem is after data update it scroll to top position automatically. I want to make something like the video. https://youtu.be/omcS-6LeKoo
I have tried with link from SO
RecyclerView scrolls to top position when change the adapter data RecyclerView notifyDataSetChanged scrolls to top position but unable to solve. below is my attempt
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerViewId);
handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Toast.makeText(getApplicationContext(),"Updating",Toast.LENGTH_LONG).show();
listShow();
handler.postDelayed(this,1000);
}
},1000);
}
void listShow(){
retrofitApiCall = RetrofitInstance.getRetrofitInstance().create(RetrofitApiCall.class);
Call<ModelClass_JSONParse> getDetails = retrofitApiCall;
anime = ExtendedAnime.getAll();
getDetails.enqueue(new Callback<ModelClass_JSONParse>() {
#Override
public void onResponse(Call<ModelClass_JSONParse> call,
Response<ModelClass_JSONParse> response) {
Log.v("Res",response.toString());
getWithValues = new HashMap<>();
if (response.isSuccessful()){
list.add(mModelClass_adapter);
}
adapter = new Adapter(getApplicationContext(),list);
StaggeredGridLayoutManager layoutManager = new
StaggeredGridLayoutManager(1,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
#Override
public void onFailure(Call<ModelClass_JSONParse> call, Throwable t) {
Log.v("Res",call.toString());
}
});
}
These lines of code are causing the problem for you. You're setting a new adapter reference and linear layout manager reference every time of your API calling.
adapter = new Adapter(getApplicationContext(),list);
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(1,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
To Do your desired task you need to do following steps -
Just set your LayoutManager and adapter for the first time.
Make a setDataList method in your adapter class. And set your updated list to adapter list.
And then every time of calling API set that list to setDataList and call adapter.notifyDataSetChanged() method of your adapter class.
The above steps will solve your problem. Just give it a try.
The problem is probably because of you are setting new adapter reference in network callback method onResponse(). Try setting adapter in onCreate and then update dataset in callback.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerViewId);
recyclerView.setAdapter(yourAdapter);
}
In network callback,
#Override
public void onResponse(Call<ModelClass_JSONParse> call,
Response<ModelClass_JSONParse> response) {
Log.v("Res",response.toString());
getWithValues = new HashMap<>();
if (response.isSuccessful()){
adapter.setDataSet(newDataList) //not change adapter reference,only update data set
}
}
Implement setDataSet() method in your adapter to update list like below.
class YourAdapter extends RecyclerView.Adapter<>{
priavate List<> list = new ArrayList();
public void setDataSet(newList:List<>){
list.clear();
list.addAll(newList);
notifyDataSetChanged();
}
}
Don't use adapter.notifyDataSetChanged(); method because I think your main view must be wrap content so either set a fixed height like 150dp.
Try different methods like notifyItemChanged(), notifyItemRangeChanged(), notifyItemInserted()
You are setting adapter again and again when the response is changing, so you should change list and set adapter in onCreate.
Arraylist<ModelClass_adapter> list = new Arraylist<ModelClass_adapter>;
Adapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerViewId);
//set adapter here
adapter = new Adapter(getApplicationContext(),list);
StaggeredGridLayoutManager layoutManager = new
StaggeredGridLayoutManager(1,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Toast.makeText(getApplicationContext(),"Updating",Toast.LENGTH_LONG).show();
listShow();
handler.postDelayed(this,1000);
}
},1000);
}
void listShow(){
retrofitApiCall = RetrofitInstance.getRetrofitInstance().create(RetrofitApiCall.class);
Call<ModelClass_JSONParse> getDetails = retrofitApiCall;
anime = ExtendedAnime.getAll();
getDetails.enqueue(new Callback<ModelClass_JSONParse>() {
#Override
public void onResponse(Call<ModelClass_JSONParse> call,
Response<ModelClass_JSONParse> response) {
Log.v("Res",response.toString());
getWithValues = new HashMap<>();
if (response.isSuccessful()){
list.clear();
list.add(mModelClass_adapter);
}
adapter.notifyDataSetChanged();
}
}
#Override
public void onFailure(Call<CurrencyModelClass_JSONParse> call, Throwable t) {
Log.v("Res",call.toString());
}
});
}
You are setting a new adapter every time and a new layout manager response comes.
which may cause this type of problem. you need to set adapter and layout manager in onCreate. just update adapter list in response of the api.
according to this answer you need linear layout manager only.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerViewId);
list= ArrayList<>();
adapter = new Adapter(getApplicationContext(),list);
LinearLayoutManager linearLayoutManager = new
LinearLayoutManager(context, OrientationHelper.VERTICAL, false);
recycleView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(adapter);
handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Toast.makeText(getApplicationContext(),"Updating",Toast.LENGTH_LONG).show();
listShow();
handler.postDelayed(this,1000);
}
},1000);
}
void listShow(){
retrofitApiCall = RetrofitInstance.getRetrofitInstance().create(RetrofitApiCall.class);
Call<ModelClass_JSONParse> getDetails = retrofitApiCall;
anime = ExtendedAnime.getAll();
getDetails.enqueue(new Callback<ModelClass_JSONParse>() {
#Override
public void onResponse(Call<ModelClass_JSONParse> call,
Response<ModelClass_JSONParse> response) {
Log.v("Res",response.toString());
getWithValues = new HashMap<>();
if (response.isSuccessful()){
adapter.getList().add(mModelClass_adapter);
}
adapter.notifyDataSetChanged();
}
}
#Override
public void onFailure(Call<CurrencyModelClass_JSONParse> call, Throwable t) {
Log.v("Res",call.toString());
}
});
}
you can do by following way
First get the count of your current datalist
int position = datalist.size();
after adding data into datalist
call DataAdapter.notifyDataSetChanged();
then move cursor to position in recyclerview
recyclerView.scrollToPosition(position);
Happy coding...!
I am going to make website app and load feed on my first page but the problem is the scrolling is endless, how to stop this? The scrolling is endless so I want to stop it.
public class FeedActivity extends AppCompatActivity
{
private SwipeRefreshLayout swipeLayout;
private RecyclerView listView;
private LinearLayoutManager layoutManager;
private FeedAdapter adapter;
private FeedService service;
private FeedModel model;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_feed);
ActionBar actionBar = getSupportActionBar();
if(null != actionBar)
{
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setIcon(R.mipmap.ic_launcher);
}
model = new FeedModel();
adapter = new FeedAdapter(model);
service = FeedService.create(model);
layoutManager = new LinearLayoutManager(this);
swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipeLayout);
listView = (RecyclerView) findViewById(R.id.listView);
listView.setLayoutManager(layoutManager);
listView.setAdapter(adapter);
}
#Override
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
}
#Override
protected void onStart()
{
super.onStart();
model.subscribe(onDataChangedListener);
adapter.setOnItemClickListener(onItemClickListener);
swipeLayout.setOnRefreshListener(onRefreshListener);
service.fetchOlder();
}
#Override
protected void onStop()
{
super.onStop();
model.unSubscribe(onDataChangedListener);
adapter.setOnItemClickListener(null);
swipeLayout.setOnRefreshListener(null);
}
FeedModel.OnDataChangedListener onDataChangedListener = new FeedModel.OnDataChangedListener()
{
#Override
public void onFetchedAndAddedToTop(int count)
{
swipeLayout.setRefreshing(false);
adapter.notifyDataSetChanged();
}
#Override
public void onFetchedAndAddedToBottom(int count)
{
if(count == 0)
{
adapter.setFooterEnabled(false);
}
adapter.notifyDataSetChanged();
}
};
SwipeRefreshLayout.OnRefreshListener onRefreshListener = new SwipeRefreshLayout.OnRefreshListener()
{
#Override
public void onRefresh()
{
service.fetchNewer();
}
};
FeedAdapter.OnItemClickListener onItemClickListener = new FeedAdapter.OnItemClickListener()
{
#Override
public void onItemClick(View view)
{
int position = listView.getChildAdapterPosition(view);
FeedItem item = model.get(position);
Intent intent = new Intent(getApplicationContext(), PostActivity.class);
intent.putExtra("id", item.getId());
startActivity(intent);
// System.out.println("Click: "+item.getTitle());
}
};
}
You can stop scrolling in two ways
If you know how many items are refreshing for every refresh you done then make a condition to stop calling refresh when you get less items than actual.
You can simply make a condition to stop refreshing list when you don't get data from earlier refresh.
Hope this Helpful..
#Rajesh
To stop endless scrolling apply a condition.
For example for every scroll 20 results are fetched and added to the list. Then you can apply a condition
if(lastFetchedItemCount!=0&&lastFetchedItemCount%20==0){
//enable scrolling
}
else{
//disable scrolling
}
I have almost same problem as stated in the below question, expect that I am using retrofit. I want the data to be passed into spaceDecorator method, so each time my settings changed or refreshed, extra space being added.
RecyclerView decorator adding extra padding on refresh
I tried all the solutions suggested above, but didn't work. Please suggested a way to handle this issue.
My code :
public class MainActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
public static final String top_rated = "http://api.themoviedb.org/3/movie/top_rated?api_key=1401a8cfe672a592a1a72b023d9febd7";
public static final String popular = "http://api.themoviedb.org/3/movie/popular?api_key=1401a8cfe672a592a1a72b023d9febd7";
public static final String baseUrl = "http://api.themoviedb.org/3/";
public static final String apiKEy = "1401a8cfe672a592a1a72b023d9febd7";
public static final String preUrl = "http://image.tmdb.org/t/p/w342";
public static List<MovieData> movieDataList;
private static SpaceDecorator spaceDecorator;
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar myToolbar = (Toolbar) findViewById(R.id.main_toolbar);
setSupportActionBar(myToolbar);
recyclerView = (RecyclerView)findViewById(R.id.main_recyclerview);
recyclerView.setHasFixedSize(true);
layoutManager = new GridLayoutManager(MainActivity.this,2);
recyclerView.setLayoutManager(layoutManager);
//use a layout manager, a grid layout manager with 2 columns in our case
updateJson();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.action_settings){
startActivity(new Intent(this, SettingsActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
private void updateJson(){
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setIndeterminate(true);
mProgressDialog.setMessage("Loading...");
mProgressDialog.show();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
final RequestInterface requestInterface = retrofit.create(RequestInterface.class);
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
String sort_by = sharedPreferences.getString("sort_by","popular");
Call<JsonMovieResponse> call = requestInterface.getTopRatedMovies(sort_by, apiKEy);
call.enqueue(new Callback<JsonMovieResponse>() {
#Override
public void onResponse(Call<JsonMovieResponse> call, Response<JsonMovieResponse> response) {
movieDataList = response.body().getResults();
adapter = new MainRecyclerViewAdapter(MainActivity.this, movieDataList);
recyclerView.setAdapter(adapter);
spaceDecorator = new SpaceDecorator(4,adapter.getItemCount());
recyclerView.addItemDecoration(spaceDecorator);
if(mProgressDialog.isShowing())
mProgressDialog.dismiss();
}
#Override
public void onFailure(Call<JsonMovieResponse> call, Throwable t) {
Log.e("retrofit error", t.toString());
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
PreferenceManager.getDefaultSharedPreferences(this).
unregisterOnSharedPreferenceChangeListener(this);
Log.i("main","destroy");
}
#Override
protected void onResume() {
super.onResume();
PreferenceManager.getDefaultSharedPreferences(this).
registerOnSharedPreferenceChangeListener(this);
Log.i("activity","main resume");
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
Log.i("main settings", "changed");
updateJson();
}
}
Consider your onResponse() method wehre you add your spaceDecorator as an item decoration. This method is additive, so for every update you're adding up spaces between item. Instead you have to remove the old spaceDecorator before adding a new one.
#Override
public void onResponse(Call<JsonMovieResponse> call, Response<JsonMovieResponse> response) {
movieDataList = response.body().getResults();
adapter = new MainRecyclerViewAdapter(MainActivity.this, movieDataList);
recyclerView.setAdapter(adapter);
if (spaceDecorator != null)
recyclerView.removeItemDecoration(spaceDecorator);
spaceDecorator = new SpaceDecorator(4,adapter.getItemCount());
recyclerView.addItemDecoration(spaceDecorator);
if(mProgressDialog.isShowing())
mProgressDialog.dismiss();
}
Please try to remove the itemDecoration before adding as shown below:
movieDataList = response.body().getResults();
adapter = new MainRecyclerViewAdapter(MainActivity.this, movieDataList);
recyclerView.setAdapter(adapter);
if(spaceDecorator != null){
recyclerView.removeItemDecoration(spaceDecorator);
}
spaceDecorator = new SpaceDecorator(4,adapter.getItemCount());
recyclerView.addItemDecoration(spaceDecorator);
if(mProgressDialog.isShowing())
mProgressDialog.dismiss();
Each time you call addItemDecoration method, onDraw in the itemDecoration class will be called. In that method if you are using each cell's layout params for adding space then on the first time it will be correct. On the subsequent call's on taking cell's layout params earlier added space will be there. So first remove the space and then add new space.
Hope this will help.
My app tries to get various information from an api call using Retrofit and Gson. This information needs to be displayed as a gridview and the gridview needs to repopulate on scrolling. As of now, I can get the first 10 items, and thats it. How to add the endless scrolling feature to this.
public class ProductListing extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.product_listing_act);
init();
}
public void productListingApiCall() {
RestAdapter restAdapter = new RestAdapter.Builder().setEndpoint(base_url).setLogLevel(RestAdapter.LogLevel.FULL).build();
final ProductListingApi productListingApi =
restAdapter.create(ProductListingApi.class);
productListingApi.getFeed(file, operation_condition, search_string_condition, minprice_condition, maxprice_condition, mincusratings_condition,
maxcusratings_condition, discount_condition, catids_condition, brands_condition, affids_condition, start_row_condition, limit_condition,
orderby_condition, sortby_condition, new Callback<ProductListingPojo>() {
#Override
public void success(ProductListingPojo productListingPojo, Response response) {
final ProductListingPojo product = productListingPojo;
new Thread(new Runnable() {
#Override
public void run() {
product_key = Arrays.copyOf(product.getProductkey(),
product.getProductkey().length);
cs_category_id = Arrays.copyOf(product.getCsCategoryid(),
product.getCsCategoryid().length);
title = Arrays.copyOf(product.getTitle(),
product.getTitle().length);
price = Arrays.copyOf(product.getSellingprice(),
product.getSellingprice().length);
mrp = Arrays.copyOf(product.getMrp(),
product.getMrp().length);
discount = Arrays.copyOf(product.getDiscountpercent(),
product.getDiscountpercent().length);
image = Arrays.copyOf(product.getProductimageSmall1(),
product.getProductimageSmall1().length);
cus_agg_num = Arrays.copyOf(product.getCustratingAggNum(),
product.getCustratingAggNum().length);
}
}).run();
setAdapter();
}
#Override
public void failure(RetrofitError error) {
tv_title_header.setText(error.getMessage());
Log.e("error", error.getMessage());
}
});
}
void setAdapter() {
adapter = new ProductListingGridAdapter(this, title, image, price, mrp, discount);
gv_product_listing_act.setAdapter(adapter);
}
}
The init() in OnCreate() will initialise all the view and call the productListingApiCall() for the first time. The way the api works is that, i will request for the first 10 items (start_row_condition: 0 and limit: 10), then on reaching the bottom after scrolling it should add the next 10, hence i need to call the api with (start_row_condition: 10 and limit:10). How can i implement this.