[JAVA] Passen Sie Registerkarten mit Animation an

Einführung

Ich habe versucht, TabLayout zu implementieren, das so animiert.

tab_anim.gif

!Hinweis!

TabLayout + ViewPager

Erstellen Sie mit TabLayout + ViewPager eine Layoutdatei für den Hauptbildschirm. Einzelheiten zur Verwendung von TabLayout und ViewPager finden Sie in anderen Artikeln und offiziellen Artikeln.

https://qiita.com/furu8ma/items/1602a4bbed4303fec5b1

Platzieren Sie hier einfach TabLayout und ViewPager und steuern Sie sie mit MainActivity. Als Bonus habe ich die Titelleiste oben eingerichtet.

activity_main.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.hoge.hogeapp.MainActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_below="@+id/titlebar"
            android:background="@color/color_white1">

            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="70dp"
                app:tabIndicatorColor="@color/color_green1"
                app:tabMode="scrollable"
                android:background="@android:color/white"
                android:elevation="4dp"
                tools:targetApi="lollipop" />

            <android.support.v4.view.ViewPager
                android:id="@+id/pager"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

        </LinearLayout>

        <include
            android:id="@+id/titlebar"
            layout="@layout/item_titlebar" />

    </RelativeLayout>
</LinearLayout>

Machen Sie einen Adapter und verbinden Sie ihn.

MainActivity.java


MainFragmentPagerAdapter adapter = new MainFragmentPagerAdapter(getSupportFragmentManager());
ViewPager viewPager = findViewById(R.id.pager);
viewPager.setAdapter(adapter);

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);

Adaptereinstellungen

MainFragmentPagerAdapter.java


package com.hoge.hogeapp;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;


public class MainFragmentPagerAdapter extends FragmentPagerAdapter {

    public MainFragmentPagerAdapter(FragmentManager fm) { super(fm); }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return new FugaFragment();
            case 1:
                return new HogeFragment();
            default:
                return new PiyoFragment();
        }
    }

    @Override
    public CharSequence getPageTitle(int position) { return null; }

    @Override
    public int getCount() { return MainActivity.tabLength; }
}

Da der Titel der Registerkarte durch Aktivität festgelegt wird, sollte getPageTitle () null zurückgeben. Setzen Sie getItem () bzw. getCount ().

Erstellen Sie eine Ansicht des Inhalts von TabLayout

Legen Sie als Nächstes den Text und das Symbol im Inhalt von TabLayout fest.

// create TAB1
tabLayout.getTabAt(0).setCustomView(R.layout.item_tab1);
// create TAB2
tabLayout.getTabAt(1).setCustomView(R.layout.item_tab2);
                             :
                             :

Oder

// create TAB1
tabLayout.getTabAt(0).setText(R.string.tab1);
tabLayout.getTabAt(0).setIcon(R.drawable.tab1Icon);
// create TAB2
tabLayout.getTabAt(1).setText(R.string.tab2);
tabLayout.getTabAt(1).setIcon(R.drawable.tab2Icon);
                             :
                             :

Es ist am einfachsten, es in tabLayout so einzustellen Ich muss viele Layoutdateien erstellen, Wenn Sie setText (), setIcon () ausführen, können Sie es nicht aus der Layoutdatei verarbeiten, also ...

Blasen Sie diesmal die Layoutdatei auf und binden Sie Bild und Text mit Datenbindung. Danach setzen wir die Ansicht an das Array von TabLayout.Tab.

LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
TabLayout.Tab[] tab = new TabLayout.Tab[tabLength];
// create TAB1
tab[0] = tabLayout.getTabAt(0);
View tabView = inflater.inflate(R.layout.item_tab, null);

ItemTabBinding binding = ItemTabBinding.bind(tabView);
Drawable drawable = ResourcesCompat.getDrawable(getResources(), R.drawable.tab1Icon, null);
binding.setItemTabData(new ItemTabData(drawable, R.string.tab1));

tab[0].setCustomView(tabView);
                               :
                               :

Es ist ein Ärger, aber ich denke, dass es eine große Erweiterbarkeit hat. Sie können für jede Registerkarte eine Layoutdatei vorbereiten.

viewGroup = (ViewGroup) tabLayout.getChildAt(0);
View childView = viewGroup.getChildAt(tabPosition);
ImageView tabIconView1 = (ImageView) childView.findViewById(R.id.tab_icon);
TextView tabTitleView1 = (TextView) childView.findViewById(R.id.tab_title);
                               :
                               :

