3

Ich versuche, einen Selektor zu verwenden, um eine einfache Punktanzeige für einen ViewPager zu implementieren.Android Selector ändert Farbe, aber nicht Größe

Die Punkte sollen die Farbe und Größe ändern, wenn die Seite geändert wird, aber sie ändern nur die Farbe, während die Größe gleich bleibt.

Der Selektor:

<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_selected="true"> 
     <shape android:shape="oval"> 
      <size 
       android:height="12dp" 
       android:width="12dp"/> 
      <solid android:color="@color/highlight"/> 
     </shape> 
    </item> 
    <item> 
     <shape android:shape="oval"> 
      <size 
       android:height="6dp" 
       android:width="6dp"/> 
      <solid android:color="@color/light_grey"/> 
     </shape> 
    </item> 
</selector> 

, die in einem Layout verwendet wird

<ImageView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:padding="@dimen/margin_2x" 
    android:src="@drawable/dot_selector"> 
</ImageView> 

die in onCreate benutzt wird(), um den Ausgangszustand zu zeigen:

for (int i = 0; i < mPagerAdapter.getCount(); i++) { 
    getLayoutInflater().inflate(R.layout.dot_indicator, viewPagerCountDots); 
} 
viewPagerCountDots.getChildAt(0).setSelected(true); 

Dies sieht aus, als erwartet:

enter image description here

Aber wenn ich den Wahlzustand ändern, wenn die Seite wie folgt geändert wird ...

@Override 
public void onPageSelected(int position) { 
    for (int i = 0; i < mPagerAdapter.getCount(); i++) { 
     viewPagerCountDots.getChildAt(i).setSelected(i == position); 
    } 
} 

..es sieht wie folgt aus:

enter image description here

Invalidierung das Kind oder die ViewGroup macht nichts. Irgendeine Ahnung, was hier schief läuft?

aktualisieren

requestLayout Aufruf auf das Kind fixiert es, vorgeschlagen, wie durch Bartek Lipinski

@Override 
public void onPageSelected(int position) { 
    for (int i = 0; i < mPagerAdapter.getCount(); i++) { 
     View dotView = viewPagerCountDots.getChildAt(i); 
     dotView.setSelected(i == position); 
     dotView.invalidate(); 
     dotView.requestLayout(); 
    } 
} 

Antwort

4

requestLayout() Anrufe in Ihrem onPageSelected Rückruf hinzu:

@Override 
public void onPageSelected(int position) { 
    for (int i = 0; i < mPagerAdapter.getCount(); i++) { 
     viewPagerCountDots.getChildAt(i).setSelected(i == position); 
     viewPagerCountDots.getChildAt(i).requestLayout(); 
    } 
} 

EDIT:

alternativ können Sie Ihre ziehbar immer haben ändern die gleiche Größe, so dass die setSelected ist genug:

<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_selected="true"> 
     <shape android:shape="oval"> 
      <size 
       android:width="12dp" 
       android:height="12dp"/> 
      <solid android:color="@color/highlight"/> 
     </shape> 
    </item> 
    <item> 
     <layer-list> 
      <item android:bottom="3dp" 
        android:left="3dp" 
        android:right="3dp" 
        android:top="3dp"> 
       <shape android:shape="oval"> 
        <size 
         android:width="6dp" 
         android:height="6dp"/> 
        <solid android:color="@color/light_grey"/> 
       </shape> 
      </item> 
     </layer-list> 
    </item> 
</selector> 
+0

Dies funktioniert, aber es gibt eine leichte Verzögerung zwischen der Farbe und der Größenänderung –

+1

Der Aufruf von 'requestLayout()' ist so, als würde man Android bitten, einen Layout-Durchlauf auf einer 'View' durchzuführen. Es bedeutet nicht, dass es sofort ist. –

+0

Der Aufruf von 'invalidate()' in der Sicht vor dem Aufruf von 'requestLayout()' entfernt die Verzögerung. –

-1

Größen anzeigen einmal gemessen werden, wenn sie erstellt werden. Da Sie die Layoutbreite und -höhe von ImageView auf "wrap_content" festlegen, haben nicht ausgewählte Kreise eine Größe von 6 dpi und ihre Größe ändert sich nicht. Sie können die Breite und Höhe des Layouts "12dp" einstellen.

BTW, ich schlage vor, eine Bibliothek für Indikator zu verwenden, anstatt es zu implementieren. ViewPagerIndicator ist gut

+0

Danke, aber ich versuche tatsächlich weg von ViewPagerIndicator zu bekommen, da es nicht mehr gehalten wird –

+1

Sie können dieses verwenden: https://github.com/ugurtekbas/fadingIndicator –

0

versuchen, wie diese

//if you container is LinearLayout ,change to LinearLayout.params 
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); 
    //as you wish 
    params.width=200; 
    params.height=200; 
    @Override 
    public void onPageSelected(int position) { 
     for (int i = 0; i < mPagerAdapter.getCount(); i++) { 
      ImageView dotIv= (ImageView)viewPagerCountDots.getChildAt(i); 
      dotIv.setImageResource("//normalPic"); 
      if(i==position){ 
       dotIv.setImageResource("//selectPic"); 
       dotIv.setLayoutParams(params); 
      } 

     } 
    }