Skip to content

Commit 013616a

Browse files
committed
fix(bottom-navigation/tabs): android full rewrite using ViewPager2
1 parent 64aa993 commit 013616a

File tree

3 files changed

+41
-76
lines changed

3 files changed

+41
-76
lines changed

packages/core-tabs/platforms/android/java/com/nativescript/material/core/TabStrip.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,15 @@ int getSelectedPosition(){
183183

184184
void setSelectedPosition(int position) {
185185
if (mSelectedPosition != position) {
186-
getChildAt(mSelectedPosition).setSelected(false);
187-
getChildAt(position).setSelected(true);
188-
updateTabTextColor(mSelectedPosition, false);
189-
updateTabTextColor(position, false);
186+
final int childCount = getChildCount();
187+
if (mSelectedPosition > -1 && mSelectedPosition < childCount ) {
188+
getChildAt(mSelectedPosition).setSelected(false);
189+
updateTabTextColor(mSelectedPosition, false);
190+
}
191+
if (position > -1 && position < childCount ) {
192+
getChildAt(position).setSelected(true);
193+
updateTabTextColor(position, true);
194+
}
190195
mSelectedPosition = position;
191196
invalidate();
192197
}

src/bottom-navigation/index.android.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,10 @@ export class BottomNavigation extends TabNavigation<com.nativescript.material.co
9696
// }
9797
}
9898

99-
_onAttachedToWindow(): void {
100-
super._onAttachedToWindow();
101-
// this.changeTab(this.selectedIndex);
102-
}
99+
// _onAttachedToWindow(): void {
100+
// super._onAttachedToWindow();
101+
// // this.changeTab(this.selectedIndex);
102+
// }
103103

104104
public override updateAndroidItemAt(index: number, spec: com.nativescript.material.core.TabItemSpec) {
105105
// that try catch is fix for an android NPE error on css change which navigated in (not the current fragment)

src/core-tabs/tab-navigation/index.android.ts

Lines changed: 28 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { Application, Color, CoreTypes, Font, Frame, ImageSource, Utils, View, getTransformedText } from '@nativescript/core';
1+
import { Application, Color, CoreTypes, Font, ImageSource, Utils, getTransformedText } from '@nativescript/core';
22
import { TabContentItem } from '../tab-content-item';
33
import { getIconSpecSize, itemsProperty, selectedIndexProperty, tabStripProperty } from '../tab-navigation-base';
44
import { TabStrip } from '../tab-strip';
55
import { TabStripItem } from '../tab-strip-item';
6-
import { TabNavigationBase, TabsPosition, animationEnabledProperty, offscreenTabLimitProperty, swipeEnabledProperty } from './index-common';
6+
import { TabNavigationBase, TabsPosition, offscreenTabLimitProperty, swipeEnabledProperty } from './index-common';
77
export * from './index-common';
88
export { TabContentItem, TabStrip, TabStripItem };
99

@@ -27,7 +27,6 @@ let PagerAdapter: PagerAdapter;
2727
// eslint-disable-next-line no-redeclare
2828
let PageChangeCallback: PageChangeCallback;
2929
let appResources: android.content.res.Resources;
30-
// let AttachStateChangeListener: any;
3130

3231
function getTabById(id: number): TabNavigation {
3332
const ref = tabs.find((ref) => {
@@ -75,7 +74,7 @@ function initializeNativeClasses() {
7574
class TabFragmentImplementation extends org.nativescript.widgets.FragmentBase {
7675
private owner: TabNavigation;
7776
private index: number;
78-
private backgroundBitmap: android.graphics.Bitmap = null;
77+
// private backgroundBitmap: android.graphics.Bitmap = null;
7978

8079
constructor() {
8180
super();
@@ -111,7 +110,6 @@ function initializeNativeClasses() {
111110
}
112111

113112
public onDestroyView() {
114-
console.log('TabFragmentImplementation', 'onDestroyView', this.index);
115113
// const hasRemovingParent = this.getRemovingParentFragment();
116114

117115
// // Get view as bitmap and set it as background. This is workaround for the disapearing nested fragments.
@@ -160,54 +158,30 @@ function initializeNativeClasses() {
160158

161159
@NativeClass
162160
class FragmentPagerAdapter extends androidx.viewpager2.adapter.FragmentStateAdapter {
163-
public items: TabContentItem[];
164-
private mCurTransaction: androidx.fragment.app.FragmentTransaction;
165-
private mCurrentPrimaryItem: androidx.fragment.app.Fragment;
166-
167161
constructor(public owner: WeakRef<TabNavigation>, fragmentActivity: androidx.fragment.app.FragmentActivity) {
168162
super(fragmentActivity);
169-
170163
return global.__native(this);
171164
}
172165

173166
getItemCount() {
174-
const items = this.items;
175-
176-
return items ? items.length : 0;
167+
const owner = this.owner?.get();
168+
if (!owner) {
169+
return 0;
170+
}
171+
return owner.items.length;
177172
}
178-
179-
// getPageTitle(index: number) {
180-
// const items = this.items;
181-
// if (index < 0 || index >= items.length) {
182-
// return '';
183-
// }
184-
185-
// return ''; // items[index].title;
186-
// }
187173
createFragment(position: number): androidx.fragment.app.Fragment {
188174
const owner = this.owner?.get();
189175
if (!owner) {
190176
return null;
191177
}
192-
193-
const itemId = this.getItemId(position);
194-
// const name = makeFragmentName(itemId);
195-
196178
const fragment: androidx.fragment.app.Fragment = TabFragmentImplementation.newInstance(owner._domId, position);
197-
198-
const tabItems = owner.items;
199-
const tabItem = tabItems ? tabItems[position] : null;
200-
if (tabItem) {
201-
tabItem.canBeLoaded = true;
202-
}
203-
204179
return fragment;
205180
}
206181
}
207182

208183
PagerAdapter = FragmentPagerAdapter;
209184
PageChangeCallback = PageChangeCallbackImpl;
210-
// AttachStateChangeListener = new AttachListener();
211185
appResources = Application.android.context.getResources();
212186
}
213187

@@ -238,17 +212,8 @@ function setElevation(grid: org.nativescript.widgets.GridLayout, tabsBar: androi
238212

239213
export const tabs = new Array<WeakRef<TabNavigation>>();
240214

241-
function iterateIndexRange(index: number, eps: number, lastIndex: number, callback: (i) => void) {
242-
const rangeStart = Math.max(0, index - eps);
243-
const rangeEnd = Math.min(index + eps, lastIndex);
244-
for (let i = rangeStart; i <= rangeEnd; i++) {
245-
callback(i);
246-
}
247-
}
248-
249215
//TODO: move to abstract
250216
export abstract class TabNavigation<T extends android.view.ViewGroup = any> extends TabNavigationBase {
251-
// export abstract class TabNavigation<T extends com.nativescript.material.core.TabsBar> extends TabNavigationBase {
252217
nativeViewProtected: org.nativescript.widgets.GridLayout;
253218
protected mTabsBar: T;
254219
protected mViewPager: androidx.viewpager2.widget.ViewPager2;
@@ -289,9 +254,6 @@ export abstract class TabNavigation<T extends android.view.ViewGroup = any> exte
289254
const context: android.content.Context = this._context;
290255
const nativeView = new org.nativescript.widgets.GridLayout(context);
291256
const viewPager = new androidx.viewpager2.widget.ViewPager2(context);
292-
//dirty trick to be able to disable swipe
293-
// const recyclerView = viewPager as any as androidx.recyclerview.widget.RecyclerView;
294-
// recyclerView.addOnItemTouchListener();
295257
const lp = new org.nativescript.widgets.CommonLayoutParams();
296258
lp.row = 1;
297259
if (this.tabsPosition === 'top') {
@@ -313,7 +275,6 @@ export abstract class TabNavigation<T extends android.view.ViewGroup = any> exte
313275
(viewPager as any).adapter = adapter;
314276
this.mViewPager = viewPager;
315277
setElevation(nativeView, null, this.tabsPosition);
316-
317278
if (this.tabStrip) {
318279
this.handleTabStripChanged(nativeView, null, this.tabStrip);
319280
}
@@ -344,6 +305,7 @@ export abstract class TabNavigation<T extends android.view.ViewGroup = any> exte
344305
}
345306
nativeView.addView(tabsBar);
346307
nativeView['tabsBar'] = tabsBar;
308+
this.setTabStripItems(newTabStrip?.items || null);
347309
}
348310
}
349311
public onTabStripChanged(oldTabStrip: TabStrip, newTabStrip: TabStrip) {
@@ -388,13 +350,14 @@ export abstract class TabNavigation<T extends android.view.ViewGroup = any> exte
388350
public onLoaded(): void {
389351
super.onLoaded();
390352

391-
if (this._originalBackground) {
392-
this.backgroundColor = null;
393-
this.backgroundColor = this._originalBackground;
394-
this._originalBackground = null;
395-
}
353+
// if (this._originalBackground) {
354+
// console.log('setting original background', this._originalBackground);
355+
// this.backgroundColor = null;
356+
// this.backgroundColor = this._originalBackground;
357+
// this._originalBackground = null;
358+
// }
396359

397-
this.setItems(this.items as any);
360+
// this.setItems(this.items as any);
398361

399362
if (this.tabStrip) {
400363
this.setTabStripItems(this.tabStrip.items);
@@ -404,13 +367,13 @@ export abstract class TabNavigation<T extends android.view.ViewGroup = any> exte
404367
public onUnloaded(): void {
405368
super.onUnloaded();
406369

407-
this.setItems(null);
408-
this.setTabStripItems(null);
370+
// this.setItems(null);
371+
// this.setTabStripItems(null);
409372

410373
// TODO: needed ?
411-
this.items.forEach((item, i) => {
412-
item.unloadView(item.content);
413-
});
374+
// this.items.forEach((item, i) => {
375+
// item.unloadView(item.content);
376+
// });
414377
}
415378

416379
private shouldUpdateAdapter(items: TabContentItem[]) {
@@ -447,15 +410,13 @@ export abstract class TabNavigation<T extends android.view.ViewGroup = any> exte
447410
}
448411

449412
private setItems(items: TabContentItem[]) {
413+
if (items && items.length) {
414+
items.forEach((item: TabContentItem, i) => {
415+
item.index = i;
416+
});
417+
}
418+
this._loadUnloadTabItems(this.selectedIndex);
450419
if (this.shouldUpdateAdapter(items)) {
451-
(this.mPagerAdapter as any).items = items;
452-
453-
if (items && items.length) {
454-
items.forEach((item: TabContentItem, i) => {
455-
(item as any).index = i;
456-
});
457-
}
458-
459420
this.mPagerAdapter.notifyDataSetChanged();
460421
}
461422
}
@@ -664,8 +625,7 @@ export abstract class TabNavigation<T extends android.view.ViewGroup = any> exte
664625
if (!tabStripItem.nativeViewProtected) {
665626
return;
666627
}
667-
const itemColor = tabStripItem.index === this.selectedIndex ? this.mSelectedItemColor : this.mUnSelectedItemColor;
668-
628+
const itemColor = tabStripItem.index === this.selectedIndex ? this.mSelectedItemColor : tabStripItem.style.color || this.mUnSelectedItemColor;
669629
// set label color
670630
if (itemColor) {
671631
tabStripItem.nativeViewProtected.setTextColor(itemColor.android || null);

0 commit comments

Comments
 (0)