Reputation: 1281
I want to create a horizontal scrollable ViewPager. My ViewPager contains Fragments. Each Fragment's width is larger than the screen so scrolling has to be enabled.
I use following layout for my fragment item:
<HorizontalScrollView
android:id="@+id/view_horizontal_scroll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:isScrollContainer="true" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<View
android:layout_width="100dp"
android:layout_height="fill_parent"
android:background="#AABBCC" />
<View
android:id="@+id/test"
android:layout_width="1500dp"
android:layout_height="fill_parent" />
<View
android:layout_width="100dp"
android:layout_height="fill_parent"
android:background="#ccBBaa" />
</LinearLayout>
</HorizontalScrollView>
I also created a custom ViewPager which allows horizontal scrolling:
public class ScrollableViewPager extends ViewPager {
private GestureDetector mGestureDetector;
public ScrollableViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
mGestureDetector = new GestureDetector(getContext(),
new YScrollDetector());
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// Tell our parent to stop intercepting our events!
getParent().requestDisallowInterceptTouchEvent(true);
return super.onInterceptTouchEvent(ev)
&& mGestureDetector.onTouchEvent(ev);
}
}
The YScrollDetector only overwrites the onScrollMethod. So far so good. Horizontal Scrolling works fine.
But now I have a problem:
Let's say I have a ViewPager with 5 Fragments, ([0], [1], [2], [3], [4]) in it and want to start with item [2]. When I siwpe backwards I want that the scroll position of the previous item [1] is at right maximum and not 0.
My Framgents look like this:
public class AbstractFragment extends Fragment {
private static final String _ID = "ID";
private int _id;
private ScrollableViewPager mPager;
public AbstractFragment() {
}
public AbstractFragment(int id, int colorId) {
this._id = id;
}
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d(getClass().getSimpleName(), "[" + _id + "]: onCreate");
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
_id = savedInstanceState.getInt(_ID);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View fragmentView = inflater.inflate(R.layout.fragment_menu_container,
container, false);
setUpScrollView(fragmentView);
return fragmentView;
}
@Override
public void onResume() {
Log.d(getClass().getSimpleName(), "[" + _id + "]: onResume");
setUpScrollView(getView());
super.onResume();
}
private void setUpScrollView(View fragmentView) {
if (fragmentView == null) {
return;
}
HorizontalScrollView scrollView = (HorizontalScrollView) fragmentView
.findViewById(R.id.view_horizontal_scroll);
if (scrollView != null) {
int currentItem = getCurrentPagerItem();
if (_id < currentItem) {
// previous Item : X Scroll: width of content
View content = scrollView.getChildAt(0);
int width = content.getRight();
width = width - scrollView.getRight();
scrollView.scrollTo(width, 0);
Log.d(getClass().getSimpleName(), "[" + _id + "] width: "
+ width);
// scrollView.fullScroll(View.FOCUS_RIGHT);
} else if (_id > currentItem) {
// next Item - X Scroll: 0
scrollView.fullScroll(View.FOCUS_LEFT);
} else {
// current Item - Nothing to do her
}
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (outState == null) {
return;
}
outState.putInt(_ID, _id);
}
private ScrollableViewPager getPager() {
PagerActivity activity = (PagerActivity) getActivity();
return activity.getViewPager();
}
private int getCurrentPagerItem() {
if (mPager == null) {
mPager = getPager();
}
return mPager.getCurrentItem();
}
}
In my fragments I want to set the scroll position of the previous fragment. But this doesn't work, because the width of the ScrollView and the ContentView are both 0.
Does anybody know an answer? Thanks!!!
Upvotes: 1
Views: 2981
Reputation: 1281
I found a solution by myself:
private void setUpScrollView(final ViewGroup fragmentView) {
if (fragmentView == null) {
return;
}
fragmentView.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
HorizontalScrollView scrollView = (HorizontalScrollView) fragmentView
.findViewById(R.id.view_horizontal_scroll);
if (scrollView != null) {
int currentItem = getCurrentPagerItem();
if (_id < currentItem) {
// previous Item
View content = scrollView.getChildAt(0);
int width = content.getWidth();
width = width - scrollView.getWidth();
scrollView.scrollTo(width, 0);
} else if (_id > currentItem) {
// next Item
scrollView.scrollTo(0, 0);
} else {
// current Item
}
}
}
});
}
Upvotes: 2