Die Anleitung zu Android ViewPager2
1. Android ViewPager2 vs ViewPager
Android ViewPager ist eine Interface-Komponente, die in der Unterstützungsbibliothek von Android eingeführt wurde. Der Benutzer kann nach links oder rechts wischen, um eine völlig neue Seite (Bildschirm) anzuzeigen.
ViewPager/ViewPager2
Ein ViewPager/ViewPager2, bei dem jede Seite den Bildschirm ausfüllt. Der Benutzer wischt nacht links, um zur nächsten Seite zu gelangen, oder nach rechts, um eine Seite zurück zu kehren.
Ein ViewPager/ViewPager2, der in der Sprachlern-Anwendung Duolingo angezeigt wird.
ViewPager2 vs ViewPager
Wie wir alle wissen, veröffentlicht das Team Android ständig neue Updates und Verbesserung für das Android Framework. Eine der Komponenten, die wichtige Updates erhalten haben, ist ViewPager2. ViewPager2 ist der Ersatz für ViewPager und hat nur wenige Leistungsverbesserungen und zusätzliche Funktionen erhalten.
So what's new in ViewPager2?
- ViewPager2 ist eine improvisierte Version von ViewPager, die zusätzliche Funktionen bietet und häufig auftretende Probleme in ViewPager behebt.
- ViewPager2 basiert auf RecyclerView. Deshalb haben Sie die größen Vorteile, die RecyclerView bietet. Z.B: Sie können DiffUtils benutzen, um die Differenz zwischen Datensätzen effizient zu berechnen und den ViewPager mit Animation zu aktualisieren.
- ViewPager2 unterstützt die vertikale Ausrichtung. Wenn Sie ViewPager verwenden, müssen Sie die zusätzlichen Anpassungen für ViewPager schreiben um dieselben Ergebnisse zu erhalten.
- ViewPager2 unterstütz Right-to-Left (RTL) und das wird automatisch basierend auf App Locale aktiviert.
- Bei der Arbeit mit einer Reihe von Fragment. Wenn eines der Fragment seine Interface ändert, sollten Sie die Methode notifyDatasetChanged() aufrufen um die Interface der Anwendung ordnungsgemäß zu aktualisieren.
- ViewPager2 unterstützt die Seitentransformation, d.h Sie können bei der Seitentransformation die Animation bereitstellen. Sie können auch Ihren eigenen benutzerdefinierten PageTransformer schreiben.
- PagerAdapter wird durch RecyclerView ersetzt.
- FragmentStatePagerAdapter wird durch FragmentStateAdapter ersetzt.
Library
ViewPager2 ist eine Komponente, die in der Standardbibliothek von Android nicht verfügbar ist. Wenn Sie sie benutzen möchten, sollten Sie sie in Ihrem Projekt installieren.
Sie können ViewPager2 aus Palette vom Design-Fenster installieren.
Nach der vollständigen Installation wird die Bibliothek ViewPager2 in build.gradle (Module: app) deklariert.
implementation 'androidx.viewpager2:viewpager2:1.0.0'
2. Example: ViewPager2
Jetzt üben wir ein Beispiel für ViewPager2 und verwenden Fragment als ein Design für jede Seite. Hier ist das Vorschaubild des Beispiel:
- Die Datei fragment_employee_page.xml ist die Interface-Design einer Seite (Page).
- Die Klasse EmployeePageFragment enthältet die Daten eines Objekt Employee und zeigt sie in einer Seite (Page).
Auf Android Studio erstellen Sie ein neues Projekt:
- File > New > New Project > Empty Activity
- Name: ViewPager2Example
- Package name: org.o7planning.viewpager2example
- Language: Java
Wie oben erwähnt ist ViewPager2 eine Komponente, die in der Standardbibliothek von Android nicht verfügbar ist. Daher müssen Sie es im nächsten Schritt über Palette vom das Designfenster in Ihr Projekt installieren.
Und dann erstellen Sie ein Fragment (EmployeePageFragment), das einer Seite (Page) von ViewPager2 entspricht:
- File > New > Fragment > Fragment (Blank)
- Fragment Name: EmployeePageFragment
- Fragment Layout Name: fragment_page_employee
- Source Language: Java
Jetzt können Sie sehen, dass zwei Datei erstellt werden:
Zum nächsten öffnen Sie die Datei fragment_employee_page.xml um die Interface zu entwerfen.
fragment_employee_page.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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">
<TextView
android:id="@+id/textView_fullName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:background="#C4CFB9"
android:gravity="center_horizontal"
android:text="Fullname"
android:textSize="22sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView71"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:text="Position:"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView_fullName" />
<TextView
android:id="@+id/textView_position"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:text="(Position)"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textView71"
app:layout_constraintTop_toBottomOf="@+id/textView_fullName" />
<TextView
android:id="@+id/textView72"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:text="Email:"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView71" />
<TextView
android:id="@+id/textView_email"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:text="(Email)"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textView72"
app:layout_constraintTop_toBottomOf="@+id/textView71" />
</androidx.constraintlayout.widget.ConstraintLayout>
EmployeePageFragment.java
package org.o7planning.viewpager2example;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class EmployeePageFragment extends Fragment {
private static final String LOG_TAG = "AndroidExample";
private Employee employee;
private TextView textViewEmail;
private TextView textViewPosition;
private TextView textViewFullName;
private static int counter = 0;
// IMPORTANT:
// Required default public constructor.
// If configuration change.
// For example: User rotate the Phone,
// Android will create new Fragment (EmployeePageFragment) via default Constructor
// so this.employee will be null.
public EmployeePageFragment() {
}
public EmployeePageFragment(Employee employee) {
this.employee = employee;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = (ViewGroup) inflater.inflate(
R.layout.fragment_employee_page, container, false);
counter++;
if(counter % 2 == 0) {
view.setBackgroundColor(Color.parseColor("#ebdef0"));
} else {
view.setBackgroundColor(Color.parseColor("#e8f8f5"));
}
this.textViewFullName = view.findViewById(R.id.textView_fullName);
this.textViewPosition = view.findViewById(R.id.textView_position);
this.textViewEmail = view.findViewById(R.id.textView_email);
return view;
}
// Called when configuration change.
// For example: User rotate the Phone,
// Android will create new Fragment (EmployeePageFragment) object via default Constructor
// so this.employee will be null.
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
Log.i(LOG_TAG, "onSaveInstanceState: save employee data to Bundle");
// Convert employee object to Bundle.
Bundle dataBundle = this.employeeToBundle(this.employee);
outState.putAll(dataBundle);
super.onSaveInstanceState(outState);
}
@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
Log.i(LOG_TAG, "onViewStateRestored");
super.onViewStateRestored(savedInstanceState);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
Log.i(LOG_TAG, "onViewCreated");
super.onViewCreated(view, savedInstanceState);
if(this.employee == null) {
Log.i(LOG_TAG, "Get employee data from savedInstanceState");
// The state was saved by onSaveInstanceState(Bundle outState) method.
this.employee = this.bundleToEmployee(savedInstanceState);
}
this.showInGUI(this.employee);
}
// Call where View ready.
private void showInGUI(Employee employee) {
this.textViewFullName.setText(employee.getFullName());
this.textViewPosition.setText(employee.getPosition());
this.textViewEmail.setText(employee.getEmail());
}
private Bundle employeeToBundle(Employee employee) {
Bundle bundle = new Bundle();
bundle.putString("fullName", employee.getFullName());
bundle.putString("position", employee.getPosition());
bundle.putString("email", employee.getEmail());
return bundle;
}
private Employee bundleToEmployee(Bundle savedInstanceState) {
String fullName = savedInstanceState.getString("fullName");
String position = savedInstanceState.getString("position");
String email = savedInstanceState.getString("email");
return new Employee(fullName, email, position);
}
}
EmployeeFragmentStateAdapter.java
package org.o7planning.viewpager2example;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import java.util.ArrayList;
import java.util.List;
public class EmployeeFragmentStateAdapter extends FragmentStateAdapter {
private List<Employee> employees;
public EmployeeFragmentStateAdapter(@NonNull FragmentActivity fragmentActivity) {
super(fragmentActivity);
this.employees = this.intDatas();
}
private List<Employee> intDatas() {
Employee emp1 = new Employee("James Smith", "jamessmith@example.com", "Web Designer");
Employee emp2 = new Employee("Elizabeth Johnson", "elizabethjohnson@example.com", "Project Manager");
Employee emp3 = new Employee("Catherine Johnson", "catherinejohnson@example.com", "President of Sales");
List<Employee> list = new ArrayList<Employee>();
list.add(emp1);
list.add(emp2);
list.add(emp3);
return list;
}
@NonNull
@Override
public Fragment createFragment(int position) {
Employee employee = this.employees.get(position);
return new EmployeePageFragment(employee);
}
@Override
public int getItemCount() {
return this.employees.size();
}
}
Employee.java
package org.o7planning.viewpager2example;
public class Employee {
private String fullName;
private String email;
private String position;
public Employee(String fullName, String email, String position) {
this.fullName = fullName;
this.email = email;
this.position = position;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
}
Die Hauptinterface der Anwendung:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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=".MainActivity">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager2_employee"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java
package org.o7planning.viewpager2example;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
private ViewPager2 viewPager2Employee;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.viewPager2Employee = findViewById(R.id.viewPager2_employee);
// Employee FragmentStateAdapter.
EmployeeFragmentStateAdapter adapter = new EmployeeFragmentStateAdapter(this);
this.viewPager2Employee.setAdapter(adapter);
}
}
3. Example: Transformation
Um den Animationseffekt bei der Seitentransformation anzuzeigen, müssen Sie eine Klasse schreiben, die die Interface ViewPager2.PageTransformer implementiert und für das Objekt ViewPager2 bereitstellt.
ViewPager2 viewPager = findViewById(R.id.pager);
...
viewPager.setPageTransformer(new YourPageTransformer());
Die Interface ViewPager2.PageTransformer hat nur die einzige Methode transformPage(),. Diese Methode wird bei jeder Transittion einmal aufgeruft.
/**
* Apply a property transformation to the given page.
*
* @param page Apply the transformation to this page
* @param position Position of page relative to the current front-and-center
* position of the pager. 0 is front and center. 1 is one full
* page position to the right, and -2 is two pages to the left.
* Minimum / maximum observed values depend on how many pages we keep
* attached, which depends on offscreenPageLimit.
*
* @see #setOffscreenPageLimit(int)
*/
void transformPage(@NonNull View page, float position);
Weiter mit dem obigen Beispiel werden wir die Animationseffekt hinzufügen.
Zoom Out Page Transformer
ZoomOutPageTransformer.java
package org.o7planning.viewpager2example.transformer;
import android.view.View;
import androidx.viewpager2.widget.ViewPager2;
public class ZoomOutPageTransformer implements ViewPager2.PageTransformer {
private static final float MIN_SCALE = 0.85f;
private static final float MIN_ALPHA = 0.5f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0f);
} else if (position <= 1) { // [-1,1]
// Modify the default slide transition to shrink the page as well
float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
float vertMargin = pageHeight * (1 - scaleFactor) / 2;
float horzMargin = pageWidth * (1 - scaleFactor) / 2;
if (position < 0) {
view.setTranslationX(horzMargin - vertMargin / 2);
} else {
view.setTranslationX(-horzMargin + vertMargin / 2);
}
// Scale the page down (between MIN_SCALE and 1)
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
// Fade the page relative to its size.
view.setAlpha(MIN_ALPHA +
(scaleFactor - MIN_SCALE) /
(1 - MIN_SCALE) * (1 - MIN_ALPHA));
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0f);
}
}
}
MainActivity.java (Zoom Out Page Transformer)
package org.o7planning.viewpager2example;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import android.os.Bundle;
import org.o7planning.viewpager2example.transformer.ZoomOutPageTransformer;
public class MainActivity extends AppCompatActivity {
private ViewPager2 viewPager2Employee;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.viewPager2Employee = findViewById(R.id.viewPager2_employee);
// Employee FragmentStateAdapter.
EmployeeFragmentStateAdapter adapter = new EmployeeFragmentStateAdapter(this);
this.viewPager2Employee.setAdapter(adapter);
// PageTransformer
this.viewPager2Employee.setPageTransformer(new ZoomOutPageTransformer());
}
}
Depth Page Transformer
DepthPageTransformer.java
package org.o7planning.viewpager2example.transformer;
import android.view.View;
import androidx.annotation.RequiresApi;
import androidx.viewpager2.widget.ViewPager2;
@RequiresApi(21)
public class DepthPageTransformer implements ViewPager2.PageTransformer {
private static final float MIN_SCALE = 0.75f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0f);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
view.setAlpha(1f);
view.setTranslationX(0f);
view.setTranslationZ(0f);
view.setScaleX(1f);
view.setScaleY(1f);
} else if (position <= 1) { // (0,1]
// Fade the page out.
view.setAlpha(1 - position);
// Counteract the default slide transition
view.setTranslationX(pageWidth * -position);
// Move it behind the left page
view.setTranslationZ(-1f);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE
+ (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0f);
}
}
}
MainActivity.java (Depth Page Transformer)
package org.o7planning.viewpager2example;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import android.os.Build;
import android.os.Bundle;
import org.o7planning.viewpager2example.transformer.DepthPageTransformer;
public class MainActivity extends AppCompatActivity {
private ViewPager2 viewPager2Employee;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.viewPager2Employee = findViewById(R.id.viewPager2_employee);
// Employee FragmentStateAdapter.
EmployeeFragmentStateAdapter adapter = new EmployeeFragmentStateAdapter(this);
this.viewPager2Employee.setAdapter(adapter);
// PageTransformer
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // Api 21+.
this.viewPager2Employee.setPageTransformer(new DepthPageTransformer());
}
}
}
Anleitungen Android
- Konfigurieren Sie Android Emulator in Android Studio
- Die Anleitung zu Android ToggleButton
- Erstellen Sie einen einfachen File Finder Dialog in Android
- Die Anleitung zu Android TimePickerDialog
- Die Anleitung zu Android DatePickerDialog
- Was ist erforderlich, um mit Android zu beginnen?
- Installieren Sie Android Studio unter Windows
- Installieren Sie Intel® HAXM für Android Studio
- Die Anleitung zu Android AsyncTask
- Die Anleitung zu Android AsyncTaskLoader
- Die Anleitung zum Android für den Anfänger - Grundlegende Beispiele
- Woher weiß man die Telefonnummer von Android Emulator und ändere es
- Die Anleitung zu Android TextInputLayout
- Die Anleitung zu Android CardView
- Die Anleitung zu Android ViewPager2
- Holen Sie sich die Telefonnummer in Android mit TelephonyManager
- Die Anleitung zu Android Phone Calls
- Die Anleitung zu Android Wifi Scanning
- Die Anleitung zum Android 2D Game für den Anfänger
- Die Anleitung zu Android DialogFragment
- Die Anleitung zu Android CharacterPickerDialog
- Die Anleitung zum Android für den Anfänger - Hello Android
- Verwenden des Android Device File Explorer
- Aktivieren Sie USB Debugging auf einem Android-Gerät
- Die Anleitung zu Android UI Layouts
- Die Anleitung zu Android SMS
- Die Anleitung zu Android SQLite Database
- Die Anleitung zu Google Maps Android API
- Text zu Sprache in Android
- Die Anleitung zu Android Space
- Die Anleitung zu Android Toast
- Erstellen Sie einen benutzerdefinierten Android Toast
- Die Anleitung zu Android SnackBar
- Die Anleitung zu Android TextView
- Die Anleitung zu Android TextClock
- Die Anleitung zu Android EditText
- Die Anleitung zu Android TextWatcher
- Formatieren Sie die Kreditkartennummer mit Android TextWatcher
- Die Anleitung zu Android Clipboard
- Erstellen Sie einen einfachen File Chooser in Android
- Die Anleitung zu Android AutoCompleteTextView und MultiAutoCompleteTextView
- Die Anleitung zu Android ImageView
- Die Anleitung zu Android ImageSwitcher
- Die Anleitung zu Android ScrollView und HorizontalScrollView
- Die Anleitung zu Android WebView
- Die Anleitung zu Android SeekBar
- Die Anleitung zu Android Dialog
- Die Anleitung zu Android AlertDialog
- Die Anleitung zu Android RatingBar
- Die Anleitung zu Android ProgressBar
- Die Anleitung zu Android Spinner
- Die Anleitung zu Android Button
- Die Anleitung zu Android Switch
- Die Anleitung zu Android ImageButton
- Die Anleitung zu Android FloatingActionButton
- Die Anleitung zu Android CheckBox
- Die Anleitung zu Android RadioGroup und RadioButton
- Die Anleitung zu Android Chip und ChipGroup
- Verwenden Sie Image Asset und Icon Asset von Android Studio
- Richten Sie die SDCard für den Emulator ein
- ChipGroup und Chip Entry Beispiel
- Hinzufügen externer Bibliotheken zu Android Project in Android Studio
- Wie deaktiviere ich die Berechtigungen, die der Android-Anwendung bereits erteilt wurden?
- Wie entferne ich Anwendungen aus dem Android Emulator?
- Die Anleitung zu Android LinearLayout
- Die Anleitung zu Android TableLayout
- Die Anleitung zu Android FrameLayout
- Die Anleitung zu Android QuickContactBadge
- Die Anleitung zu Android StackView
- Die Anleitung zu Android Camera
- Die Anleitung zu Android MediaPlayer
- Die Anleitung zu Android VideoView
- Spielen Sie Sound-Effekte in Android mit SoundPool
- Die Anleitung zu Android Networking
- Die Anleitung zu Android JSON Parser
- Die Anleitung zu Android SharedPreferences
- Die Anleitung zu Android Internal Storage
- Die Anleitung zu Android External Storage
- Die Anleitung zu Android Intents
- Beispiel für eine explizite Android Intent, nennen Sie eine andere Intent
- Beispiel für implizite Android Intent, Öffnen Sie eine URL, senden Sie eine Email
- Die Anleitung zu Android Services
- Die Anleitung zu Android Notifications
- Die Anleitung zu Android DatePicker
- Die Anleitung zu Android TimePicker
- Die Anleitung zu Android Chronometer
- Die Anleitung zu Android OptionMenu
- Die Anleitung zu Android ContextMenu
- Die Anleitung zu Android PopupMenu
- Die Anleitung zu Android Fragment
- Die Anleitung zu Android ListView
- Android ListView mit Checkbox verwenden ArrayAdapter
- Die Anleitung zu Android GridView
Show More