2014-05-09 8 views
5

Ich habe this und that Antworten verfolgt, ich fand auch this Link.Viewpager mit dynamischer Höhe funktioniert nicht (verwenden Sie immer die Höhe des ersten Fragments)

Ich verwende diese Ressourcen, um & Fehler zu testen. Jetzt meine ViewPager erfolgreich messen ihren Inhalt, , aber nur die erste angezeigt. FYI, meine ViewPager hält einige komplexe Ansichten, wie ExpendableListView - das ist, warum keiner der Code in diesen Ressourcen perfekt funktioniert, muss ich den Code selbst ändern.

Ich habe 4 Fragmente (Inhalt), so dass ich verwenden pager.setOffscreenPageLimit(3);

Das ist mein Brauch ist 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(); 
    } 
} 

Das ist mein 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(); 

Und das ist mein 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> 

Beispielfall:

Wenn die Höhe des ersten Fragments 100 Pixel ist, dann werden alle anderen Fragmente werden auf 100 Pixel bleiben. Wenn also die Höhe des zweiten Fragments 130px beträgt, wird es auf 100px geschnitten.

Als ich versuchte, zu debuggen, die onMeasure auf meinem CustomViewPager immer 4 Mal aufgerufen, wenn der Activity erstellt wird, aber alle von ihnen nur das erste Fragment lesen. Die onMeasurenie wieder danach aufgerufen werden, auch wenn ich (von links nach rechts wechseln) von einem Fragment zum anderen.

Bitte helfen Sie mir, ich habe viele Stunden ausgegeben, um dieses Ding zum Laufen zu bringen. Fragen Sie mich einfach, wenn Sie weitere Informationen benötigen, Danke für Ihre Zeit.

+0

Irgendwelche Hilfe bitte? –

+0

Hallo Ich möchte wissen, wie Sie das Problem lösen .. –

+0

@RenjithKN Leider konnte ich dieses Problem nicht lösen, also verwende ich andere Ansatz (nicht mit einigen komplexen Ansicht in der Ansicht Pager) :( –

Antwort

14

Hallo Blaze fand etwas Verwendung voll, folgende Lösung funktioniert für mich.

Es enthält eine benutzerdefinierte Bildlaufansicht und benutzerdefinierte Ansicht Pager. Der Zweck der benutzerdefinierten Ansicht Pager ist seine Höhe dynamisch nach der Höhe seiner Kinder berechnen, ist seine Höhe festgelegt, um Inhalt zunächst umbrechen und der Zweck der Bildlaufleiste ist die Berührung Ereignis, wenn die Benutzer den Bildschirm vertikal scrollen wird es nicht die Berührung übergeben sogar zum Scrollen und somit kann der Benutzer die Seite scrollen.

Benutzerdefinierte Ansicht blättern

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)); 
    } 
} 
} 

Benutzerdefinierte Ansicht 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(); 
} 
} 

Layout-Datei

<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> 

Aktivität

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); 

} 



} 

Fragment Adapter

Fragmente mit unterschiedlichen Höhen an den viewpager hinzugefügt, FragmentBlue, Grün usw. werden nur verwendet, um Fragmente zu dem viewpager hinzufügen Sie Ihre eigenen verwenden können Fragmente, eine Sache zu erinnern ist ihre äußere Layout sollte das gleiche in meinem Fall habe ich Liner Layout für alle

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

Vielen Dank! Ich könnte das in der Zukunft brauchen: D –

+0

OMG !!!! Ich danke dir sehr!!!! ;) – juliobetta

+0

hat nicht funktioniert. Haben Sie den gleichen Code hier 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); 
} 
Verwandte Themen