3

我想使用选择器来实现ViewPager的简单点指示器。Android选择器更改颜色,但不是大小

当页面被改变时,点应该改变颜色和大小,但它们只是改变颜色,而尺寸保持不变。

选择器:

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

其在布局

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

其在的onCreate使用用于()来显示的初始状态:

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

这看起来如预计:

enter image description here

但是当我改变页面时改变这样的选择状态...

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

..它看起来是这样的:

enter image description here

无效的儿童或ViewGroup不做任何事情。任何线索在这里出了什么问题?

更新

对孩子调用requestLayout修复它,通过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(); 
    } 
} 

回答

4

onPageSelected回调添加requestLayout()电话:

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

编辑:

或者你可以改变你的绘制到所要的相同的尺寸,所以setSelected就够了:

<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

这工作,但有一个轻微颜色和尺寸变化之间的延迟 –

+1

调用'requestLayout()'就像要求Android在'View'上执行布局传递一样。这并不意味着它是即时的。 –

+0

在调用requestLayout()之前在视图上调用'invalidate()'来消除延迟。 –

-1

查看大小的建议被创建时就被测量一次。由于您将ImageView的布局宽度和高度设置为“wrap_content”,因此未选择的圆圈将具有6dp大小,并且其大小不会更改。您可以设置版面宽度和高度“12dp”

顺便说一句,我建议使用指标库而不是实现它。 ViewPagerIndicator是一个很好的

+0

谢谢,但我实际上试图摆脱ViewPagerIndicator,因为它不再维护 –

+1

您可以使用这一个:https://github.com/ugurtekbas/fadingIndicator –

0

尝试这样

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

     } 
    }