Rufen Sie für jede Registerkarte eine Instanz der untergeordneten Ansicht ab Sie können die Animation für jedes Teil innerhalb der Registerkarte festlegen. Sie können es tun, ob Sie es verwenden oder nicht.

tab_anim2.gif

Ich habe versucht, es so zusammenzufassen.

MainActivity.java


private View[] tabIconView;
private View tabView;
private LayoutInflater inflater;
                               :
                               :
// create tab
TabLayout.Tab[] tab = new TabLayout.Tab[tabLength];
inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
tabIconView = new View[tabLength];
for(int i = 0; i < tabLength; i++) {
    tab[i] = tabLayout.getTabAt(i);
    switch (i) {
        case 0:
            bindTabData(R.drawable.ic_cached, R.string.tab1);
            break;
        case 1:
            bindTabData(R.drawable.ic_alarm, R.string.tab2);
            break;
        case 2:
            bindTabData(R.drawable.ic_notifications, R.string.tab3);
            break;
        case 3:
            bindTabData(R.drawable.ic_android, R.string.tab4);
            break;
        default:
            break;
    }
    tab[i].setCustomView(tabView);
}

MainActivity.java


// create tab dataBinding
private void bindTabData(int drawableRoot, int stringRoot) {
   tabView = inflater.inflate(R.layout.item_tab, null);

   ItemTabBinding binding = ItemTabBinding.bind(tabView);
   Drawable drawable = ResourcesCompat.getDrawable(getResources(), drawableRoot, null);
   binding.setItemTabData(new ItemTabData(drawable, getString(stringRoot)));
}

Setzen Sie tabLength = 4 und erstellen Sie ungefähr 4 Registerkarten. Es ist leicht zu erkennen, ob Sie den DataBinding-Teil zu einer Methode machen und die Ressourcendatei verwenden, die Sie an das Argument binden möchten.

Als nächstes benötigen wir eine Registerkartenlayoutdatei, ein Modell von DataBinding, also fügen Sie es hinzu. Weitere Informationen finden Sie unter Empfohlene Datenbindung

https://qiita.com/Omoti/items/a83910a990e64f4dbdf1

item_tab.xml


<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.hoge.hogeapp.MainActivity">

    <data>
        <variable name="itemTabData" type="com.hoge.hogeapp.MainActivity.ItemTabData" />
    </data>

    <RelativeLayout
        android:id="@+id/item_tab"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="80dp"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:background="@drawable/tab_color_selector">

            <ImageView
                android:id="@+id/tab_icon"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:layout_marginTop="12dp"
                android:src="@{itemTabData.tabIcon}"
                android:layout_gravity="center" />

            <TextView
                android:id="@+id/tab_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="4dp"
                android:text="@{itemTabData.tabTitle}"
                android:layout_gravity="center"
                android:textColor="@color/color_green1"
                android:textSize="12sp" />

        </LinearLayout>
    </RelativeLayout>
</layout>

MainActivity.java


public class ItemTabData {
    private Drawable tabIcon;
    private String tabTitle;

    private ItemTabData(Drawable tabIcon, String tabTitle) {
        this.tabIcon = tabIcon;
        this.tabTitle = tabTitle;
    }

    public Drawable getTabIcon() {
        return tabIcon;
    }
    public void setTabIcon(Drawable tabIcon) {
        this.tabIcon = tabIcon;
    }

    public String getTabTitle() {
        return tabTitle;
    }
    public void setTabTitle(String tabTitle) {
        this.tabTitle = tabTitle;
    }
}

Vergiss nicht, es zu build.gradle hinzuzufügen

build.gradle


dataBinding {
    enabled = true
}

Zu diesem Zeitpunkt ist die Tab-Generierung abgeschlossen.

Stellen Sie die Animation im Listener ein

Als nächstes möchte ich die Animation einstellen. Und davor

MainActivity.java


// get tabs instance
viewGroup = (ViewGroup) tabLayout.getChildAt(0);
for(int tabPosition = 0; tabPosition < tabLength; tabPosition++) {
    View childView = viewGroup.getChildAt(tabPosition);
    tabIconView[tabPosition] = (View) childView.findViewById(R.id.tab_icon);
}

