2013-04-25 6 views
14

Ich muss die untergeordnete Ansicht als Mitte des ViewPager und auch möchte ich einige Teil der nächsten und vorherigen Ansichten zu den aktuellen Ansichten Seiten zeigen (wie aktuelle Bildschirm unten 1). Derzeit wird die aktuelle Ansicht jedoch auf der linken Seite des ViewPagers gestartet (wie bei dem erwarteten Bildschirm unter 2). Wie kann ich das erreichen?Richten Sie die Kinderansichten in der Mitte des ViewPagers android

Hier ist mein Code ..

MyViewPagerAdapter

public class MyViewPagerAdapter extends PagerAdapter { 
    private Activity mActivity; 
    private int mPageCount; 
    public MyViewPagerAdapter(Activity activity,int pageCount) { 
     mActivity = activity; 
     mPageCount = pageCount; 
    } 

    @Override 
    public int getCount() { 
     return mPageCount; 
    } 

    @Override 
    public boolean isViewFromObject(View view, Object obj) { 
     return (view ==(View)obj); 
    } 

    @Override 
    public Object instantiateItem(ViewGroup container,final int position) { 
     ViewGroup viewGroup = (ViewGroup)mActivity.getLayoutInflater().inflate(
       R.layout.item_view, null); 

     viewGroup.setBackgroundColor(randomColor()); 

     TextView textView = (TextView)viewGroup.findViewById(R.id.textView1); 
     textView.setText("Page: "+(position+1)); 
     Button button = (Button) viewGroup.findViewById(R.id.button1); 
     button.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       Toast.makeText(mActivity, "Hey, Its clicked!!! at page "+(position+1), Toast.LENGTH_LONG).show(); 
      } 
     }); 
     container.addView(viewGroup); 
     return viewGroup; 
    } 

    Random rnd = new Random(); 
    private int randomColor(){ 
     return Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256)); 
    } 

    @Override 
    public void destroyItem(ViewGroup collection, int position, Object view) { 
     //must be overridden else throws exception as not overridden. 
     Log.d("Tag", collection.getChildCount()+""); 
     collection.removeView((View) view); 
    } 

    @Override 
    public float getPageWidth(int position) { 
     return 0.8f; 
    } 
} 

MainActivity

public class MainActivity extends Activity { 
    private ViewPager viewPager; 
    LinearLayout linearLayout; 
    private int ID = 100; 

    private final int count = 8; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     viewPager = (ViewPager) findViewById(R.id.viewPager); 
     linearLayout = (LinearLayout) findViewById(R.id.indicator_layout); 
     generateIndicators(count); 


     MyViewPagerAdapter adapter = new MyViewPagerAdapter(this, count); 
     viewPager.setAdapter(adapter); 
     viewPager.setOnPageChangeListener(new OnPageChangeListener() { 
      int oldPosition = 0; 
      @Override 
      public void onPageSelected(int position) { 
       //this changes the old position's view state image 
       ((TextView)linearLayout.getChildAt(oldPosition)).setText(""); 
       oldPosition = position; 


       //this changes the current position's view state image 
       ((TextView)linearLayout.getChildAt(position)).setText((position+1)+""); 

      } 
      //this method will be called repeatedly upto another item comes as front one(active one) 
      @Override 
      public void onPageScrolled(int arg0, float arg1, int arg2) { 


      } 
      //this will be called as per scroll state 
      @Override 
      public void onPageScrollStateChanged(int arg0) { 


      } 
     }); 

     viewPager.setOffscreenPageLimit(4); 

    } 

    private void generateIndicators(int count) { 
     /// Converts 14 dip into its equivalent px 
     int padd = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, getResources().getDisplayMetrics()); 

     for(int i=0;i<count;i++){ 
      TextView textView = new TextView(this); 
      textView.setId(ID+i); 
      final int currentItem = i; 
      textView.setBackgroundResource(R.drawable.white_cell); 
      textView.setPadding(padd,padd,padd,padd); 
      /// Converts 14 dip into its equivalent px 
      int size = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics()); 
      textView.setTextSize(size); 
      textView.setGravity(Gravity.CENTER); 
      /// Converts 14 dip into its equivalent px 
      int px = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, getResources().getDisplayMetrics()); 

      LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(px, px); 
      linearLayout.addView(textView,params); 
     } 

     ((TextView)linearLayout.getChildAt(0)).setText("1"); 

    } 





} 

activity_main.xml

<RelativeLayout 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" 
    tools:context=".MainActivity" > 



    <android.support.v4.view.ViewPager 
     android:id="@+id/viewPager" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentTop="true" > 
    </android.support.v4.view.ViewPager> 


    <LinearLayout 
     android:id="@+id/indicator_layout" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:layout_centerHorizontal="true" 
     android:layout_marginBottom="19dp" > 
    </LinearLayout> 

</RelativeLayout> 

item_view.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="100dp" 
    android:layout_height="match_parent" 
    android:id="@+id/root_view" 
    android:orientation="vertical" > 

    <TextView 
     android:id="@+id/textView1" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:gravity="center" 
     android:text="Text" 
     android:textAppearance="?android:attr/textAppearanceLarge" /> 

    <Button 
     android:id="@+id/button1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:text="click me" /> 

</LinearLayout> 

Aktuelle Bildschirm Current screen

erwartet Bildschirm expected screen

+0

Ich habe dies jetzt getan, indem ich den ViewPager angepasst habe. – Noundla

+0

