如何为tabLayout点设置动画

时间:2017-08-22 08:29:45

标签: android animation android-tablayout

我有一个像tabLayout这样的viewPager:

Dots

我需要在使用放大动画(将选定的点缩放到原始大小)时滑动页面来设置点动画。

我的TabLayout元素包含 app:tabBackground 可绘制的xml文件:

<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/on"
        android:drawable="@drawable/selected_dot"
        android:state_selected="true" />

    <item
        android:id="@+id/off"
        android:drawable="@drawable/default_dot" />

    <transition
        android:fromId="@id/off"
        android:toId="@+id/on">
        <animation-list>
            <!-- here I stuck -->
        </animation-list>
    </transition>
</animated-selector>

tabLayout以这种方式与viewPager连接:

tabLayout.setupWithViewPager(viewPager);

点只是一个形状元素,因此 selected_dot.xml 如下所示:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
    <shape
        android:innerRadius="0dp"
        android:shape="ring"
        android:thickness="8dp"
        android:useLevel="false">
        <solid android:color="#FFFFFF"/>
    </shape>
</item>

我认为我需要动画资源文件来创建放大和缩小动画,所以我创建了 scale.xml 文件作为动画资源

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true" >
    <scale
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="1000"
        android:fromXScale="0.5"
        android:fromYScale="0.5"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1"
        android:toYScale="1" >
    </scale>
</set>

但是我可以将它应用到点?我以为我可以在tabLayout drawable中的 transition 标签内添加动画,但没有成功。我也尝试在viewPager的onPageChangeListener中以编程方式进行,但我不知道如何将形状(选定点)表示为开始动画的视图。我试过tabLayout.getTabAt(position).getCustomView().startAnimation(...);但getCustomView()返回null。

感谢您的帮助,对不起我的英语!

3 个答案:

答案 0 :(得分:0)

看看我建议您使用其他较小(取消选择)的点制作较大(选定)点的每个实例的不同图像,并使用ImageView设置这些图像...... 现在每次更改ViewPager时都会相应地更改图像...

希望它有所帮助...

答案 1 :(得分:0)

你可以试试这个

<强> 1。在您的视图寻呼机下方添加一个线性布局,如

<android.support.v4.view.ViewPager
    android:id="@+id/view_pager"
    android:layout_width="wrap_content"
    android:layout_marginTop="160dp"
    android:layout_marginBottom="190dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal|center">

</android.support.v4.view.ViewPager>

    <LinearLayout
       android:id="@+id/viewPagerCountDots"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_centerHorizontal="true"
       android:layout_gravity="bottom|center"
       android:layout_marginTop="-20dp"
       android:gravity="center"
       android:orientation="horizontal" />

<强> 2。像这样选择和未选择两个图像拇指

<强> nonselected_thumb

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" android:useLevel="true"
    android:dither="true">

    <size android:height="6dip" android:width="6dip"/>

    <solid android:color="@color/colorPrimaryDark"/>
</shape>

选中的拇指

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" android:useLevel="true"
    android:dither="true">

    <size android:height="12dip" android:width="12dip"/>

    <solid android:color="@color/colorPrimary"/>
</shape>

现在在你的java文件中添加此代码

声明您的变量

private LinearLayout pager_indicator;
private int dotsCount;
private ImageView[] dots;

在onCreate()方法中添加此代码

setIndicator();

 viewPager = (ViewPager) findViewById(R.id.view_pager);
    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            for (int i = 0; i < dotsCount; i++) {
                dots[i].setImageDrawable(getResources().getDrawable(R.drawable.nonselected_item));
            }
            dots[position].setImageDrawable(getResources().getDrawable(R.drawable.selected_item));
        }

        @Override
        public void onPageSelected(int position) {

        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });

现在像这样创建setIndicator()方法

private void setIndicator() {

pager_indicator = (LinearLayout) findViewById(R.id.viewPagerCountDots);
dotsCount = adapter.getCount();
dots = new ImageView[dotsCount];

for (int i = 0; i < dotsCount; i++) {
    dots[i] = new ImageView(this);
    dots[i].setImageDrawable(getResources().getDrawable(R.drawable.nonselected_item));

    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT
    );

    params.setMargins(4, 0, 4, 0);

    pager_indicator.addView(dots[i], params);
 }   

     dots[0].setImageDrawable(getResources().getDrawable(R.drawable.selected_item));
}

如果有任何疑问,请询问我

答案 2 :(得分:0)

谢谢你的问题,我终于找到了一个可能不是那么完美但完全正常工作的解决方案。现在所有的点都有相同的xml布局(selected_dot.xml),我通过缩放来调整点的大小

        tabLayout = findViewById(R.id.tab_layout) as TabLayout
        tabLayout.setupWithViewPager(viewPager)


        val vg = tabLayout.getChildAt(0) as ViewGroup

        tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
            override fun onTabSelected(tab: TabLayout.Tab) {
                val a = vg.getChildAt(tab.position)
                a.animate()
                        .scaleX(1f)
                        .scaleY(1f)
                        .setInterpolator(FastOutSlowInInterpolator())
                        .setDuration(resources.getInteger(android.R.integer.config_mediumAnimTime).toLong())
                        .start()
            }

            override fun onTabUnselected(tab: TabLayout.Tab) {
                val a = vg.getChildAt(tab.position)
                a.animate()
                        .scaleX(0.5f)
                        .scaleY(0.5f)
                        .setInterpolator(FastOutSlowInInterpolator())
                        .setDuration(1)  // See explanation below
                        .start()
            }

            override fun onTabReselected(tab: TabLayout.Tab) {
            }
        })

我不需要动画取消选择所以我制作持续时间为1ms的动画。我不知道为什么,但简单

a.clearAnimation()
a.scaleX = 0.5f
a.scaleY = 0.5f

给了我错误。所以我选择1ms动画。 由于所有点都使用selected_dot.xml布局,我需要在用户启动活动时缩小2,3和4个位置上的点

private fun initializeDots() {
    val vg = tabLayout.getChildAt(0) as ViewGroup
    for (i in 0 until vg.childCount) {
        if (i == tabLayout.selectedTabPosition) {
            continue
        }
        val a = vg.getChildAt(i)
        a.scaleX = 0.5f
        a.scaleY = 0.5f
    }

我可能应该在 onCreate 方法中调用它,但vg.childCount会返回0。因此我在 onResume 中调用此函数。 它现在很完美。