Rufen Sie die Ansicht, die Sie animieren möchten, aus der ID der untergeordneten Ansicht für jede Registerkarte als Array ab. Deklarieren Sie tabLayout und viewGroup als Mitgliedsvariablen, damit Sie innerhalb der Aktivität darauf zugreifen können.

Dann aus den Listener-Einstellungen

tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {
    }

    @Override
    public void onTabReselected(TabLayout.Tab tab) {
    }
});

Es scheint am besten, addOnTabSelectedListener zu verwenden. * Version 26.1.0 oder höher Sie können jetzt TabLayout.OnTabSelectedListener erweitern. Fügen wir nun jedem Rückruf eine Animation hinzu.

MainActivity.java


tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        int position = tab.getPosition();
        switch (position) {
            case 0:
                Animation tabAnimation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.roll_anim);
                tabIconView[0].startAnimation(tabAnimation);
                break;
            case 1:
                Animation tabAnimation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.updown_anim);
                tabIconView[1].startAnimation(tabAnimation);
                break;
                               :
                               :
        }
    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {
        int position = tab.getPosition();
        switch (position) {
            case 0:
                tabIconView[0].setAnimation(null);
                break;
            case 1:
                tabIconView[1].setAnimation(null);
                break;
                               :
                               :
        }
    }

    @Override
    public void onTabReselected(TabLayout.Tab tab) {
    }
});

Ich denke, es wäre schön, die Animation für die Ansicht zu starten, die bei Auswahl jeder Registerkarte erfasst wurde, und sie zu stoppen, wenn der ausgewählte Status endet. Beginnen wir zunächst mit der Layoutdatei. Erstellen Sie einen Animationsordner unter dem Ordner res und erstellen Sie ihn darin. Implementieren Sie eine einfache Methode mit View Animation. Ich habe es als Beispiel so gemacht. Siehe andere für Animation Empfohlen

https://qiita.com/BingSyu/items/bd1278feab270501330b

roll_anim.xml


<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <rotate
        android:duration="800"
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%"
        android:startOffset="200"
        android:repeatMode="restart"
        android:repeatCount="-1" />
</set>

Wenn Sie von der Aktivität behandeln möchten

// composite animation
AlphaAnimation alphaAnimation = new AlphaAnimation(0.9f, 0.2f);
alphaAnimation.setRepeatCount(Animation.INFINITE);
alphaAnimation.setRepeatMode(Animation.REVERSE);

RotateAnimation rotateAnimation = new RotateAnimation(0, 360, 45, 45);
rotateAnimation.setRepeatCount(Animation.INFINITE);
rotateAnimation.setRepeatMode(Animation.RESTART);

AnimationSet animationSet = new AnimationSet(false);

animationSet.addAnimation(alphaAnimation);
animationSet.addAnimation(rotateAnimation);
animationSet.addAnimation(new ScaleAnimation(0.1f, 1, 0.1f, 1));
animationSet.addAnimation(new TranslateAnimation(50, 0, 150, 0));

animationSet.setDuration(3000);
iconView.startAnimation(animationSet);

Sie können mehrere Animationen festlegen, damit es sich beim Schreiben etwas kompliziert anfühlt. (Eigenschaftsanimation ist besser ...)

Es wäre schön, wenn ich das könnte, Versuchen Sie abschließend, die Skalierung der gesamten ausgewählten Registerkarte zu erhöhen. Ich denke, dass Sie onTabSelected bzw. onTabUnselected Folgendes hinzufügen sollten.

final View view = viewGroup.getChildAt(tabLayout.getSelectedTabPosition());
view.setScaleX(1.25F);
view.setScaleY(1.25F);
final View view = viewGroup.getChildAt(tabLayout.getSelectedTabPosition());
view.setScaleX(1.0F);
view.setScaleY(1.0F);

Wenn Sie es danach zu einer Methode machen und in der switch-Anweisung anordnen, ist sie fast vollständig, wie Sie es wollten. Danke für deine harte Arbeit.

Schließlich

... Ich möchte nicht mehr mit Gradle bauen und ich möchte Flutter verwenden

Quelle https://github.com/udzuv/AnimatingTabLayout

Ende

Recommended Posts

Passen Sie Registerkarten mit Animation an
Passen Sie die Ansicht mit dem Ansichtsmodifikator in der Swift-Benutzeroberfläche an