Saya hanya ingin meningkatkan pengalaman pengguna dengan beberapa animasi dan desain konsep lain seperti yang saya lakukan di aplikasi kali ini, Saya baru-baru ini mengerjakan alur onboarding menggunakan ViewPager transformer. ViewPager dapat mengimplementasikan antarmuka yang berguna, ViewPager.PageTransformer, yang mengekspos satu metode, transformPage(). Ini memungkinkan Anda membuat beberapa animasi slide yang bagus tergantung pada posisi halaman di layar (misalnya Zoom-out atau Depth page).
Dan saya buat tiga buah file fragment, untuk file fragment_satu.xml saya susun seperti ini:
Ini untuk file fragmen kedua saya fragment_dua.xml:
file fragmen ketiga fragment_tiga.xml:
Dari sini kita dapat mengganti metode transformPage(), mencari posisi halaman yang berbeda, menemukan tampilan yang ingin kita ubah dan menerapkan efek transformasi yang diinginkan pada tampilan misalnya, setTranslationX(), setScaleY(), setAlpha(), dll.).
Saya membuat kelas yang mengimplementasikan ViewPager.PageTransformer. sebagai ObPageTransform.java
Kemudian kita cukup mengatur setPageTransformer() pada ViewPager dalam file OnboardingActivity.java
Hasilnya akan seperti ini:
Parameter posisi menunjukkan di mana halaman tertentu berada relatif terhadap pusat layar. Ini adalah properti dinamis yang berubah saat pengguna menggulir halaman. Saat halaman mengisi layar, nilai posisinya adalah 0.
Saat halaman mengisi layar, nilai posisinya adalah 0. Ketika halaman ditarik tepat di sisi kanan layar, nilai posisinya adalah 1. Jika pengguna menggulir setengah jalan antara halaman satu dan dua, halaman satu memiliki posisi -0,5 dan halaman dua memiliki posisi 0,5.
Berdasarkan posisi pada layar, Anda dapat membuat animasi kustom slide dengan mengatur properti halaman dengan metode seperti setTranslationX(), setScaleY(), atau setAlpha(),
Sampel code
Untuk file activity_main.xml saya susun seperti ini:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android:id="@+id/onboarding_layout"
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"
android:fitsSystemWindows="true"
tools:background="@color/transparentBlack">
<android.support.v4.view.ViewPager
android:id="@+id/onboarding_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="bottom"
android:layout_marginBottom="?attr/actionBarSize"
android:alpha="0.12"
android:background="@android:color/white"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom">
<Button
android:id="@+id/btn_cancel"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start|center"
android:text="@string/btn_skip"
android:textColor="@android:color/white"
android:onClick="onCancelButton"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/indicator_01"
android:layout_width="8dp"
android:layout_height="8dp"
android:background="@drawable/indicator_unselected"/>
<ImageView
android:id="@+id/indicator_02"
android:layout_width="8dp"
android:layout_height="8dp"
android:background="@drawable/indicator_unselected"/>
<ImageView
android:id="@+id/indicator_03"
android:layout_width="8dp"
android:layout_height="8dp"
android:background="@drawable/indicator_unselected"/>
</LinearLayout>
<Button
android:id="@+id/btn_finish"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center"
android:text="@string/btn_finish"
android:textColor="@android:color/white"
android:visibility="gone"
android:onClick="onFinishButton"/>
<ImageButton
android:id="@+id/btn_next"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center"
android:src="@drawable/ic_chevron_right"
android:tint="@color/white"
android:onClick="onNextButton"/>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
Dan saya buat tiga buah file fragment, untuk file fragment_satu.xml saya susun seperti ini:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/onboarding_fragment_bg"
tools:background="@color/transparentBlack"
android:padding="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/textSkip"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Skip"
android:layout_gravity="right"
android:gravity="center"
android:textStyle="bold"
android:textColor="#FFFFFFFF"
android:textSize="15sp"
android:shadowRadius="4"
android:shadowColor="#FFFFFFFF"
android:layout_alignParentRight="true"
android:layout_marginBottom="30dp"/>
<ImageView
android:id="@+id/gambar1"
android:layout_width="300dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_below="@+id/textSkip"
android:layout_centerHorizontal="true"
android:scaleType="fitXY"
android:background="@drawable/gambar1"
android:layout_marginBottom="15dp"/>
<TextView
android:id="@+id/textJudul"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:gravity="center"
android:layout_below="@+id/gambar1"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#FFFFFFFF"
android:shadowRadius="2"
android:shadowColor="#FFE4E4E4"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"
android:text="Pelajari apa pun di luar kelas"
android:singleLine="false"
android:lines="2"
android:maxLines="2"/>
<TextView
android:id="@+id/textDescripsi"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:gravity="center"
android:layout_below="@+id/textJudul"
android:textSize="16sp"
android:textStyle="normal"
android:textColor="#FFFFFFFF"
android:layout_centerHorizontal="true"
android:layout_marginBottom="70dp"
android:text="Biarkan procces belajar mengalir untuk mengembangkan keterampilan pengembangan kognitif mereka"
android:singleLine="false"
android:lines="3"
android:maxLines="3"/>
<Button
android:id="@+id/Button1"
android:layout_height="40dp"
android:layout_width="200dp"
android:text="Happy Codx"
android:gravity="center"
android:textStyle="bold"
android:textSize="16sp"
android:layout_centerHorizontal="true"
android:layout_below="@+id/textDescripsi"
android:background="@drawable/button_background"
android:textColor="#FFFFFFFF"/>
</RelativeLayout>
Ini untuk file fragmen kedua saya fragment_dua.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/onboarding_fragment_bg"
tools:background="@color/transparentBlack"
android:padding="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/textSkip2"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Skip"
android:layout_gravity="right"
android:gravity="center"
android:textStyle="bold"
android:textColor="#FFFFFFFF"
android:textSize="15sp"
android:shadowRadius="4"
android:shadowColor="#FFFFFFFF"
android:layout_alignParentRight="true"
android:layout_marginBottom="30dp"/>
<ImageView
android:id="@+id/gambar2"
android:layout_width="300dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_below="@+id/textSkip2"
android:layout_centerHorizontal="true"
android:scaleType="fitXY"
android:background="@drawable/gambar2"
android:layout_marginBottom="15dp"/>
<TextView
android:id="@+id/textJudul2"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:gravity="center"
android:layout_below="@+id/gambar2"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#FFFFFFFF"
android:shadowRadius="2"
android:shadowColor="#FFE4E4E4"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"
android:text="text"
android:singleLine="false"
android:lines="2"
android:maxLines="2"/>
<TextView
android:id="@+id/textDescripsi2"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:gravity="center"
android:layout_below="@+id/textJudul2"
android:textSize="16sp"
android:textStyle="normal"
android:textColor="#FFFFFFFF"
android:layout_centerHorizontal="true"
android:layout_marginBottom="70dp"
android:text="text"
android:singleLine="false"
android:lines="3"
android:maxLines="3"/>
<Button
android:id="@+id/Button2"
android:layout_height="40dp"
android:layout_width="200dp"
android:text="Happy Codx"
android:gravity="center"
android:textStyle="bold"
android:textSize="16sp"
android:layout_centerHorizontal="true"
android:layout_below="@+id/textDescripsi2"
android:background="@drawable/button_background"
android:textColor="#FFFFFFFF"/>
</RelativeLayout>
file fragmen ketiga fragment_tiga.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/onboarding_fragment_bg"
tools:background="@color/transparentBlack"
android:padding="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/textSkip3"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Skip"
android:layout_gravity="right"
android:gravity="center"
android:textStyle="bold"
android:textColor="#FFFFFFFF"
android:textSize="15sp"
android:shadowRadius="4"
android:shadowColor="#FFFFFFFF"
android:layout_alignParentRight="true"
android:layout_marginBottom="30dp"/>
<ImageView
android:id="@+id/gambar3"
android:layout_width="300dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_below="@+id/textSkip3"
android:layout_centerHorizontal="true"
android:scaleType="fitXY"
android:background="@drawable/gambar3"
android:layout_marginBottom="15dp"/>
<TextView
android:id="@+id/textJudul3"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:gravity="center"
android:layout_below="@+id/gambar3"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#FFFFFFFF"
android:shadowRadius="2"
android:shadowColor="#FFE4E4E4"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"
android:text="text"
android:singleLine="false"
android:lines="2"
android:maxLines="2"/>
<TextView
android:id="@+id/textDescripsi3"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:gravity="center"
android:layout_below="@+id/textJudul3"
android:textSize="16sp"
android:textStyle="normal"
android:textColor="#FFFFFFFF"
android:layout_centerHorizontal="true"
android:layout_marginBottom="70dp"
android:text="text"
android:singleLine="false"
android:lines="3"
android:maxLines="3"/>
<Button
android:id="@+id/Button3"
android:layout_height="40dp"
android:layout_width="200dp"
android:text="Happy Codx"
android:gravity="center"
android:textStyle="bold"
android:textSize="16sp"
android:layout_centerHorizontal="true"
android:layout_below="@+id/textDescripsi3"
android:background="@drawable/button_background"
android:textColor="#FFFFFFFF"/>
</RelativeLayout>
Dari sini kita dapat mengganti metode transformPage(), mencari posisi halaman yang berbeda, menemukan tampilan yang ingin kita ubah dan menerapkan efek transformasi yang diinginkan pada tampilan misalnya, setTranslationX(), setScaleY(), setAlpha(), dll.).
Saya membuat kelas yang mengimplementasikan ViewPager.PageTransformer. sebagai ObPageTransform.java
package com.happycodx.app;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Button;
import android.view.animation.AlphaAnimation;
/**
* Created by Happycodx on 7/02/26.
*/
public class ObPageTransform implements ViewPager.PageTransformer {
@Override
public void transformPage(View page, float position) {
// Mendapatkan indeks halaman dari tag
int pagePosition = (int) page.getTag();
int pageWidth = (int) page.getWidth();
float pageWidthTimesPosition = pageWidth * position;
float absPosition = Math.abs(position);
int pageHeight = (int) page.getHeight();
float pageHeightTimesPosition = pageWidth * position;
AlphaAnimation animation1 = new AlphaAnimation(0.2f, 1.0f);
animation1.setDuration(100);
if (position <= -1.0f || position >= 1.0f) {
} else if (position == 0.0f) {
// Halaman jika dipilih, atur ulang tampilan apa pun jika perlu
} else {
// Halaman ketika di geser -- terapkan animasi di sini
// Fragment 1
final TextView skip_text = page.findViewById(R.id.textSkip);
if (skip_text != null) skip_text.setAlpha(1.0f - absPosition * 2);
final View gambar1 = page.findViewById(R.id.gambar1);
if (gambar1 != null) {
gambar1.setScaleX(1.0f - absPosition * 2);
gambar1.setScaleY(1.0f - absPosition * 2);
gambar1.setAlpha(1.0f - absPosition * 2);
}
final TextView text_judul1 = page.findViewById(R.id.textJudul);
if (text_judul1 != null) {
text_judul1.setTranslationX(pageWidthTimesPosition * 0.5f);
}
final TextView text_descripsi1 = page.findViewById(R.id.textDescripsi);
if (text_descripsi1 != null) {
text_descripsi1.setTranslationX(pageWidthTimesPosition * 1.2f);
}
final Button button1 = page.findViewById(R.id.Button1);
if (button1 != null) {
button1.setTranslationY(pageHeightTimesPosition * 1.2f);
button1.setAlpha(1f);
button1.startAnimation(animation1);
}
// Fragment 2
final TextView skip_text2 = page.findViewById(R.id.textSkip2);
if (skip_text2 != null) skip_text2.setAlpha(1.0f - absPosition * 2);
final View gambar2 = page.findViewById(R.id.gambar2);
if (gambar2 != null) {
gambar2.setScaleX(1.0f - absPosition * 2);
gambar2.setScaleY(1.0f - absPosition * 2);
gambar2.setAlpha(1.0f - absPosition * 2);
}
final TextView text_judul2 = page.findViewById(R.id.textJudul2);
if (text_judul2 != null) {
text_judul2.setTranslationX(pageWidthTimesPosition * 0.5f);
text_judul2.setText("Ada banyak kegiatan kursus");
}
final TextView text_descripsi2 = page.findViewById(R.id.textDescripsi2);
if (text_descripsi2 != null) {
text_descripsi2.setTranslationX(pageWidthTimesPosition * 1.2f);
text_descripsi2.setText("Materi pembelajaran berkualitas tinggi untuk setiap mata pelajaran yang akan membantu melakukan pembelajaran mandiri");
}
final Button button2 = page.findViewById(R.id.Button2);
if (button2 != null) {
button2.setTranslationY(pageHeightTimesPosition * 0.5f);
button2.setAlpha(1f);
button2.startAnimation(animation1);
}
// Fragment 3
final TextView skip_text3 = page.findViewById(R.id.textSkip3);
if (skip_text3 != null) skip_text3.setAlpha(1.0f - absPosition * 2);
final View gambar3 = page.findViewById(R.id.gambar3);
if (gambar3 != null) {
gambar3.setScaleX(1.0f - absPosition * 2);
gambar3.setScaleY(1.0f - absPosition * 2);
gambar3.setAlpha(1.0f - absPosition * 2);
}
final TextView text_judul3 = page.findViewById(R.id.textJudul3);
if (text_judul3 != null) {
text_judul3.setTranslationX(pageWidthTimesPosition * 0.5f);
text_judul3.setText("Sesi online dengan guru");
}
final TextView text_descripsi3 = page.findViewById(R.id.textDescripsi3);
if (text_descripsi3 != null) {
text_descripsi3.setTranslationX(pageWidthTimesPosition * 1.2f);
text_descripsi3.setText("Bergabunglah dengan sesi langsung dengan guru atau mentor dan dapatkan pemberitahuan untuk sesi mendatang mereka");
}
final Button button3 = page.findViewById(R.id.Button3);
if (button3 != null) {
button3.setTranslationY(pageHeightTimesPosition * 0.5f);
button3.setAlpha(1f);
button3.startAnimation(animation1);
}
}
}
}
Kemudian kita cukup mengatur setPageTransformer() pada ViewPager dalam file OnboardingActivity.java
package com.happycodx.app;
import android.animation.ArgbEvaluator;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
public class OnboardingActivity extends AppCompatActivity {
private int pagePosition = 0;
private ImageButton nextBtn;
private Button finishBtn;
private ViewPager viewPager;
private ImageView[] indicators;
private ImageView indicator01, indicator02, indicator03;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nextBtn = (ImageButton) findViewById(R.id.btn_next);
finishBtn = (Button) findViewById(R.id.btn_finish);
indicator01 = (ImageView) findViewById(R.id.indicator_01);
indicator02 = (ImageView) findViewById(R.id.indicator_02);
indicator03 = (ImageView) findViewById(R.id.indicator_03);
indicators = new ImageView[] {indicator01, indicator02, indicator03};
updateIndicator(pagePosition);
final int pageColor01 = ContextCompat.getColor(this, R.color.lightBlue);
final int pageColor02 = ContextCompat.getColor(this, R.color.cyan);
final int pageColor03 = ContextCompat.getColor(this, R.color.teal);
final int[] pageColorList = new int[] {pageColor01, pageColor02, pageColor03};
final ArgbEvaluator argbEvaluator = new ArgbEvaluator(); // digunakan untuk meng update warna halaman
viewPager = (ViewPager) findViewById(R.id.onboarding_viewpager);
// Set Adapter untuk ViewPager
viewPager.setAdapter(new OnboardingAdapter(getSupportFragmentManager()));
// Set PageTransformer untuk ViewPager
viewPager.setPageTransformer(false, new ObPageTransform());
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// Update warna Background Halaman
int pageColorUpdate = (Integer) argbEvaluator.evaluate(
positionOffset,
pageColorList[position],
pageColorList[position == 2 ? position : position + 1] //If there's no last page, do not increment
);
viewPager.setBackgroundColor(pageColorUpdate);
}
@Override
public void onPageSelected(int position) {
pagePosition = position;
updateIndicator(pagePosition);
// set warna background saat dipilih
switch (position) {
case 0:
viewPager.setBackgroundColor(pageColor01);
break;
case 1:
viewPager.setBackgroundColor(pageColor02);
break;
case 2:
viewPager.setBackgroundColor(pageColor03);
break;
}
nextBtn.setVisibility(position == 2 ? View.GONE : View.VISIBLE);
finishBtn.setVisibility(position == 2 ? View.VISIBLE : View.GONE);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
private void updateIndicator(int pagePosition) {
for(int i = 0; i < indicators.length; i++) {
indicators[i].setBackgroundResource(
i == pagePosition ? R.drawable.indicator_selected : R.drawable.indicator_unselected
);
}
}
public void onNextButton(View view) {
pagePosition += 1;
viewPager.setCurrentItem(pagePosition, true);
}
public void onFinishButton(View view) {
finish();
}
public void onCancelButton(View view) {
finish();
}
}
Hasilnya akan seperti ini: