【问题标题】:How to animate tabLayout dots如何为 tabLayout 点设置动画
【发布时间】:2018-01-30 10:40:21
【问题描述】:

我有一个带有 tabLayout 的 viewPager,如下所示:

滑动页面时我需要动画点动画放大动画(将选定的点缩放到她的原始大小)。

我有带有 app:tabBackground 可绘制 xml 文件的 TabLayout 元素:

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

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

【问题讨论】:

    标签: android animation android-tablayout


    【解决方案1】:

    感谢您的回答,我终于找到了一个可能不是那么完美但完全有效的解决方案。现在所有点都有相同的 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) {
                }
            })
    

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

    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 中调用此函数。 现在完美运行。

    【讨论】:

      【解决方案2】:

      看看我的建议是,您将较大(选定)点的每个实例与其他较小(未选定)点制作不同的图像,并使用 ImageView 设置这些图像... 现在随着 ViewPager 的每次更改相应地更改图像...

      希望对你有帮助...

      【讨论】:

        【解决方案3】:

        你可以试试这个

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

        如有任何疑问,请咨询我

        【讨论】:

          猜你喜欢
          • 2023-02-14
          • 1970-01-01
          • 2016-06-01
          • 2017-08-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多