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) {
Related
I use mvp architecture.
I have the setupViews () method in which the buttons and ... are defined
how i can use setOnclickListener for Button in "presenter" and call it in SetupViews in "activity".
I do not want to use it directly in "view",I want to tell the presenter that the click is done and the presenter will do the job.
My interface:
public interface HomeContract {
interface View extends BaseView {
void showNews(List<News> newsList);
void showError(String error);
}
interface Presenter extends BasePresenter<View> {
void getNewsList();
} }
presenter class :
public class HomePresenter implements HomeContract.Presenter {
private HomeContract.View view;
private NewsDataSourse newsDataSourse;
CompositeDisposable compositeDisposable = new CompositeDisposable();
public HomePresenter(NewsDataSourse newsDataSourse) {
this.newsDataSourse = newsDataSourse;
}
#Override
public void getNewsList() {
newsDataSourse.getNews().subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SingleObserver<List<News>>() {
#Override
public void onSubscribe(Disposable d) {
compositeDisposable.add(d);
}
#Override
public void onSuccess(List<News> news) {
view.showNews(news);
}
#Override
public void onError(Throwable e) {
view.showError(e.toString());
}
});
}
#Override
public void attachView(HomeContract.View view) {
this.view = view;
getNewsList();
}
#Override
public void detachView() {
this.view = null;
if (compositeDisposable != null && compositeDisposable.size() > 0) {
compositeDisposable.clear();
}
}}
my view :
public class HomeActivity extends BaseActivity implements HomeContract.View {
private HomeContract.Presenter presenter;
private NewsRepository newsRepository = new NewsRepository();
private RecyclerView recyclerView;
private RecyclerAdapter recyclerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
presenter = new HomePresenter(newsRepository);
}
#Override
public void setupViews() {
Button btn_Ok = (Button) findViewById(R.id.btn_Ok);
recyclerView = (RecyclerView) findViewById(R.id.recycler);
recyclerView.setLayoutManager(new LinearLayoutManager(getViewContext(), LinearLayout.VERTICAL, false));
// btn_Ok.setOnClickListener();
}
#Override
public void showNews(List<News> newsList) {
setupViews();
recyclerView.setAdapter(new RecyclerAdapter(newsList, getViewContext()));
if (newsList.size() > 0) {
Toast.makeText(getViewContext(), "ok", Toast.LENGTH_SHORT).show();
Toast.makeText(getViewContext(), newsList.get(0).getName(), Toast.LENGTH_SHORT).show();
} else
Toast.makeText(getViewContext(), "not Ok", Toast.LENGTH_SHORT).show();
}
#Override
public void showError(String error) {
Toast.makeText(getViewContext(), error, Toast.LENGTH_SHORT).show();
}
#Override
public Context getViewContext() {
return getApplicationContext();
}
#Override
protected void onStart() {
super.onStart();
presenter.attachView(this);
}
#Override
protected void onStop() {
super.onStop();
presenter.detachView();
}
}
i want to use btn_Ok.setOnClickListener(presenter....); in view Or any better solution you need to do this
In your presenter interface type a method :
interface Presenter extends BasePresenter<View> {
void getNewsList();
void onButtonClicked();
}
And than in your HomePresenter class use it :
#Override
public void onButtonClicked(){
// continue logic here
}
If you don't override it the class will show an error
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 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);
Hello i am trying to implement a log in screen showing a progress dialog and allowing the phone to rotate.
I want to ask what is the best way to do that (IntentService, AsyncTask,Service) and allowing the phone to rotate?
I read a lot answers saying different things using an empty fragment with AsyncTask etc.
You can do something like that in manifest to allow rotation:
<application
android:allowBackup="true"
android:configChanges="orientation|keyboardHidden|screenSize"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity
android:name=".activities.MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name"/>
Then you can catch the rotation with this snipet inside your activity:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.v(this.getClass().getName(), "onConfigurationChanged()");
}
To do an asynctask with progress dialog, this snipet should give you a ligth:
private ProgressDialog pDialog;
private class MyAsync extends AsyncTask<String, Void, String> {
Activity context;
public MyAsync (Activity context) {
this.context = context;
}
#Override
protected void onPreExecute(){
super.onPreExecute();
pdia = new ProgressDialog(context);
pdia.setMessage("Loading...");
pdia.show();
}
#Override
protected String doInBackground(String... urls) {
...
//do your login scheme
...
//context.methods()
return "ok";
}
#Override
protected void onPostExecute(String result) {
pDialog.dismiss();
if(result!=null && result.equals("ok")){
//login was successfully done
} else {
//login has failed
}
}
}
And to use this asynctask you shoud call:
new MyAsync(this).execute(null, null , null);
By the way this is your activity/fragment.
Try adding this attribute android:configChanges="orientation" to your Activity element in the AndroidManifest.xml file.
show a ProgressDialog in the onPreExecute method of an AsyncTask object and canceling the ProgressDialog in the onPostExecute method. doInBackground method is running When change the orientation.
Refer to http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html for a detailed answer.
Basically, you can use fragment with setRetainInstance set to true inside your LoginActivity so that it doesn't get destroyed when activity is recreated during orientation change.
Sample Code :
public class AsyncFragment extends Fragment {
private LoginTask mTask;
private AsyncTaskListener mListener;
private static final String TAG = "AsyncFragment";
private boolean isTaskRunning = false;
private ProgressDialog mProgressDialog;
FrameLayout mLayout;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
mTask = new LoginTask();
mTask.execute();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mLayout = new FrameLayout(getActivity());
mLayout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
if(isTaskRunning) {
mProgressDialog = new ProgressDialog(getActivity());
mProgressDialog.show();
}
return mLayout;
}
#Override
public void onDestroyView() {
if(mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
super.onDestroyView();
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
mListener = (AsyncTaskListener) context;
} catch (ClassCastException e) {
Log.d(TAG, "Class not instance of AsyncTaskListener");
}
}
#Override
public void onDetach() {
mListener = null;
super.onDetach();
}
private class LoginTask extends AsyncTask<Void,Integer,Void> {
#Override
protected Void doInBackground(Void... params) {
if(mListener != null) {
mListener.onBackground();
}
SystemClock.sleep(10000);
return null;
}
#Override
protected void onPreExecute() {
isTaskRunning = true;
mProgressDialog = new ProgressDialog(getActivity());
mProgressDialog.show();
if(mListener != null) {
mListener.onPreExecute();
}
super.onPreExecute();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(mListener != null) {
mListener.onPostExecute();
}
isTaskRunning = false;
if(mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if(mListener != null) {
mListener.onProgressUpdate(values[0]);
}
}
#Override
protected void onCancelled() {
super.onCancelled();
if(mListener != null) {
mListener.onCancelled();
}
}
}
//Listener to notify for async task callbacks
public interface AsyncTaskListener{
void onPreExecute();
void onPostExecute();
void onCancelled();
void onBackground();
void onProgressUpdate(int progress);
}
}
LoginActivity
public class MainActivity extends AppCompatActivity implements AsyncFragment.AsyncTaskListener{
private static final String FRAGMENT_TAG = "asyncFragment";
private static final String TAG = "MainActivity";
private AsyncFragment mAsyncFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fm = getSupportFragmentManager();
mAsyncFragment = (AsyncFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (mAsyncFragment == null) { //fragment was retained during orientation change
mAsyncFragment = new AsyncFragment();
fm.beginTransaction().add(mAsyncFragment, FRAGMENT_TAG).commit();
}
}
#Override
public void onPreExecute() {
Log.d(TAG, "onPreExecute: ");
}
#Override
public void onPostExecute() {
Log.d(TAG, "onPostExecute: ");
}
#Override
public void onCancelled() {
Log.d(TAG, "onCancelled: ");
}
#Override
public void onBackground() {
Log.d(TAG, "onBackground: ");
}
#Override
public void onProgressUpdate(int progress) {
Log.d(TAG, "onProgressUpdate: ");
}
Have you tried this?
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize">
</activity>
This way the activity will not be recreated. but you can detect the screen orientation using onConfigurationChanged()