I've got an App with a LinearLayout to which rectangular fragments are added below each other over time from top to bottom.
At some point the screen is full and the new fragments are "hidden" outside the view of the screen. What I'd like to do then is to make the App scroll to bottom every time a new fragment is added.
A fragment is added everytime a button in the activity is pushed or a checkbox in the above fragment is checked.
So I've tried the following in the onClickListeners and in the onCreateView of the fragments:
fm.beginTransaction().add(R.id.activity_uhf_layout, fragment).commit(); //Adding fragment
runOnUiThread(new Runnable() {
#Override
public void run() {
scrollView.scrollTo(0, scrollView.getBottom());
}});
This works sometimes, the fragment is added and the screen scrolls down, but its like 1/8 times.
I've tried other things such as:
scrollView.post(new Runnable() {
#Override
public void run() {
scrollView.scrollTo(0, scrollView.getBottom());
}
});
Which basically gives the same result and I've tried without the Runnable post, which doesn't work at all.
The result I'm getting is that the layout is only scrolled down to the bottom of the fragment which is already present and not all the way down to the end of the new fragment which has just been added by the fragmentmanager.
To me it seems that even though the fragment is added, the LayoutManager hasn't really "detected it" or something similar, but how to get around it, I'm not really sure about.
You could also try doing this.
fm.executePendingTransactions();
runOnUiThread(new Runnable() {
#Override
public void run() {
//Linearlayout is the layout the fragments are being added to.
View view = linearLayout.getChildAt(linearLayout.getChildCount()-1);
scrollView.scrollTo(0, view.getY() + view.getHeight());
}});
I don't know that the executePendingTransactions() is necessary, but if the view has been added, then that should work.
Related
I have a fragment with a nestedScrollView with some static information and some LinearLayouts with visibility GONE.
Those LinearLayout get fills after this fragment get opened and then I set the visibility of those Layouts on VISIBLE. I want just to scroll to the bottom of this fragment when this info load.
I tried with the property descendantFocusability and using the fullscroll function on this nestedScrollView, but I get no results.
While load the fragment try to call this in onCreateview() in your fragment for scroll at the bottom.
Runnable runnable=new Runnable() {
#Override
public void run() {
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
};
scrollView.post(runnable);
Happy coding!!
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.
I'm using Android Tutorial Bubbles library to add informative bubbles referring to views in my UI. My main UI consists of three tabs using a ViewPager. And I would like the tutorial for the second tab to begin only when the user navigates to that tab. I am able to catch the event that the user navigates to the tab using an OnPageChangeListener.
The problem is that the onPageSelected() method fires before the views are in their correct positions, meaning that the highlighted area that is supposed to surround the view of interest is significantly shifted. I could solve this using Thread.sleep() for a short period of time; is there a cleaner way of handling this?
Here's my code:
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
if (position == 1) {
sensorReadingFragment.showTutorial();
}
}
});
Ok, you can delay it as
pager.post(new Runnable() {
#Override
public void run() {
pager.setCurrentItem(position_tab);
// Perform your operations
}
});
I can't found how make animation between two fragments sequential. Is it possible?
For example. I have fragmentA and fragmentB. I can make animation
getSupportFragmentManager.beginTransaction()
.setCustomAnimations(R.anim.fragment_fade_in, R.anim.fragment_fade_out)
.replace(fragmentB)
.commit();
But animations shows together. I need scenario:
remove fragmentA with animation
waiting some ms
add fragmentB with animation
I found solution, but I think it's not good.
Handler mSequentiallyFrgAnimHandler = new Handler(Looper.getMainLooper());
//first remove preview fragment
getSupportFragmentManager().beginTransaction()
.setCustomAnimations(0, R.anim.fragment_fade_out)
.remove(fragmentA)
.commit();
//we need animations sequentially, wait 400ms between animations
mSequentiallyFrgAnimHandler.postDelayed(new Runnable() {
#Override
public void run() {
getSupportFragmentManager().beginTransaction()
.setCustomAnimations(R.anim.fragment_fade_in, 0)
.add(fragmentB)
.commit();
}
}, 400);
Can someone give an example? How does it make correctly?
I have a list of fragments implemented together with FragmentStatePagerAdapter. I must replace the current fragment with a new one each time the button don't like will be clicked. The problem with the ViewPager. In my case the ViewPager scroll exactly list.size() -1 times smoothly, All other scrolling disable the smoothly scrolling.
doNotLike.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
fragmentList.set(viewPager.getCurrentItem(), alternativeList.get(viewPager.getCurrentItem()));
viewPagerAdapter.notifyDataSetChanged();
viewPager.setCurrentItem(currentPos + 1, true);
}
});
I have no idea why the smoothly scrolling is so limited with fragmentList-size and how can I turn off this behaviour.