clean RecyclerView after tap to button Back - android

I have RecyclerView that is filled with a list of items received from the server response.
First, the user enters a log / password and selects a specific content, such as: 1 content.
After login the user go to the activity with has RecyclerView, where there are fields of content 1.
When user click on the Back button he goes back to the main activity of registration and selects the already content 2. After clicking the Login button, again goes to RecyclerView, but for some reason it has fields from the content 1 and fields content 2 Add to end of list.
I use this methods :
#Override
public void onBackPressed() {
super.onBackPressed();
recyclerView.removeAllViewsInLayout();
recyclerView.removeAllViews();
unswerFromMain.clear();
recyclerAdapter.updateAdapter(unswerFromMain);
}
This is in Adapter :
public void updateAdapter (ArrayList<Unswer> updateUnswer){
getUnswer.clear();
getUnswer.addAll(updateUnswer);
notifyDataSetChanged();
}
All this method didn`t work.

I believe this is because you are calling onBackPressed() before you do anything else. This means those other lines never run. Try swapping it around:
#Override
public void onBackPressed() {
recyclerView.removeAllViewsInLayout();
recyclerView.removeAllViews();
unswerFromMain.clear();
recyclerAdapter.updateAdapter(unswerFromMain);
super.onBackPressed();
}

Set an empty array into your adapter and notify
adapter.setItems(new ArrayList<MyPOJO>);
adapter.notifyDataSetChanged();
EDIT
You should call super.onBackpressed for the last. Like this
#Override
public void onBackPressed() {
recyclerView.removeAllViewsInLayout();
recyclerView.removeAllViews();
unswerFromMain.clear();
recyclerAdapter.updateAdapter(unswerFromMain);
super.onBackPressed();
}

I found a bug.
The problem was not to clean the adapter, it was not cleansed ArrayList which was from the main activity. This ArrayList contains a field content 1 and when I was at activity with RecyclerView and pressed the Back button that returns to the main activity already filled ArrayList data content 1. Then I chose the content 2 and the data on it just added to the end of the ArrayList.
I completely removed all methods onBackPressed (), except super.onBackPressed (); and everything was working fine. Thank you all !

I'm tried with above answer are not work for me.
So I have handle RecyclerView with hide and show.
recyclerview.setVisiblity(View.GONE);
recyclerview.setVisiblity(View.VISIBLE);
and my logic is,
first initialize one int value globally like, int clicked = 0;
BackPress event use that below code:
public void onBackPressed(){
if(recycler_view!=null){
if(clicked==0){
recycler_view.setVisibility(View.GONE);
clicked =1;
}else{
finishAffinity();
}
}else {
finishAffinity();
}
}
When you show(recyclerview.setVisiblity(View.VISIBLE);) recyclerview in activity that time set Clicked =0
So, easy way to show and hide recyclerview as well as backpress also handled.

Related

Fragments : Manage data until not signup

I have 3 fragments which is settled in TabLayout with ViewPager.
The Scenario is:
First fragment has one ImageView with some EditText and RadioButton with NEXT Button
Second fragment has 5 EditText with NEXT Button
Third Fragment has 4 ImageView and 4 EditText with SignUp Button
all fields are required.
Now what I have done:
Checked all validation on Button click of Fragment 1 and moved to NEXT fragment.
if (getActivity() != null) {
((RegisterActivity) getActivity()).mViewPager.setCurrentItem(1, true);
}
Same process
Same process and proceed for SignUp.
Problem:
How can I check values When I move to second fragment without clicking button (Sliding Viewpager or Clicking on TAB)
How can I update all final values (when I change it but do not click on button and move forward)
I have tried to use onAttach and onDetach for saving values but didn't worked.
Any solution for manage all data and check validation in each situation?
You can track of current selected tab by TabLayout.ViewPagerOnTabSelectedListener,
take a look here for more information docs
In general just implement this interface and then you will be notified when user swipe tabs or if you programmatically swipe you will still get notified.
Not the best solution but the workaround I have recently implemented.
Take boolean[] of total fragments.
like:
private boolean[] arrLastPageDone = new boolean[]{false, false, false};
If all values of fragment1 validated, set true on first position. Same for other fragments.
Simply check values in onPageSelected.
like:
pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if (position > 0 && !arrLastPageDone[position - 1]) {
pager.setCurrentItem(pager.getCurrentItem() - 1);
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
And it works. It dosen't let swipe to next fragment until all values validated.
And you can save those data to SingleTon Class until all process finished.

Looking for best way to implement modal dialog in onPause

I have fragment with EditTexts that user can change.
As well I have back button on Toolbar (and physical back button too)
When the user hits back, I check if the data was changed and if it was - I need to open dialog and ask the user "Do you want to save changes?". Get the click and act accordingly (positive or negative answer).
The best place to save the data (maybe I wrong) is in onPause of this fragment.
The problem is with the dialog - it is not modal and while it's showing the question and waits for user reaction - the fragment under it disappears and previous come back from stack.
I need to "pause the onPause" with the dialog until the user make his choice. What the easy (or most correct) way to do it?
#Override
public void onPause() {
if (!(text.getText().toString().equals(user.getName())))
{
new MaterialDialog.Builder(getActivity())
.title("Save changes?")
.content("You changed you personal details, save changes?")
.cancelable(false)
.positiveText("Save")
.negativeText("Discard")
.onPositive(new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(#NonNull MaterialDialog dialog, #NonNull DialogAction which) {
save();
}})
.show();
}
super.onPause();
}
If I want to do it before onPause - I'll need to catch the Toolbar's back button and physical back button - seems too much work for this. Looking for elegant way.
Thank you
onPause is called when the activity moves into the background (not being shown on the screen anymore).
To show a dialog before the app goes off screen, you can override the "onBackPressed" function in an activity.
#Override
public void onBackPressed() {
performBackPressed();
}
public void performBackPressed(){
//show your dialog here
//call finish(); when done to close app
}
You can call the performBackPressed() method whenever the Toolbar's back button is pressed too.
If you're trying to show a popup from a fragment when back is pressed, then you still have to override that method in the activity, then notifiy the fragment whenever back is pressed.
In my app I have a container in the activity that holds all my fragments. I use this code to get the currently active fragment:
YourFragmentClass curFrag = (YourFragmentClass) fragmentManager.findFragmentById(R.id.fragment_container);
then I have a method in the fragment called onBackPressed() and I just call that on the fragment I just got.

Is it possible to set different actions for floating action button in differet fragments?

I am working or an app where I have 4 fragments in viewpager and floating action button (fab). When I click on fab there appear 3 subfabs. Each of them start different activities where user can search data from different fragments. Is it possible to set fab so that if I click on it while I'm in first fragment it'll open an activity for searching inside this fragment, onClick inside second - search for second and etc. The issue is that now clicking on sub fab while I'm in some fragment I can search data from another fragment too and it's a bit weird. I understand question is kinda strange, if something is unclear I'll explain further
You can make FAB button public and implement onClick listener in each fragment.
You should override setUserVisibleHint and put your code onResume so getActivity() will not return null. Fab button will have different actions in different fragments.
Here's an example, inside each fragment when you want Fab click listener:
#Override
public void setUserVisibleHint(boolean visible)
{
super.setUserVisibleHint(visible);
if (visible && isResumed())
{
onResume();
}
}
#Override
public void onResume()
{
super.onResume();
if (!getUserVisibleHint())
{
return;
}
MainActivity mainActivity = (MainActivity)getActivity();
mainActivity.fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Do what you want
}
});
}
You can check in onclick method of floating action button which fragment is currently opened and calling it.
Call findFragmentById() on FragmentManager and determine which fragment is in your R.id.frameTitle container.

BackButton in the Fragment cannot be disabled

I have a mainActivity with viewPager and three tabs, each tab has its respective fragment. i want when this mainActivity is launched and the backButton is pressed, nothing to happen.
to achieve this, i override onBackPressed() inside the mainActivity the one has viewPager with tabs, but when the mainActivity ia launched one of the tabs, which represents Fragment, by default appears, and when i press the backButton, i go back, which means the Backbuton is not disabled.
that is it, in the mainActivity, i have:
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
Log.w(TAG, "#onBackPressed().");
}
and he backbutton is not disabled in the Fragment, each time i press it, the logCat displays the message in the onBackPressed and i go back, and i do not want this, i want while i am in the Fragment "any one of the tabs", the backButton should has no effect.
please let me know how to achieve this?
Try not calling
super.onBackPressed();
Although the log will still print because the method will be called, this will stop Android performing it's logic and going back.
If you want the fragment tabs to do nothing, but the viewpager to handle it, do something like this
#Override
public void onBackPressed() {
if (getCurrentTab == 0) {
super.onBackPressed();
} else {
//This will stop the fragment tabs from doing anything when back is pressed
}
}
If you need avoid the back button, comment the super call //super.onBackPressed();

update listview in fragment when returning to it

I have a Activity that transitions between fragments. Fragment 1 to fragment 2. Fragment 1 has a listview. When the user goes to fragment 2 the user has the option to make changes to the data that fills the listview. When the user presses the back button it takes them back to the first fragment. When the user returns the listview has to be updated to show the changes that were made in fragment 2. How can i do this?
Frag2 pfrag = new Frag2();
pfrag.setArguments(bundle);
ft=fm.beginTransaction();
ft.add(R.id.fragment_swap, pfrag,"Profile");
ft.show(pfrag);
ft.addToBackStack("pfrag");
ft.commit();
You would do this by calling notifyDataSetChanged(); on the ListView's adapter.
For more info
You could use Robins answer or if you want to pass the data in fragment 2 to fragment 1 you could call a method in fragment 1 class:
YourFragmentClass.refreshList( your data)
and in Fragment 2 the method:
puplic void refreshList(your data) {
// set the adapter with your data
}
In you fragment, include the code as like below.
(isPaused)boolean variable is used to track current fragment is paused while navigating to next activity.
While resuming back call the webservice (or) call the method to refresh the list by calling notifydatasetchanged() from adapter.
#Override
public void onResume() {
super.onResume();
if(isPaused) {
isPaused=true;
fetchDirectories();
// call the adapter method to notify the data set.
}
}
#Override
public void onPause() {
super.onPause();
isPaused=true;
}
private boolean isPaused=false;
I think the best way to achieve this, is to load the list in the fragment's onResume()-Method. So, the code looks something like this:
#Override
public void onResume() {
super.onResume();
initializeList();
}
...
private void initializeList() {
adapter = new MessageTemplateAdapter(getActivity(), datasource.getTemplateList());
setListAdapter(adapter);
}

Categories

Resources