I am using onLoadMoreListener when i scroll RecyclerView. It will update the RecyclerView data when you scroll to bottom. After updating the Recyclerview data. The Recyclerview goes back up to the top. Ideally, I would like to retain the position in the RecyclerView. Any thoughts on how I should go about doing this?
mAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {
#Override
public void onLoadMore() {
new GroupData().execute();
}
});
InnerClass
public static class GroupData extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
try{
GroupList gm = new GroupList();
.....
groupvalues.add(gm);
} catch (Exception e){
Log.d("Grouplist ", e.toString());
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
mAdapter = new GroupAdapter(groupvalues,mrecyclerview);
mrecyclerview.setAdapter(mAdapter);
progressDialog.dismiss();
mAdapter.notifyDataSetChanged();
}
}
}
Try this,
public static class GroupData extends AsyncTask<Void, Void, Void> {
int size = 0;
#Override
protected void onPreExecute() {
size = groupvalues.size();
}
#Override
protected Void doInBackground(Void... voids) {
try {
GroupList gm = new GroupList();
.....
groupvalues.add(gm);
} catch (Exception e) {
Log.d("Grouplist ", e.toString());
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
mAdapter.notifyItemRangeChanged(size, groupvalues.size() - size);
progressDialog.dismiss();
}
}
When you are loading you must be knowing the position of top element of new loaded items. just call:
recyclerView.scrollToPosition(position);
or just save the last know position of your recyclerView and Scroll to that position when you load more items
Just notify your adapter in onPostExecute. No need to initialise your adapter again.
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
progressDialog.dismiss();
mAdapter.notifyDataSetChanged();
}
Initialise your adapter in onCreate
mAdapter = new GroupAdapter(groupvalues,mrecyclerview);
mrecyclerview.setAdapter(mAdapter);
Related
I have created an app to get RSS Feed from XML file and show it in a recyclerview within card views. I want to implement the Pull to refresh to load the data.
where exactly the method supposed to be ?
my main activity :
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
//Call Read rss asyntask to fetch rss
try {
ReadRss readRss = new ReadRss(this, recyclerView);
readRss.execute();
}catch (Exception e) {
Toast.makeText(getApplicationContext(), "There's a problem", Toast.LENGTH_LONG);
}
}
}
and this is ReadRss class :
public class ReadRss extends AsyncTask<Void, Void, Void> {
Context context;
String address = "http://karary-001-site1.htempurl.com/XMLFile1.xml";
ProgressDialog progressDialog;
ArrayList<FeedItem> feedItems;
RecyclerView recyclerView;
URL url;
public ReadRss(Context context, RecyclerView recyclerView) {
this.recyclerView = recyclerView;
this.context = context;
progressDialog = new ProgressDialog(context);
progressDialog.setMessage("loading....");
}
//before fetching of rss statrs show progress to user
#Override
protected void onPreExecute() {
progressDialog.show();
super.onPreExecute();
}
//This method will execute in background so in this method download rss feeds
#Override
protected Void doInBackground(Void... params) {
//call process xml method to process document we downloaded from getData() method
ProcessXml(Getdata());
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
progressDialog.dismiss();
FeedsAdapter adapter = new FeedsAdapter(context, feedItems);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.addItemDecoration(new VerticalSpace(20));
recyclerView.setAdapter(adapter);
}
pullToRefresh method :
final SwipeRefreshLayout pullToRefresh = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
pullToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
//refresh code
pullToRefresh.setRefreshing(false);
}
});
where exactly the method supposed to be ?
First set pullToRefresh.setRefreshing(true); if its not working than try below code
pullToRefresh.post(new Runnable() {
#Override
public void run() {
pullToRefresh.setRefreshing(true);
}
});
Here is what you can do
pullToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
//refresh code
ReadRss readRss = new ReadRss(this, recyclerView);
readRss.execute();
}
});
and then in onPostExeceute()
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
progressDialog.dismiss();
pullToRefresh.setRefreshing(false); // in case of pullToRefresh
FeedsAdapter adapter = new FeedsAdapter(context, feedItems);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.addItemDecoration(new VerticalSpace(20));
recyclerView.setAdapter(adapter);
}
Hope this helps
Hello friends i want to integrate pagination in my recycleview so below is my code
in onCreateVIew
LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.task_recycle);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setOnScrollListener(new EndlessRecyclerOnScrollListener(mLayoutManager) {
#Override
public void onLoadMore(int current_page) {
if (OnzupApplication.mPendingDatas.size() < total) {
page++;
new getPendingTask(false,true).execute();
}
}
});
if (mAllMethods.check_Internet() == true) {
new getPendingTask(true,false).execute();
} else {
mAllMethods.ShowDialog(getActivity(), "", getString(R.string.net_not_available), "OK");
}
Call AsyncTask
public class getPendingTask extends AsyncTask<Void, Void, Void> {
private boolean showLoading;
boolean pagination;
public getPendingTask(boolean showLoading,boolean page) {
this.showLoading = showLoading;
this.pagination=page;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
if (showLoading == true) {
mProgressDialog = ProgressDialog.show(getActivity(), "", getString(R.string.loading));
}
}
#Override
protected Void doInBackground(Void... voids) {
mGetPendigTask = (GetAllPendigTask) mPostParseGet.getPendingTask(mGetPendigTask, token, page);
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if (showLoading == true) {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
}
}
try {
if (mPostParseGet.isNetError) {
mAllMethods.ShowNoConnectionDialog(mActivity, mContext, "", getString(R.string.net_not_available), getString(R.string.setting), getString(R.string.cancel));
} else if (mPostParseGet.isOtherError) {
if (!mPostParseGet.isRequestTimeOutError) {
new ActivityHelper(mActivity).sendMail(token);
}
mAllMethods.ShowDialog(mActivity, "", getString(R.string.data_not_found), "OK");
} else {
if (mGetPendigTask.isSuccess() == true) {
mPendingDatas = getData();
total = Integer.parseInt(mGetPendigTask.getTotalitems());
if (mGetPendigTask.getTasks().size() > 0) {
mTextViewNoData.setVisibility(View.GONE);
mRecyclerView.setVisibility(View.VISIBLE);
mAllPendingRecyclerAdapter = new AllPendingRecyclerAdapter(getActivity(), OnzupApplication.mPendingDatas);
if (pagination==false)
{
mRecyclerView.setAdapter(mAllPendingRecyclerAdapter);
}
mAllPendingRecyclerAdapter.notifyDataSetChanged();
} else {
mTextViewNoData.setVisibility(View.VISIBLE);
mRecyclerView.setVisibility(View.GONE);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
When i call above code 1 page is loaded but when i scroll second page data is not loaded any idea how can i solve this?
Because of this line
mAllPendingRecyclerAdapter = new AllPendingRecyclerAdapter(getActivity(), OnzupApplication.mPendingDatas);
You did create the Adapter at the first time, when you use load more function in recyclerview. You should add your data in your own Adapter instead of create the new one
I use pulltorefreshListview in my project, I set Mode.Both. I want the result when I pull from end for loading more,and scroll the end ,already load all data ,I hope the footerview hide. but now when I scroll the listview to end ,the footerview is showing, How can I for that?
private void pullRefresh() {
morelist.setOnRefreshListener(new OnRefreshListener<ListView>() {
#Override
public void onRefresh(PullToRefreshBase<ListView> refreshView) {
if (refreshView.isShownHeader()) {
//refresh
new GetDataTask().execute();
}else if (refreshView.isShownFooter()) {
//load more
number = number+20;
new GetDataTask().execute();
}
}
});
}
private class GetDataTask extends AsyncTask<Void, Void, String[]> {
#Override
protected String[] doInBackground(Void... params) {
try {
if (isDown) {
getData(number,"-1");
} else {
getData(number,"1");
}
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String[] result) {
morelist.onRefreshComplete();
super.onPostExecute(result);
}
}
I receive an error with the following code. I don't understand why, but adapter.notifyDataSetChanged(); doesn't work. The message of error is: "cannot resolve symbol 'adapter'".
final String URL = "http://example....";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
rv = (RecyclerView) findViewById(R.id.rv);
....
public class PrintA extends AsyncTask<String, String, List<Model>> {
....
#Override
protected void onPostExecute(final List<MyModel> result) {
super.onPostExecute(result);
if (result != null) {
MyAdapter adapter = new MyAdapter(result);
rv.setAdapter(adapter);
} else {
Toast.makeText(getApplicationContext(), "no internet",
}
}
}
new PrintA().execute(URL);
rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
....
public class PrintB extends AsyncTask<String, String, List<Model>> {
....
#Override
protected void onPostExecute(final List<MyModel> result) {
super.onPostExecute(result);
if (result != null) {
....
adapter.notifyDataSetChanged();
} else {
Toast.makeText(getApplicationContext(), "can't add",
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
....
new PrintB().execute(URL);
}
}
}
}
MyAdapter adapter = new MyAdapter(result);
replace this by
adapter = new MyAdapter(result);
and declare this in Global
MyAdapter adapter;
like this
MyAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
I have ListView with items containing a Button among others. I start an Asynctask from the Adapter class of the ListView:
holder.btn_follow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new Follow_Async().execute(arr_id.get(position), arr_name.get(position));
}
}
});
This is my Asynctask:
public class Follow_Async extends AsyncTask<String, Void, String> {
#Override
protected void onPostExecute(String result) {
//here
Toast.makeText(Activity_Followers2.this, "You are now following " + result, Toast.LENGTH_SHORT).show();
}
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(String... params) {
try {
params_follow = new ArrayList<NameValuePair>();
params_follow.add(new BasicNameValuePair("session_userid", session_userid));
params_follow.add(new BasicNameValuePair("friend_userid", params[0]));
JSONParser jsonParser; jsonParser = new JSONParser();
JSONObject json = jsonParser.makeHttpRequest(add_follow, "POST", params_follow);
} catch (Exception e) {
e.printStackTrace();
}
return params[1];
}
}
In the PostExecute() I want to change the text of the Button I have just clicked to Unfollow. How can I access it from there?
Just pass your button as a parameter to the AsyncTask constructor:
In the adapter:
final thisButton = holder.btn_follow; // <------------ add a final Button field
thisButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new Follow_Async(thisButton). //<------------- pass button to AsyncTask
execute(arr_id.get(position), arr_name.get(position));
}
}
});
And in the AsyncTask:
class Follow_Async extends AsyncTask<String, Void, String> {
private final Button button;
public Follow_Async(Button button) { //<------------- pass button to constructor
this.button = button;
}
#Override
protected void onPostExecute(String result) {
this.button.setText(""); //<--------------- do something with button
}
}