2014-05-09 12 views
5

Podążałem za odpowiedziami this i that, znalazłem także link this.Viewpager z dynamiczną wysokością nie działa (zawsze używaj wysokości pierwszego fragmentu)

Używam tych zasobów, aby wykonać próbne błędy &. Teraz mój niestandardowy ViewPager z powodzeniem mierzy zawartość, , ale tylko pierwsza wyświetlana. FYI, mój ViewPager posiada pewne skomplikowane widoki, takie jak ExpendableListView - to dlatego żaden kod w tych zasobach nie działa idealnie, muszę zmodyfikować kod sam.

Mam 4 fragmenty (treść), więc używam pager.setOffscreenPageLimit(3);

To jest mój zwyczaj ViewPager:

public class CustomViewPager extends ViewPager{ 

    public CustomViewPager (Context context) { 
     super(context); 
    } 

    public CustomViewPager (Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    @Override 
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

     boolean wrapHeight = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST; 

     final View tab = getChildAt(0); 
     int width = getMeasuredWidth(); 
     int tabHeight = tab.getMeasuredHeight(); 

     if (wrapHeight) { 
      // Keep the current measured width. 
      widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); 
     } 

     int fragmentHeight = measureFragment(((Fragment) getAdapter().instantiateItem(this, getCurrentItem())).getView()); 
     heightMeasureSpec = MeasureSpec.makeMeasureSpec(tabHeight + fragmentHeight + (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics()), MeasureSpec.AT_MOST); 

     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    } 

    public int measureFragment(View view) { 
     if (view == null) 
      return 0; 

     view.measure(0, 0); 
     return view.getMeasuredHeight(); 
    } 
} 

To jest mój CustomPagerTabStrip:

int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST); 
super.onMeasure(widthMeasureSpec, expandSpec); 
android.view.ViewGroup.LayoutParams params = getLayoutParams(); 
params.height = getMeasuredHeight(); 

I to jest mój XML :

 <RelativeLayout 
      android:id="@+id/relativePager" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" > 

      <com.xxx.yyy.util.CustomViewPager 
       android:id="@+id/detailPager" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" > 

       <com.xxx.yyy.util.CustomPagerTabStrip 
        android:id="@+id/detailTab" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:background="#161C28" 
        android:textColor="#FFFFFF" /> 
      </com.xxx.yyy.util.CustomViewPager> 

     </RelativeLayout> 

przykładowym przypadku:

Jeśli wysokość pierwszy fragment jest 100px, to wszystkie inne fragmenty będą pozostawać na 100px. Jeśli więc wysokość drugiego fragmentu wynosi 130 pikseli, zostanie ono przycięte do 100 pikseli.

Kiedy próbowałem debugowania The onMeasure na moich CustomViewPager zawsze zwanych 4 razy, gdy Activity jest tworzony, ale wszystkie z nich odczytać tylko pierwszego fragmentu. nie można uzyskać ponownie po tym, nawet jeśli zmieniam (przesuń w lewo/w prawo) z jednego fragmentu na inny.

Proszę mi pomóc, poświęciłem wiele godzin, aby to zadziałało. Po prostu zapytaj mnie, czy potrzebujesz więcej informacji, dziękuję za poświęcony czas.

+0

Proszę o pomoc? –

+0

Witam lubię wiedzieć, jak rozwiązać ten problem .. –

+0

@RenjithKN Niestety nie udało mi się rozwiązać tego problemu, więc używam innego podejścia (nie używając jakiegoś złożonego widoku w widoku pagera) :( –

Odpowiedz

14

Cześć Blaze znalazła coś, co jest pełne, rozwiązanie działa dla mnie.

Zawiera on niestandardowy widok przewijania i niestandardowy widok pagera. Zadaniem pager'a zindywidualizowanego jest dynamiczne obliczanie wysokości w zależności od wysokości jego dzieci, jego celem jest początkowe zawijanie zawartości, a celem przewijania jest obsługa zdarzenia dotykowego, jeśli użytkownicy przewijają ekran w pionie, to nie przejdzie on przez dotyk nawet do przewijania, dzięki czemu użytkownik może przewijać stronę.

widok klienta przewijania

public class CustomScrollView extends ScrollView { 

private GestureDetector mGestureDetector; 

public CustomScrollView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    mGestureDetector = new GestureDetector(context, new YScrollDetector()); 
    setFadingEdgeLength(0); 
} 

@Override 
public boolean onInterceptTouchEvent(MotionEvent ev) { 
    return super.onInterceptTouchEvent(ev) 
      && mGestureDetector.onTouchEvent(ev); 
} 

// Return false if we're scrolling in the x direction 
class YScrollDetector extends SimpleOnGestureListener { 
    @Override 
    public boolean onScroll(MotionEvent e1, MotionEvent e2, 
      float distanceX, float distanceY) { 
     return (Math.abs(distanceY) > Math.abs(distanceX)); 
    } 
} 
} 

