Ich habe ViewPager2 kennengelernt und versucht, es zu implementieren, aber kein geeignetes Beispiel gefunden.
Kann mir jemand sagen, wie ich es benutzen kann.
Ich suche die richtige Verwendung, kein Beispiel.
android
android-viewpager
android-viewpager2
Pratik Butani
quelle
quelle
recommend or find a book, tool, software library, tutorial or other off-site resource
Bitte lesen Sie sorgfältig, dass ich nicht nach Beispiel suche.Antworten:
UPDATE 7
Überprüfen Sie: Migrieren Sie von ViewPager zu ViewPager2
Aktivieren : Erstellen Sie mit ViewPager2 Swipe-Ansichten mit Registerkarten
UPDATE 6
Schauen Sie sich meine Antwort an, wenn Sie Carousel mit View Pager2 implementieren möchten
UPDATE 5
BEISPIELCODE
Verwenden Sie unten
dependencies
implementation 'com.google.android.material:material:1.1.0-alpha08' implementation 'androidx.viewpager2:viewpager2:1.0.0-beta02'
BEISPIELCODE
<?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayout 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"> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:layout_scrollFlags="scroll|enterAlways" app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/> <com.google.android.material.tabs.TabLayout android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content"/> </com.google.android.material.appbar.AppBarLayout> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/viewpager" app:layout_anchor="@id/tabs" app:layout_anchorGravity="bottom" android:layout_width="match_parent" android:layout_height="match_parent" /> </androidx.coordinatorlayout.widget.CoordinatorLayout>
import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import kotlinx.android.synthetic.main.activity_main.* import com.google.android.material.tabs.TabLayoutMediator import com.google.android.material.tabs.TabLayout class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // setSupportActionBar(toolbar) viewpager.adapter = AppViewPagerAdapter(supportFragmentManager, lifecycle) TabLayoutMediator(tabs, viewpager, object : TabLayoutMediator.OnConfigureTabCallback { override fun onConfigureTab(tab: TabLayout.Tab, position: Int) { // Styling each tab here tab.text = "Tab $position" } }).attach() } }
TabLayout mit ViewPager2
Aus Dokumenten
ViewPager2
FragmentStateAdapter
ersetztFragmentStatePagerAdapter
RecyclerView.Adapter
ersetztPagerAdapter
registerOnPageChangeCallback
ersetztaddPageChangeListener
BEISPIELCODE
implementation 'androidx.viewpager2:viewpager2:1.0.0-alpha01'
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import androidx.viewpager2.widget.ViewPager2; import java.util.ArrayList; public class MyActivity extends AppCompatActivity { ViewPager2 myViewPager2; MyAdapter MyAdapter; private ArrayList<String> arrayList = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); myViewPager2 = findViewById(R.id.view_pager); arrayList.add("Item 1"); arrayList.add("Item 2"); arrayList.add("Item 3"); arrayList.add("Item 4"); arrayList.add("Item 5"); MyAdapter = new MyAdapter(this, arrayList); myViewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL); myViewPager2.setAdapter(MyAdapter); } }
import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> { private Context context; private ArrayList<String> arrayList = new ArrayList<>(); public MyAdapter(Context context, ArrayList<String> arrayList) { this.context = context; this.arrayList = arrayList; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false); return new MyViewHolder(view); } @Override public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { holder.tvName.setText(arrayList.get(position)); } @Override public int getItemCount() { return arrayList.size(); } public class MyViewHolder extends RecyclerView.ViewHolder { TextView tvName; public MyViewHolder(@NonNull View itemView) { super(itemView); tvName = itemView.findViewById(R.id.tvName); } } }
Neue Eigenschaften
BEISPIELCODE
myViewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { super.onPageScrolled(position, positionOffset, positionOffsetPixels); } @Override public void onPageSelected(int position) { super.onPageSelected(position); Log.e("Selected_Page", String.valueOf(position)); } @Override public void onPageScrollStateChanged(int state) { super.onPageScrollStateChanged(state); } });
BEISPIELCODE
Zur
HORIZONTAL Orientation
VerwendungmyViewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
Zur
VERTICAL Orientation
VerwendungmyViewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL);
BEISPIELCODE zum Hinzufügen eines neuen Elements
btnAdd.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { arrayList.add("New ITEM ADDED"); MyAdapter.notifyDataSetChanged(); } });
BEISPIELCODE zum Entfernen eines neuen Elements
btnRemove.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { arrayList.remove(3); MyAdapter.notifyItemRemoved(3); } });
AKTUALISIEREN
Versuchen Sie dies , wenn Sie verwenden möchten ,
Fragment
mitViewPager2
import java.util.ArrayList; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.viewpager2.adapter.FragmentStateAdapter; public class ViewPagerFragmentAdapter extends FragmentStateAdapter { private ArrayList<Fragment> arrayList = new ArrayList<>(); public ViewPagerFragmentAdapter(@NonNull FragmentManager fragmentManager) { super(fragmentManager); } @NonNull @Override public Fragment getItem(int position) { return arrayList.get(position); } public void addFragment(Fragment fragment) { arrayList.add(fragment); } @Override public int getItemCount() { return arrayList.size(); } }
import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.viewpager2.widget.ViewPager2; import neel.com.bottomappbar.R; public class MainActivity extends AppCompatActivity { ViewPager2 myViewPager2; ViewPagerFragmentAdapter myAdapter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myViewPager2 = findViewById(R.id.view_pager); myAdapter = new ViewPagerFragmentAdapter(getSupportFragmentManager()); // add Fragments in your ViewPagerFragmentAdapter class myAdapter.addFragment(new FragmentOne()); myAdapter.addFragment(new Fragmenttwo()); myAdapter.addFragment(new FragmentThree()); // set Orientation in your ViewPager2 myViewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL); myViewPager2.setAdapter(myAdapter); } }
Weitere Informationen finden Sie hier
UPDATE 2
Neue Eigenschaften
setUserInputEnabled
,isUserInputEnabled
)API-Änderungen
ViewPager2
KlassenfinaleFehlerbehebung
FragmentStateAdapter
StabilitätskorrekturenBEISPIELCODE zum Deaktivieren des Wischens in viewpager2
myViewPager2.setUserInputEnabled(false);// SAMPLE CODE to disable swiping in viewpager2 myViewPager2.setUserInputEnabled(true);//SAMPLE CODE to enable swiping in viewpager2
UPDATE 3
FragmentStateAdapter
erfordert jetzt einLifecycle
Objekt. Zwei Dienstprogrammkonstruktoren wurden hinzugefügt, um es vom HostFragmentActivity
oder vom Hostfragment zu erhaltenBEISPIELCODE
import java.util.ArrayList; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.lifecycle.Lifecycle; import androidx.viewpager2.adapter.FragmentStateAdapter; public class ViewPagerFragmentAdapter extends FragmentStateAdapter { private ArrayList<Fragment> arrayList = new ArrayList<>(); public ViewPagerFragmentAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) { super(fragmentManager, lifecycle); } @NonNull @Override public Fragment getItem(int position) { return arrayList.get(position); } public void addFragment(Fragment fragment) { arrayList.add(fragment); } @Override public int getItemCount() { return arrayList.size(); } }
import android.os.Bundle; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.viewpager2.widget.ViewPager2; import neel.com.bottomappbar.R; public class MainActivity extends AppCompatActivity { ViewPager2 myViewPager2; ViewPagerFragmentAdapter myAdapter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myViewPager2=findViewById(R.id.view_pager); myAdapter = new ViewPagerFragmentAdapter(getSupportFragmentManager(), getLifecycle()); // add Fragments in your ViewPagerFragmentAdapter class myAdapter.addFragment(new FragmentOne()); myAdapter.addFragment(new Fragmenttwo()); myAdapter.addFragment(new FragmentThree()); myViewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL); myViewPager2.setAdapter(myAdapter); } }
UPDATE 4
ItemDecorator
eingeführt mit einem Verhalten im Einklang mitRecyclerView
.MarginPageTransformer
eingeführt, um Platz zwischen Seiten zu schaffen (außerhalb des Seiteneinsatzes).CompositePageTransformer
eingeführt, um die Möglichkeit zu bieten, mehrere zu kombinierenPageTransformers
FragmentStateAdapter#getItem
Methode umbenannt inFragmentStateAdapter#createFragment
- Der vorherige Methodenname hat sich in der Vergangenheit als Fehlerquelle erwiesen.OFFSCREEN_PAGE_LIMIT_DEFAULT
Wert von 0 auf -1 geändert. Keine Notwendigkeit für eine Client-Code-Änderung, wenn derOFFSCREEN_PAGE_LIMIT_DEFAULTconstant
verwendet wird.BEISPIELCODE
import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.RecyclerView; import androidx.viewpager2.widget.MarginPageTransformer; import androidx.viewpager2.widget.ViewPager2; import neel.com.bottomappbar.R; public class MainActivity extends AppCompatActivity { ViewPager2 myViewPager2; ViewPagerFragmentAdapter myAdapter; private ArrayList<Fragment> arrayList = new ArrayList<>(); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myViewPager2 = findViewById(R.id.myViewPager2); // add Fragments in your ViewPagerFragmentAdapter class arrayList.add(new FragmentOne()); arrayList.add(new Fragmenttwo()); arrayList.add(new FragmentThree()); myAdapter = new ViewPagerFragmentAdapter(getSupportFragmentManager(), getLifecycle()); // set Orientation in your ViewPager2 myViewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL); myViewPager2.setAdapter(myAdapter); myViewPager2.setPageTransformer(new MarginPageTransformer(1500)); } }
import java.util.ArrayList; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.lifecycle.Lifecycle; import androidx.viewpager2.adapter.FragmentStateAdapter; public class ViewPagerFragmentAdapter extends FragmentStateAdapter { private ArrayList<Fragment> arrayList = new ArrayList<>(); public ViewPagerFragmentAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) { super(fragmentManager, lifecycle); } @NonNull @Override public Fragment createFragment(int position) { switch (position) { case 0: return new FragmentOne(); case 1: return new Fragmenttwo(); case 2: return new FragmentThree(); } return null; } @Override public int getItemCount() { return 3; } }
quelle
PagerTitleStrip
oderPagerTabStrip
mit oder gibt es eine Alternative?Derzeit gibt es ein offizielles Beispiel-Repo für ViewPager2 (unten verlinkt)
Repo enthält folgende Beispiele (Zitat aus der Repo-Readme-Datei unten)
Einfaches Beispiel für ViewPager2 mit Fragmenten in Kotlin
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" xmlns:app="http://schemas.android.com/apk/res-auto" tools:context=".MainActivity"> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/pager2_container" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> </LinearLayout>
MainActivity.kt
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val viewPager2 = findViewById<ViewPager2>(R.id.pager2_container) val fragmentList = arrayListOf( FirstFragment.newInstance(), SecondFragment.newInstance(), ThirdFragment.newInstance() ) viewPager2.adapter = ViewPagerAdapter(this, fragmentList) } }
FirstFragment.kt (
SecondFragment.kt
undThirdFragment.kt
sieht ähnlich ausFirstFragment.kt
)class FirstFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_first, container, false) } companion object{ fun newInstance() = FirstFragment() } }
ViewPagerAdapter.kt
class ViewPagerAdapter(fa:FragmentActivity, private val fragments:ArrayList<Fragment>): FragmentStateAdapter(fa) { override fun getItemCount(): Int = fragments.size override fun createFragment(position: Int): Fragment = fragments[position] }
Einige andere nützliche Ressourcen:
Schulung: https://developer.android.com/training/animation/screen-slide-2
Versionshinweise: https://developer.android.com/jetpack/androidx/releases/viewpager2
Mittlerer Artikel einer GDE: Erkunden des ViewPager2
quelle
Wie auf der Entwicklerseite erwähnt
API-Änderungen
In einfachen Worten funktioniert der View Pager-Adapter wie der Recycle View Adapter.
Hinweis: - In View Pager 2 muss kein Fragment verwendet werden. Es hängt vollständig vom RecyclerView.Adapter-Inflate-Layout ab.
Hier ist ein Beispiel für einen gitHub Repo Link
Beispiel:-
public class MainActivity extends AppCompatActivity { private ViewPager2 mPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getSupportActionBar().setTitle("View Pager 2"); mPager = findViewById(R.id.pager); mPager.setAdapter(new MyViewPagerAdapter(this)); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (R.id.change == item.getItemId()) { mPager.setOrientation(mPager.getOrientation() != ViewPager2.ORIENTATION_VERTICAL ? ViewPager2.ORIENTATION_VERTICAL : ViewPager2.ORIENTATION_HORIZONTAL); } return super.onOptionsItemSelected(item); } }
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.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/pager" android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.constraint.ConstraintLayout>
public class MyViewPagerAdapter extends RecyclerView.Adapter<MyHolder> { private Context context; public MyViewPagerAdapter(Context context) { this.context=context; } @NonNull @Override public MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new MyHolder(LayoutInflater.from(context).inflate(R.layout.cell_item, parent, false)); } @Override public void onBindViewHolder(@NonNull MyHolder holder, int position) { holder.mText.setText("Page "+(position+1)); } @Override public int getItemCount() { return 10; } }
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/text" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="Page 1" android:textSize="20sp" /> </android.support.constraint.ConstraintLayout>
class MyHolder extends RecyclerView.ViewHolder { public TextView mText; public MyHolder(@NonNull View itemView) { super(itemView); mText = itemView.findViewById(R.id.text); } }
Ausgabe:
quelle
Fragment
mit verwendenViewPager2
, überprüfen Sie bitte meine obige Antwort Ich habe Beispielcode fürHow use Fragment with ViewPager2
Folgendes habe ich getan, um ViewPager2 mit TabLayout mit 3 Fragmenten zu implementieren. Vollständiges Beispiel:
Layout enthält
ViewPager2
mitTabLayout
:<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="0dp" android:layout_height="0dp" android:orientation="vertical" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/include3"> <com.google.android.material.tabs.TabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:background="@color/colorPrimary" app:tabTextColor="@color/tab_dismiss_color" app:tabSelectedTextColor="@color/green" android:layout_height="wrap_content" /> <View android:layout_width="match_parent" android:layout_height="1dp" android:layout_gravity="bottom" android:background="#e4e4e4" /> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout>
Starten Sie ViewPager2 und legen Sie den Tab-Namen fest:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_report); ButterKnife.bind(this); actionBarTitleId.setText(R.string.reports); viewPager.setAdapter(new ViewPagerAdapter(this)); new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> { switch (position) { case 0: tab.setText(R.string.financial_duty_str); break; case 1: tab.setText(R.string.financial_unpaid_str); break; case 2: tab.setText(R.string.financial_paid_str); break; } }).attach(); }
ViewPager2
Adapter:public class ViewPagerAdapter extends FragmentStateAdapter { public ViewPagerAdapter(@NonNull FragmentActivity fragmentActivity) { super(fragmentActivity); } @NonNull @Override public Fragment createFragment(int position) { switch (position) { case 0: return new FinancialFragment(); case 1: return new FinancialUnPaidFragment(); case 2: return new FinancialPaidFragment(); default: return null; } } @Override public int getItemCount() { return 3; }
verwendete Abhängigkeit:
implementation "androidx.viewpager2:viewpager2:1.0.0" implementation 'com.google.android.material:material:1.1.0-alpha10'
quelle
Hier meine Lösung (Android Studio 3.6):
In app / build.gradle:
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation('com.crashlytics.sdk.android:crashlytics:2.10.1@aar') { transitive = true; } implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'com.google.android.material:material:1.1.0-beta01' implementation 'org.altbeacon:android-beacon-library:2.16.3' implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0' implementation 'androidx.viewpager2:viewpager2:1.0.0-beta05' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' implementation "androidx.core:core-ktx:+" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" }
Hier meine Tätigkeit:
import android.os.Bundle; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; import androidx.viewpager2.widget.ViewPager2; import java.util.ArrayList; import java.util.List; import com.myproject.android.R; import com.myproject.android.adapter.CustomFragmentStateAdapter; import com.myproject.android.ui.fragment.BluetoothPageFragment; import com.myproject.android.ui.fragment.QrPageFragment; public class QRBluetoothSwipeActivity extends AppCompatActivity { private ViewPager2 myViewPager2; private CustomFragmentStateAdapter myAdapter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { // Make sure this is before calling super.onCreate setTheme(R.style.AppTheme); // show splash screen super.onCreate(savedInstanceState); setContentView(R.layout.qr_bluetooth_swipe_activity); init(); } private void init() { List<Fragment> fragmentList = new ArrayList<Fragment>(); QrPageFragment m1 = new QrPageFragment(); BluetoothPageFragment m2 = new BluetoothPageFragment(); myViewPager2 = findViewById(R.id.viewPager2); fragmentList.add(m2); fragmentList.add(m1); myAdapter = new CustomFragmentStateAdapter(this, fragmentList); myViewPager2.setAdapter(myAdapter); } }
Hier Layout:
<?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=".ui.actviity.SplashDelayActivity"> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/viewPager2" android:layout_width="match_parent" android:layout_height="match_parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
Hier mein CustomFragmentStateAdapter
import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.viewpager2.adapter.FragmentStateAdapter; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; public class CustomFragmentStateAdapter extends FragmentStateAdapter { private List<Fragment> listFragment = new ArrayList<>(); public CustomFragmentStateAdapter(FragmentActivity fa, List<Fragment> list) { super(fa); listFragment = list; } @NotNull @Override public Fragment createFragment(int position) { return listFragment.get(position); } @Override public int getItemCount() { return 2; } }
Und hier meine Fragmente:
import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import com.myproject.android.R; public class BluetoothPageFragment extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.bluetooth_page_fragment, container, false); } }
und zweites Fragment:
import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import com.myproject.android.R; public class QrPageFragment extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.qr_page_fragment, container, false); } }
Und als Ergebnis verwende ich jetzt
androidx.viewpager2.widget.ViewPager2
mit meinen benutzerdefinierten Fragmenten.Und es ist Arbeit !!!
Nett.
PS Ein weiteres Gerät:
public class CustomFragmentStateAdapter extends FragmentStateAdapter { private ArrayList<Fragment> arrayList = new ArrayList<>(); public CustomFragmentStateAdapter (FragmentActivity fa) { super(fa); } public void addFragment(Fragment fragment) { arrayList.add(fragment); } @Override public int getItemCount() { return arrayList.size(); } @NonNull @Override public Fragment createFragment(int position) { // return your fragment that corresponds to this 'position' return arrayList.get(position); } }
Und verwenden Sie wie folgt (in Aktivität):
myViewPager2 = findViewById(R.id.viewPager2); myAdapter = new CustomFragmentStateAdapter (this); myAdapter.addFragment(new QrPageFragment()); myAdapter.addFragment(new BluetoothPageFragment()); myViewPager2.setAdapter(myAdapter);
quelle
createFragment
Rückruf desFragmentStateAdapter
Solls (wie die Methode sagt)create
aFragment
. Und nicht eine geben, die bereits erstellt wurde und herumliegt. Wenn Sie Ihren Ansatz verwenden, bringen Sie dieFragmentManager's
Bedienung durcheinander .Wie man es benutzt, wird sehr klar erklärt. Lassen Sie mich kleine, aber sehr wichtige Tipps und Details zu ViewPager2 geben, insbesondere wenn es sich in einem Fragment befindet, wie Speicherlecks verhindert werden können
Verwenden Sie nicht den Konstruktor, der Fragmente nimmt, insbesondere wenn Sie verwenden
TabLayout
.public FragmentStateAdapter(@NonNull Fragment fragment) { this(fragment.getChildFragmentManager(), fragment.getLifecycle()); }
weil das Risiko eines Speicherverlusts besteht, wie hier beschrieben
Verwenden Sie stattdessen FragmentManager und LifeCycle. Und senden Sie kein
lifeCycle
Fragment als Argument, verwenden SieviewLifeCycleOwner
den Lebenszyklus, da viewLifeCycleOwner den Lebenszyklus von Fragmenten darstelltview
.class NavigableFragmentStateAdapter( fragmentManager: FragmentManager, lifecycle: Lifecycle ) : FragmentStateAdapter(fragmentManager, lifecycle) { }
und Adapter mit in einstellen
onCreateView
viewPager.adapter = NavigableFragmentStateAdapter(childFragmentManager, viewLifecycleOwner.lifecycle)
TabLayout
wenn sich ViewPager2 in einem Fragment befindet, vergessen Sie nicht, TabLayout zu trennen und den Adapter von ViewPager2 als festzulegenTrennen Sie TabLayoutMediator, da es Speicherlecks verursacht, wenn es sich in einem Fragment befindet
/programming/61779776/leak-canary-detects-memory-leaks-for-tablayout-with-viewpager2
ViewPager2 in einem Fragment leckt, nachdem das Fragment, in dem es sich befindet, durch die Navigation der Navigationskomponente ersetzt wurde
TabLayoutMediator(tabLayout, viewPager2, tabConfigurationStrategy).detach() viewPager2.adapter = null
innere
onDestroyView
Methode des FragmentsWenn Sie Seiten von ViewPager wie
navHostFragment
Navigationskomponenten verwenden möchten, um zu untergeordneten Fragmenten zurückzukehren, registrieren Sie FragmentTransactionCallback inFragmentStateAdapter
asprivate val fragmentTransactionCallback = object : FragmentStateAdapter.FragmentTransactionCallback() { override fun onFragmentMaxLifecyclePreUpdated( fragment: Fragment, maxLifecycleState: Lifecycle.State ) = if (maxLifecycleState == Lifecycle.State.RESUMED) { // This fragment is becoming the active Fragment - set it to // the primary navigation fragment in the OnPostEventListener OnPostEventListener { fragment.parentFragmentManager.commitNow { setPrimaryNavigationFragment(fragment) } } } else { super.onFragmentMaxLifecyclePreUpdated(fragment, maxLifecycleState) } } init { // Add a FragmentTransactionCallback to handle changing // the primary navigation fragment registerFragmentTransactionCallback(fragmentTransactionCallback) }
Wenn Sie einige Beispiele zur Verwendung von ViewPager2 mit Navigationskomponenten, dynamischen Funktionsmodulen und zur Kombination mit BottomNavigationView sehen möchten, können Sie die Tutorials in diesem Github-Repo lesen.
quelle