I have an app based on Android-ViewPagerIndicator.
I would like to create an HorizontalScrollView
in a Fragment
.The view will include some pictures. My problem is that my Scrolling view isn't working beacuse when I'm trying to scroll, I scroll all the fragment and not only the view I want. Hope my question is understandable! :)
This is a part of code:
.xml
<HorizontalScrollView android:id="@+id/horizontalScroll"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scrollbars="none"
android:fadingEdgeLength="10dp">
<LinearLayout
android:id="@+id/harokLayout"
android:background="#EEEEEE"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView android:src="@drawable/app2" android:layout_height="wrap_content" android:layout_width="wrap_content" />
<ImageView android:src="@drawable/app1" android:layout_height="wrap_content" android:layout_width="wrap_content" />
<ImageView android:src="@drawable/app2" android:layout_height="wrap_content" android:layout_width="wrap_content" />
<ImageView android:src="@drawable/app1" android:layout_height="wrap_content" android:layout_width="wrap_content" />
<ImageView android:src="@drawable/app2" android:layout_height="wrap_content" android:layout_width="wrap_content" />
<ImageView android:src="@drawable/app1" android:layout_height="wrap_content" android:layout_width="wrap_content" />
<ImageView android:src="@drawable/app2" android:layout_height="wrap_content" android:layout_width="wrap_content" />
<ImageView android:src="@drawable/app1" android:layout_height="wrap_content" android:layout_width="wrap_content" />
<ImageView android:src="@drawable/app2" android:layout_height="wrap_content" android:layout_width="wrap_content" />
<ImageView android:src="@drawable/app1" android:layout_height="wrap_content" android:layout_width="wrap_content" />
<ImageView android:src="@drawable/app2" android:layout_height="wrap_content" android:layout_width="wrap_content" />
<ImageView android:src="@drawable/app1" android:layout_height="wrap_content" android:layout_width="wrap_content" />
</LinearLayout>
</HorizontalScrollView>
TabPageIndicator:
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
* This widget implements the dynamic action bar tab behavior that can change
* across different configurations or circumstances.
*/
public class TabPageIndicator extends HorizontalScrollView implements PageIndicator {
Runnable mTabSelector;
private OnClickListener mTabClickListener = new OnClickListener() {
public void onClick(View view) {
TabView tabView = (TabView)view;
mViewPager.setCurrentItem(tabView.getIndex());
}
};
private LinearLayout mTabLayout;
private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mListener;
private LayoutInflater mInflater;
int mMaxTabWidth;
private int mSelectedTabIndex;
public TabPageIndicator(Context context) {
this(context, null);
}
public TabPageIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
setHorizontalScrollBarEnabled(false);
mInflater = LayoutInflater.from(context);
mTabLayout = new LinearLayout(getContext());
addView(mTabLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.FILL_PARENT));
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
final boolean lockedExpanded = widthMode == MeasureSpec.EXACTLY;
setFillViewport(lockedExpanded);
final int childCount = mTabLayout.getChildCount();
if (childCount > 1 && (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST)) {
if (childCount > 2) {
mMaxTabWidth = (int)(MeasureSpec.getSize(widthMeasureSpec) ); //edw itan * 0.4f
} else {
mMaxTabWidth = MeasureSpec.getSize(widthMeasureSpec) / 2;
}
} else {
mMaxTabWidth = -1;
}
final int oldWidth = getMeasuredWidth();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int newWidth = getMeasuredWidth();
if (lockedExpanded && oldWidth != newWidth) {
// Recenter the tab display if we're at a new (scrollable) size.
setCurrentItem(mSelectedTabIndex);
}
}
private void animateToTab(final int position) {
final View tabView = mTabLayout.getChildAt(position);
if (mTabSelector != null) {
removeCallbacks(mTabSelector);
}
mTabSelector = new Runnable() {
public void run() {
final int scrollPos = tabView.getLeft() - (getWidth() - tabView.getWidth()) / 2;
smoothScrollTo(scrollPos, 0);
mTabSelector = null;
}
};
post(mTabSelector);
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
if (mTabSelector != null) {
// Re-post the selector we saved
post(mTabSelector);
}
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mTabSelector != null) {
removeCallbacks(mTabSelector);
}
}
private void addTab(String text, int index) {
//Workaround for not being able to pass a defStyle on pre-3.0
final TabView tabView = (TabView)mInflater.inflate(R.layout.vpi__tab, null);
tabView.init(this, text, index);
tabView.setFocusable(true);
tabView.setOnClickListener(mTabClickListener);
mTabLayout.addView(tabView, new LinearLayout.LayoutParams(0, LayoutParams.FILL_PARENT, 1));
}
@Override
public void onPageScrollStateChanged(int arg0) {
if (mListener != null) {
mListener.onPageScrollStateChanged(arg0);
}
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
if (mListener != null) {
mListener.onPageScrolled(arg0, arg1, arg2);
}
}
@Override
public void onPageSelected(int arg0) {
setCurrentItem(arg0);
if (mListener != null) {
mListener.onPageSelected(arg0);
}
}
@Override
public void setViewPager(ViewPager view) {
final PagerAdapter adapter = view.getAdapter();
if (adapter == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
if (!(adapter instanceof TitleProvider)) {
throw new IllegalStateException("ViewPager adapter must implement TitleProvider to be used with TitlePageIndicator.");
}
mViewPager = view;
view.setOnPageChangeListener(this);
notifyDataSetChanged();
}
public void notifyDataSetChanged() {
mTabLayout.removeAllViews();
TitleProvider adapter = (TitleProvider)mViewPager.getAdapter();
final int count = ((PagerAdapter)adapter).getCount();
for (int i = 0; i < count; i++) {
addTab(adapter.getTitle(i), i);
}
if (mSelectedTabIndex > count) {
mSelectedTabIndex = count - 1;
}
setCurrentItem(mSelectedTabIndex);
requestLayout();
}
@Override
public void setViewPager(ViewPager view, int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}
@Override
public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
mSelectedTabIndex = item;
final int tabCount = mTabLayout.getChildCount();
for (int i = 0; i < tabCount; i++) {
final View child = mTabLayout.getChildAt(i);
final boolean isSelected = (i == item);
child.setSelected(isSelected);
if (isSelected) {
animateToTab(item);
}
}
}
@Override
public void setOnPageChangeListener(OnPageChangeListener listener) {
mListener = listener;
}
public static class TabView extends LinearLayout {
private TabPageIndicator mParent;
private int mIndex;
public TabView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void init(TabPageIndicator parent, String text, int index) {
mParent = parent;
mIndex = index;
TextView textView = (TextView)findViewById(android.R.id.text1);
textView.setText(text);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// Re-measure if we went beyond our maximum size.
if (mParent.mMaxTabWidth > 0 && getMeasuredWidth() > mParent.mMaxTabWidth) {
super.onMeasure(MeasureSpec.makeMeasureSpec(mParent.mMaxTabWidth, MeasureSpec.EXACTLY),
heightMeasureSpec);
}
}
public int getIndex() {
return mIndex;
}
}
}
FragmentPagerAdapter2:
import java.util.List;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
class FragmentPagerAdapter2 extends FragmentPagerAdapter implements TitleProvider {
private final List<Fragment> fragments;
/**
* @param fm
* @param fragments
*/
public FragmentPagerAdapter2(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
/*
* (non-Javadoc)
*
* @see android.support.v4.app.FragmentPagerAdapter#getItem(int)
*/
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
/*
* (non-Javadoc)
*
* @see android.support.v4.view.PagerAdapter#getCount()
*/
@Override
public int getCount() {
return this.fragments.size();
}
public String getTitle(int position) {
return MarketAppActivity.CONTENT[position % MarketAppActivity.CONTENT.length].toUpperCase();
}
}
You must create a custom child class of HorizontalScrollView and modify onTouchEvent to intercept the touch event from the fragment if a horizontal swipe is detected.
For example:
public class CustomHorizontalScrollView extends HorizontalScrollView {
...
public void setParent(ViewPager parentView) {
mParentView = parentView;
}
@Override
public synchronized boolean onTouchEvent(MotionEvent event) {
if ((event.getAction() == MotionEvent.ACTION_DOWN) &&
(mParentView != null)) {
mParentView.requestDisallowInterceptTouchEvent(true);
}
return super.onTouchEvent(event);
}
...
}
mParentView is of course a reference to the ViewPager the fragments are attached to. This way, all further actions associated with that particular MotionEvent (ACTION_MOVE and ACTION_UP) will be given to the child HorizontalScrollView, bypassing the ViewPager altogether.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With