我正在使用帶有5個標簽的BottomNavigationView。最初,我在應用程式啟動時加載第一個標簽。當我點擊任何其他標簽時,就會進行API呼叫并加載資料。現在,當我再次點擊前一個標簽(在啟動時加載)時,API呼叫再次加載相同的資料。
我不希望再次加載資料,并希望在不重新呼叫 API 的情況下顯示具有相同資料的片段。
我的代碼: 我不想使用 uj5u.com熱心網友回復: 我不知道這是否可能,因為使用導航組件時,只要你使用它,它就會彈出片段堆疊。 但是為了保持資料,我認為有一個方法,那就是使用ViewModel,即使片段被破壞,它也會保持活力。
現在你會想到,每次從零開始創建的片段都會從頭開始創建ViewModel,但這里有一個轉折,只要你通過ViewModelProvider給它一個參考的物件還活著,ViewModel就會一直活著,在我們的例子中就是主活動。
這樣一來,只要你的活動沒有被破壞,ViewModel 就會在應用程式的整個生命周期中只呼叫一次它的建構式,而且之后每次你在片段的 onCreate 中詢問 ViewModel 時,它都會給你一個先前創建的參考,而不是創建一個新的(如果你之前遇到過設計模式,就像單子設計模式)。
隨后您可以為您的 ViewModel 添加一個 getter,以便在您的片段中隨時獲取資料。
N.B:你在ViewModel中帶來和存盤的資料會消耗你的RAM,所以要避免擁有大量的資料,只存盤必要的資料,所以作為一個例子,不要存盤一個位圖,而是存盤它的URI/不要存盤一個擁有屬于資料庫的鍵/ID的物件,只存盤鍵/ID,當你需要時,只需從資料庫中將它帶入記憶體。
前面的通知對于在你的應用中避免OutOfMemoryError例外非常重要。
如果你對ViewModels感到好奇,你可以通過這個鏈接開始閱讀它們 uj5u.com熱心網友回復: 這可能是一個比你所希望的更復雜的解決方案,但將資料與UI解耦將是一個好辦法。這意味著使用類似于 MVVM 的東西,然后只保留 ViewModel 資料(而不是人為地保持片段的活力) 另一個更簡單/更快速的方法是將資料與 UI 分離。
另一個更簡單/更快速的解決方案是使用一個存盤庫,并將加載的資料保存在該類中,然后片段可以只檢查存盤庫是否已經加載了資料,然后相應地顯示內容。
標籤: 上一篇:更新了正確的chrome驅動路徑/驅動版本,也添加了seleniumjar,但還是出現以下問題,你能幫我解決嗎?
public class MainActivity extends AppCompatActivity implements NavigationBarView. OnItemSelectedListener {
private BottomNavigationView bottomNavigationView。
public static ViewPager2 viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(s savedInstanceState)。
setContentView(R.layout.activity_main)。
viewPager = findViewById(R.id.viewpager);
bottomNavigationView = findViewById(R.id.navigation);
bottomNavigationView.setOnItemSelectedListener(this)。
getTabs()。
}
public void getTabs() {
FragmentManager fragmentManager = getSupportFragmentManager()。
FragmentAdapterMain adapter = new FragmentAdapterMain(fragmentManager。getLifecycle())。
viewPager.setAdapter(adapter);
viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override。
public void onPageSelected(int position) {
super.onPageSelected(position)。
switch (position) {
case 0:
bottomNavigationView.getMenu().findItem(R.id.one).setChecked(true)。
break。
case 1:
bottomNavigationView.getMenu().findItem(R.id.two).setChecked(true)。
break。
case 2:
bottomNavigationView.getMenu().findItem(R.id.three).setChecked(true)。
break。
case 3:
bottomNavigationView.getMenu().findItem(R.id.four).setChecked(true)。
break。
case 4:
bottomNavigationView.getMenu().findItem(R.id.five).setChecked(true)。
break。
}
}
});
}
@SuppressLint("NonConstantResourceId")/span>
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item){
switch (item.getItemId() ) {
case R.id.one:
viewPager.setCurrentItem(0, false)。
break。
case R.id.two:
viewPager.setCurrentItem(1, false) 。
break。
case R.id.3:
viewPager.setCurrentItem(2, false) 。
break;
case R.id.four。
viewPager.setCurrentItem(3, false) 。
break。
case R.id.five:
viewPager.setCurrentItem(4, false) 。
break。
}
return true;
}
viewPager.setOffscreenPageLimit(size),因為它在啟動時一次性加載所有5個片段的資料(我不想在啟動時呼叫所有5個API)。
dependencies {
...
實作 "androidx.lifecycle:lifecycle-viewmodel:2.3.1"
實作 "androidx.lifecycle:lifecycle-common-java8:2.3.1"。
...
}
public class MyViewModel extends ViewModel {
資料類 myData 。
public MyViewModel () {
super()。
getData()。
}
void getData(){
...
將myData分配到這里
...
}
}
MyViewModel myViewMode= new ViewModelProvider(requireActivity()).get(MyViewModel .class)。