Hast du es geschafft? Ich habe die gleiche Frage @noundla – Jacky

+0

ja. Geben Sie mir Ihre Mail-ID, ich kann es an Sie senden. – Noundla

Antwort

6

Endlich habe ich meine Lösung für diese Frage in GitHub hinzugefügt. Ich habe ein paar Tricks gemacht, um die Lösung zu finden. Sie können das Projekt über den folgenden Link erhalten (Eigentlich habe ich geplant, einen Blog mit der Erklärung zu erstellen, aber ich habe so viel Zeit zu tun).

Hier ist die link (https://github.com/noundla/Sunny_Projects/tree/master/CenterLockViewPager)

Sie haben die Dateien aus com.noundla.centerviewpagersample.comps Paket zu einem Projekt zu kopieren. Und Sie können die Verwendung dieses Viewpager in MainActivity Klasse sehen.

Bitte lassen Sie mich wissen, wenn jemand Probleme damit hat.

9

Für eine app, die ich ähnlich der folgenden Art und Weise umgesetzt werden, mit Standard ViewPager:

  • Make Seiten im Vollbildmodus mit dem tatsächlichen Inhalt in einem inneren Layout. Zum Beispiel, machen Sie das Vollbild-Layout eine RelativeLayout mit transparentem Hintergrund und der eigentliche Inhalt eine andere RelativeLayout zentriert in der Eltern. Wenn ich mich recht erinnere, lag der Grund dafür darin, dass mit nur dem inneren Layout als Seite die ViewPager nicht die gesamte Bildschirmbreite auf einigen Geräten wie Galaxy Nexus genommen hätte.

  • Verwenden Sie ViewPager.setPageMargin(), um einen negativen Seitenrand einzurichten, d. H. Wie viel von der nächsten/vorherigen Seite, die Sie anzeigen möchten. Stellen Sie sicher, dass es nur den transparenten Bereich des übergeordneten Vollbildlayouts überlappt.

  • Anruf ViewPager.setOffscreenPageLimit() die Off-Screen-Seitenanzahl auf mindestens 2 aus dem Standard 1 einen reibungslosen Paging durch wirklich die Erstellung der Seiten aus dem Bildschirm anzupassen. Andernfalls werden die nächsten/vorherigen Seiten gezeichnet, während sie bereits teilweise auf dem Bildschirm angezeigt werden. Verlängern

+0

Danke für Ihre Antwort. Ich glaube nicht, dass dies zu dem Ergebnis führen kann, wie ich es erwarte, denn diese Ansichten sollten nicht mitkommen, wenn wir die Marge angeben. Dies habe ich jedoch getan, indem ich die Methode scrollToItem() in der ViewPager-Klasse angepasst habe. Ich sollte meine ViewPager-Klasse veröffentlichen, aber es hat mehr Zeichen, daher kann ich die Antwort hier nicht posten. Ich möchte diese Frage schließen. – Noundla

+0

So habe ich es aber mit FrameLayouts gemacht. Diese Idee bestand darin, mit getPageWidth() aufzuhören (lassen Sie es auf 1.0f) und verwenden Sie den negativen Rand, um die angrenzenden Seiten einzubringen. In meinem Seitenlayout verwendete ich ein root-FrameLayout (Params sind nicht so wichtig, weil sie vom ViewPager gesetzt werden) und ein untergeordnetes FrameLayout mit fester Breite, in das ich den gesamten Seiteninhalt legte. Dann würde ich in meiner Aktivität den negativen Rand wie folgt berechnen: margin = viewpager.getWidth() - pageWidth; viewpager.setPageMargin (-margin); Dabei ist pageWidth die feste Breite des untergeordneten FrameLayout I, das oben angegeben wurde – Lumbi

-2

HorizontalScrollView Klasse, die als Eltern für die Scroll-Ansicht. In der Methode onMeasure() können Sie die Breite und Höhe jedes untergeordneten Objekts angeben. Kleiner umständlicher Weg, aber der Effekt wird gut sein und du kannst deine Kinderansicht gut im Griff haben.

8

Für alle aufgeregt, dass die OP nicht aktualisiert seine Frage mit der Lösung hier ist ein Link, mit minimalem Aufwand erklärt, wie diese in XML ziehen aus: http://blog.neteril.org/blog/2013/10/14/android-tip-viewpager-with-protruding-children/

Grundsätzlich, wenn Sie Ihre viewpager erklären in XML, gib ihm die gleiche linke und rechte Auffüllung und setze android: clipToPadding = "false". (Der clipToPadding fehlt in seiner XML-Probe und ist notwendig, um diesen Effekt zu erzielen)

0

musste ich Zentrum der aktuelle Seite im Hinblick Pager mit verschiedenen Seitenbreiten, so Lösung mit Polsterungen war nicht geeignet. Auch das Scrollen von Benutzern war deaktiviert (es war ein Tab-Bar-Pager, der von einem anderen View-Pager gescrollt wurde). Hier ist eine sehr einfache Lösung zu tun, dass - außer Kraft setzen nur ViewPager.ScrollTo Methode wie diese (C# -Code, Xamarin):

public override void ScrollTo(int x, int y) 
{ 
    x -= (int) (MeasuredWidth * (1 - Adapter.GetPageWidth(CurrentItem))/2); 

    base.ScrollTo(x, y); 
} 

Und wenn Sie Seitenbreite für jedes Fragment berechnen vergessen Sie nicht, sie cachen in Array.