widok klienta pager

public class CustomPager extends ViewPager{ 

public CustomPager (Context context) { 
    super(context); 
} 

public CustomPager (Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

@Override 
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

    boolean wrapHeight = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST; 

    final View tab = getChildAt(0); 
    int width = getMeasuredWidth(); 
    int tabHeight = tab.getMeasuredHeight(); 

    if (wrapHeight) { 
     // Keep the current measured width. 
     widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); 
    } 

    int fragmentHeight = measureFragment(((Fragment) getAdapter().instantiateItem(this, getCurrentItem())).getView()); 
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(tabHeight + fragmentHeight + (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics()), MeasureSpec.AT_MOST); 

    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
} 

public int measureFragment(View view) { 
    if (view == null) 
     return 0; 

    view.measure(0, 0); 
    return view.getMeasuredHeight(); 
} 
} 

plik Układ

<com.example.demo2.activity.widget.CustomScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" > 

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical" > 

    <TextView 
     style="@style/text" 
     android:text="Text 1" /> 

    <View style="@style/text_divider" /> 

    <TextView 
     style="@style/text" 
     android:text="Text 2" /> 


     <com.example.demo2.activity.widget.CustomPager 
      android:id="@+id/myViewPager" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" /> 

    <View style="@style/text_divider" /> 

    <TextView 
     style="@style/text" 
     android:text="Text 4" /> 

    <View style="@style/text_divider" /> 

    <TextView 
     style="@style/text" 
     android:text="Text 5" /> 

    <View style="@style/text_divider" /> 

    <TextView 
     style="@style/text" 
     android:text="Text 6" /> 

    <View style="@style/text_divider" /> 

    <TextView 
     style="@style/text" 
     android:text="Text 7" /> 

    <View style="@style/text_divider" /> 

    <TextView 
     style="@style/text" 
     android:text="Text 8" /> 

    <View style="@style/text_divider" /> 

    <TextView 
     style="@style/text" 
     android:text="Text 9" /> 

    <View style="@style/text_divider" /> 

    <TextView 
     style="@style/text" 
     android:text="Text 10" /> 
</LinearLayout> 

aktywny

public class MainActivity extends FragmentActivity { 



@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.activity_main); 

    MyPagerAdapter pageAdapter = new MyPagerAdapter(getSupportFragmentManager()); 
    ViewPager pager = (ViewPager)findViewById(R.id.myViewPager); 
    pager.setAdapter(pageAdapter); 

} 



} 

adapter Fragment

fragmenty o różnych wysokościach są dodawane do viewpager, FragmentBlue, zielony itp są tylko fragmenty używanego dodać do viewpager można użyć własnych Fragmenty, jedną rzeczą do zapamiętania jest to, że ich zewnętrzny układ powinien być taki sam w moim przypadku Zastosowałem układ liniowy dla wszystkich

public class MyPagerAdapter extends FragmentPagerAdapter { 

private List<Fragment> fragments; 

public MyPagerAdapter(FragmentManager fm) { 
    super(fm); 
    this.fragments = new ArrayList<Fragment>(); 
    fragments.add(new FragmentBlue()); 
    fragments.add(new FragmentGreen()); 
    fragments.add(new FragmentPink()); 
    fragments.add(new FragmentRed()); 
} 

@Override 
public Fragment getItem(int position) { 
    return fragments.get(position); 
} 

@Override 
public int getCount() { 
    return fragments.size(); 
} 
} 
+0

Wielkie dzięki! Może będę potrzebował tego w przyszłości: D –

+0

OMG !!!! Dziękuję bardzo!!!! ;) – juliobetta

+0

nie działa. Mają ten sam kod tutaj https://github.com/VihaanVerma89/DynamicViewPager –

3
public CustomPager (Context context) { 
    super(context); 
} 

public CustomPager (Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

int getMeasureExactly(View child, int widthMeasureSpec) { 
    child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 
    int height = child.getMeasuredHeight(); 
    return MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); 
} 

@Override 
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    boolean wrapHeight = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST; 

    final View tab = getChildAt(0); 
    if (tab == null) { 
     return; 
    } 

    int width = getMeasuredWidth(); 
    if (wrapHeight) { 
     // Keep the current measured width. 
     widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); 
    } 
    Fragment fragment = ((Fragment) getAdapter().instantiateItem(this, getCurrentItem())); 
    heightMeasureSpec = getMeasureExactly(fragment.getView(), widthMeasureSpec); 

    //Log.i(Constants.TAG, "item :" + getCurrentItem() + "|height" + heightMeasureSpec); 
    // super has to be called again so the new specs are treated as 
    // exact measurements. 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
} 
Powiązane problemy