Suppose I am having 5 fragments in viewpager. Lets say Fragment A, B, C, D, E.
I have a button on fragment A to go to fragment B. When I press this button, viewpager scrolls to fragment B. Somehow I controlled the duration of fragment A to B. Now the thing is, I have an scrollable container in Fragment B. I want to scroll that container during the Scroll between A to B happens. Now its scrolling after I am going from Fragment A to B. I want this happen between this transition.
Inside first fragment:
#Override
public void onClick(View view) {
if(view.getId() == bottomLayout.getId())
{
MainActivity.pager.setCurrentItem(1);
}
}
It will change my pager position 0 to 1. Now when its changing. I controlled the scroll speed of viewpager. On top of second fragment, I have a ScrollView, I need to perform scroll on this scrollview as fragment is changing,not after its changed.
To animate the view of the FragmentB, you need to tell it to start animation as soon as you call viewPager.setCurrentItem().
Inside FragmentA's click listener, you will ask the parent Activity to change the ViewPager item (see Communicating with the Activity to know how this should be done) :
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
activityCallback.setViewPagerItem(POSITION_OF_FRAGMENT_B);
}
});
In your Activity in which the ViewPager resides, you will write:
public void setViewPagerItem(int position) {
viewPager.setCurrentItem(position);
// following asks the fragmentB to start its animation on its view.
if (position == POSITION_OF_FRAGMENT_B) {
fragmentB.startYourAnimation();
}
}
In FragmentB, you add a method:
public void startYourAnimation() {
// write your code to animate your ListView or whatever you want to
// animate inside the FragmentB
}
Notes:
Unless you've called viewPager.setOffscreenPageLimit(), an instance of FragmentB will already exist if you're doing it from FragmentA or FragmentC,
a Fragment should not communicate with other fragments directly, instead they should use their parent Activity as a middle person. See Communicating with Other Fragments.
No it is not possible to do so because any scrollable view like listview or recyclerview, the items are created only when it is visible to user and only when scrolled, so if that fragment is not visible, you cannot scroll any of its child scrollable view.
Related
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.
I have one tab activity that contain 3 tabs.
I have one edittext and button in my activity, one textview in fragments.
Whenever I need to change the fragment textview I simply add some text in edittext and click the button after. That text should appear in the fragment.
Here I am not able to use setArguments.
If you are using ViewPager to render the fragment use this code in your parent Activity.
if(viewPager.getCurrentItem() == 1) //First fragment
{
FragmentOne frag1 = (FragmentOne)viewPager.getAdapter().instantiateItem(viewPager, viewPager.getCurrentItem());
frag1.textview.setText(yourText);
}
Otto's EventBus to the rescue.
I had exactly this situation to handle. In my case I needed to trigger a fragment change inside a viewpager with locked swipes. So
Gradle:
// EventBus
implementation 'org.greenrobot:eventbus:3.0.0'
Make an event which will be passed from the activity to the fragment
public class FragmentChangeEvent {
public int fragmentToBeChanged;
//here you can define variables of your choosing, just make sure you're including them into the constructor of the event.
public FragmentChangeEvent(int fragmentToBeChanged) {
this.fragmentToBeChanged = fragmentToBeChanged;
}
}
Trigger the event from the activity
EventBus.getDefault().post(new FragmentChangeEvent(1));
And finally make your fragment aware of the bus and the events
#Subscribe(threadMode = ThreadMode.MAIN)
public void onChangeFragmentEvent(FragmentChangeEvent event) {
//do your work here.
}
}
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.
I took over this android project from an outsourced developer. I do iOS development so I am still trying to get up to speed with android. The app has a top tab navigation which appears on all views. The home view is a fragment which has icons which when clicked on produce webviews that replace the home view, which the navigation tab still in view. I want to replace one of the webviews with a list view which is a fragment which I already have coded (EHallSchedFragment.java), so that when the icon is clicked on the list view replaces the home view with the navigation tab still in view. See the images below.
HOME VIEW
VIEW I WANT WHEN EXHIBIT HALL SCHEDULE ICON IS CLICKED ON
Here is the code for the onClick event for that button as it exists. It calls a webView:
ivExhall.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
openInternalWebview("http://www.web.org/m/content.aspx?id=7006");
//Need code here to open EhallSchedFragment.java
}
});
SO what I need is the onClick code that will open the fragment in the existing view, leaving the navigation tab in place.
Try this approach: Define an interface inside your fragment, implement it in your activity and then override the method there. Then finally, from your fragment, when a user clicks an item from a list, call the interface method to notify the activity of the event.
From Your Fragment
#Override
public void onClick()
{
//when a user selects an event from your list
switch(position)
{
((OnScheduleSelectedListener) getActivity()).switchFragment(new DetailsFragment());
}
}
public interface OnScheduleSelectedListener
{
void switchFragment(Fragment frag);
}
You can then do the following in your activity:
public class ScheduleAppActivity extends Activity implements OnScheduleSelectedListener
{
.............................
#Override
switchFragment(Fragment frag)
{
//check if fragment is in view here and if,
replaceFragment(fragment)
//else
addFragment(frag);
commit();
}
}
So at this point, the right fragment will be added to view.
I hope this helps you!
I have a Viewpager that uses a FragmentStatePagerAdapter. Each page is a Fragment. My pages contains an linearlayout (llTags) which is default visible.
If the user clicks on a page (main layout of the fragment), the linearlayout must be invisible (works) but the other linearlayouts (llTags in other pages) needs to be changed too.
If i click, the visibility of the linearlayouts changed off all pages exept the previous and next.
This is because the getItem from the adapter isn't called for the next/previous item again.
How can i notify these pages.
ps: i have a newInstance method and a public void setTagslayoutVisible(boolean) for changing the visibility from the adapter.
Next and previous are already loaded and the adapter is not going to call creation.
Take a quick try at this, in your adapter get function if your fragment is already loaded it returns those objects. So just add something like this
if(myMap.containsKey(position))
{
LiveStreamFullScreenFragment lfsf = (LiveStreamFullScreenFragment) myMap.get(position));
lfsf.setShowTags(mShowTags);
return lfsf;
} else
{
and in your fragment class
public void setShowTags(boolean showtags)
{
mShowTags = showtags;
if(!mShowTags)
{
llLiveStreamTags.setVisibility(View.GONE);
}
}
Hope this helps and enjoy your work.