Risposte:
Se conosci l'indice della scheda che desideri selezionare, puoi farlo in questo modo:
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
TabLayout.Tab tab = tabLayout.getTabAt(someIndex);
tab.select();
Questa tecnica funziona anche se stai usando TabLayout da solo senza un ViewPager (che è atipico e probabilmente una cattiva pratica, ma l'ho visto fatto).
Ecco come l'ho risolto:
void selectPage(int pageIndex){
tabLayout.setScrollPosition(pageIndex,0f,true);
viewPager.setCurrentItem(pageIndex);
}
Usa questo:
tabs.getTabAt(index).select();
Objects.requireNonNull(tabs.getTabAt(position)).select();
sicuro da usare
Usa questo:
<android.support.design.widget.TabLayout
android:id="@+id/patienthomescreen_tabs"
android:layout_width="match_parent"
android:layout_height="72sp"
app:tabGravity="fill"
app:tabMode="fixed"
app:tabIndicatorColor="@android:color/white"
app:tabSelectedTextColor="@color/green"/>
Dopo in OnClickListener:
TabLayout tabLayout = (TabLayout) findViewById(R.id.patienthomescreen_tabs);
TabLayout.Tab tab = tabLayout.getTabAt(someIndex);
tab.select();
Questa probabilmente non è la soluzione definitiva , e richiede di usare TabLayout
insieme aViewPager
, ma è così che l'ho risolto:
void selectPage(int pageIndex)
{
viewPager.setCurrentItem(pageIndex);
tabLayout.setupWithViewPager(viewPager);
}
Ho testato l'impatto delle prestazioni dell'utilizzo di questo codice osservando prima i monitor della CPU e della memoria in Android Studio durante l'esecuzione del metodo, quindi confrontandolo con il carico che è stato inserito nella CPU e nella memoria quando ho navigato tra le pagine me stesso (usando i gesti di scorrimento) e la differenza non è significativamente grande, quindi almeno non è una soluzione orribile ...
Spero che questo aiuti qualcuno!
tabLayout.setScrollPosition(pageIndex,0f,true);
), quando ho fatto clic sulla scheda a destra, non ho aggiornato la pagina di ViewPager (non so perché). Solo facendo clic indietro sulla scheda sinistra e quindi nuovamente sulla scheda destra, si aggiorna infine la pagina per avere la pagina della scheda destra, che è molto glitch. Ma questa soluzione non ha avuto problemi.
Se non puoi usare tab.select () e non vuoi usare un ViewPager, puoi comunque selezionare una scheda a livello di programmazione. Se stai usando una vista personalizzata attraverso di TabLayout.Tab setCustomView(android.view.View view)
essa è più semplice. Ecco come farlo in entrambi i modi.
// if you've set a custom view
void updateTabSelection(int position) {
// get the position of the currently selected tab and set selected to false
mTabLayout.getTabAt(mTabLayout.getSelectedTabPosition()).getCustomView().setSelected(false);
// set selected to true on the desired tab
mTabLayout.getTabAt(position).getCustomView().setSelected(true);
// move the selection indicator
mTabLayout.setScrollPosition(position, 0, true);
// ... your logic to swap out your fragments
}
Se non stai utilizzando una vista personalizzata, puoi farlo in questo modo
// if you are not using a custom view
void updateTabSelection(int position) {
// get a reference to the tabs container view
LinearLayout ll = (LinearLayout) mTabLayout.getChildAt(0);
// get the child view at the position of the currently selected tab and set selected to false
ll.getChildAt(mTabLayout.getSelectedTabPosition()).setSelected(false);
// get the child view at the new selected position and set selected to true
ll.getChildAt(position).setSelected(true);
// move the selection indicator
mTabLayout.setScrollPosition(position, 0, true);
// ... your logic to swap out your fragments
}
Utilizzare un StateListDrawable per alternare tra disegni estraibili selezionati e non selezionati o qualcosa di simile per fare ciò che si desidera con colori e / o disegni.
Basta impostare viewPager.setCurrentItem(index)
e il TabLayout associato selezionerebbe la rispettiva scheda.
prova questo
new Handler().postDelayed(
new Runnable(){
@Override
public void run() {
if (i == 1){
tabLayout.getTabAt(0).select();
} else if (i == 2){
tabLayout.getTabAt(1).select();
}
}
}, 100);
Un po 'in ritardo, ma potrebbe essere una soluzione utile. Sto usando il mio TabLayout direttamente nel mio frammento e sto provando a selezionare una scheda abbastanza presto nel ciclo di vita del frammento. Quello che ha funzionato per me è stato aspettare fino a quando TabLayout ha finito di disegnare le sue viste figlio usando il android.view.View#post
metodo. vale a dire:
int myPosition = 0;
myFilterTabLayout.post(() -> { filterTabLayout.getTabAt(myPosition).select(); });
new Handler().postDelayed(()->{ tabLayout.post(() -> { tabLayout.getTabAt(myPosition).select(); }); },200);
Io sto usando TabLayout per passare frammenti. Funziona per la maggior parte, tranne quando ho provato a selezionare una scheda in modo programmatico usando tab.select()
, il mio TabLayout.OnTabSelectedListener
avrebbe innescato il onTabSelected(TabLayout.Tab tab)
, il che mi avrebbe causato molto dolore. Stavo cercando un modo per fare la selezione programmatica senza innescare l'ascoltatore.
Quindi ho adattato la risposta di @kenodoggy al mio uso. Stavo affrontando ulteriormente un problema in cui alcuni degli oggetti interni sarebbero tornati null (perché non erano ancora stati creati, perché rispondevo onActivityResult()
dal mio frammento, che si verifica prima onCreate()
nel caso l'attività sia singleTask
o singleInstance
), quindi ho scritto un dettagliato se / else sequenza che segnalerebbe l'errore e cadrebbe senza NullPointerException
che altrimenti si innescherebbe. Uso Timber per la registrazione, se non si utilizza quel sostituto con Log.e()
.
void updateSelectedTabTo(int position) {
if (tabLayout != null){
int selected = tabLayout.getSelectedTabPosition();
if (selected != -1){
TabLayout.Tab oldTab = tabLayout.getTabAt(0);
if (oldTab != null){
View view = oldTab.getCustomView();
if (view != null){
view.setSelected(false);
}
else {
Timber.e("oldTab customView is null");
}
}
else {
Timber.e("oldTab is null");
}
}
else {
Timber.e("selected is -1");
}
TabLayout.Tab newTab = tabLayout.getTabAt(position);
if (newTab != null){
View view = newTab.getCustomView();
if (view != null){
view.setSelected(false);
}
else {
Timber.e("newTab customView is null");
}
}
else {
Timber.e("newTab is null");
}
}
else {
Timber.e("tablayout is null");
}
}
Qui tabLayout è la mia variabile di memoria associata TabLayout
all'oggetto nel mio XML. E non utilizzo la funzione di scorrimento delle schede, quindi ho rimosso anche quella.
dovresti usare un viewPager per usare viewPager.setCurrentItem ()
viewPager.setCurrentItem(n);
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
aggiungi per il tuo viewpager:
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
array.clear();
switch (position) {
case 1:
//like a example
setViewPagerByIndex(0);
break;
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
// sul gestore per impedire il crash outofmemory
private void setViewPagerByIndex(final int index){
Application.getInstance().getHandler().post(new Runnable() {
@Override
public void run() {
viewPager.setCurrentItem(index);
}
});
}
Con il TabLayout
fornito dalla Material Components Library basta usare il selectTab
metodo:
TabLayout tabLayout = findViewById(R.id.tab_layout);
tabLayout.selectTab(tabLayout.getTabAt(index));
Richiede la versione 1.1.0.
Per impostazione predefinita, se si seleziona una scheda, questa verrà evidenziata. Se si desidera selezionare esplicitamente significa utilizzare il codice commentato specificato in onTabSelected (scheda TabLayout.Tab) con la posizione dell'indice della scheda specificata. Questo codice spiega come modificare il frammento nella posizione selezionata sulla scheda usando viewpager.
public class GalleryFragment extends Fragment implements TabLayout.OnTabSelectedListener
{
private ViewPager viewPager;public ViewPagerAdapter adapter;private TabLayout tabLayout;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_gallery, container, false);
viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
adapter = new ViewPagerAdapter(getChildFragmentManager());
adapter.addFragment(new PaymentCardFragment(), "PAYMENT CARDS");
adapter.addFragment(new LoyaltyCardFragment(), "LOYALTY CARDS");
viewPager.setAdapter(adapter);
tabLayout = (TabLayout) rootView.findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
tabLayout.setOnTabSelectedListener(this);
}
@Override
public void onTabSelected(TabLayout.Tab tab) {
//This will be called 2nd when you select a tab or swipe using viewpager
final int position = tab.getPosition();
Log.i("card", "Tablayout pos: " + position);
//TabLayout.Tab tabdata=tabLayout.getTabAt(position);
//tabdata.select();
tabLayout.post(new Runnable() {
@Override
public void run() {
if (position == 0) {
PaymentCardFragment paymentCardFragment = getPaymentCardFragment();
if (paymentCardFragment != null) {
VerticalViewpager vp = paymentCardFragment.mypager;
if(vp!=null)
{
//vp.setCurrentItem(position,true);
vp.setCurrentItem(vp.getAdapter().getCount()-1,true);
}
}
}
if (position == 1) {
LoyaltyCardFragment loyaltyCardFragment = getLoyaltyCardFragment();
if (loyaltyCardFragment != null) {
VerticalViewpager vp = loyaltyCardFragment.mypager;
if(vp!=null)
{
vp.setCurrentItem(position);
}
}
}
}
});
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
//This will be called 1st when you select a tab or swipe using viewpager
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
//This will be called only when you select the already selected tab(Ex: selecting 3rd tab again and again)
}
private PaymentCardFragment getLoyaltyCardFragment() {
Fragment f = adapter.mFragmentList.get(viewPager.getCurrentItem());
if(f instanceof PaymentCardFragment)
{
return (PaymentCardFragment) f;
}
return null;
}
private LoyaltyCardFragment getPaymentCardFragment() {
Fragment f = adapter.mFragmentList.get(viewPager.getCurrentItem());
if(f instanceof LoyaltyCardFragment)
{
return (LoyaltyCardFragment) f;
}
return null;
}
class ViewPagerAdapter extends FragmentPagerAdapter {
public List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
}
}
Anche questo può aiutare
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int i) {
tablayout.getTabAt(i).select();
}
@Override
public void onPageScrollStateChanged(int i) {
}
});
In tal caso, la scheda predefinita è la prima (0) e si passa a un frammento, quindi è necessario sostituire manualmente il frammento per la prima volta. Questo perché la scheda è selezionata prima che l'ascoltatore venga registrato.
private TabLayout mTabLayout;
...
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tablayout, container, false);
mTabLayout = view.findViewById(R.id.sliding_tabs);
mTabLayout.addOnTabSelectedListener(mOnTabSelectedListener);
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.tabContent, MyFirstFragment.newInstance()).commit();
return view;
}
In alternativa, puoi considerare di chiamare getTabAt(0).select()
e sovrascrivere in questo onTabReselected
modo:
@Override
public void onTabReselected(TabLayout.Tab tab) {
// Replace the corresponding tab fragment.
}
Questo funzionerebbe perché stai essenzialmente sostituendo il frammento su ogni scheda selezionata nuovamente.
È possibile impostare la posizione TabLayout utilizzando le seguenti funzioni
public void setTab(){
tabLayout.setScrollPosition(YOUR_SCROLL_INDEX,0,true);
tabLayout.setSelected(true);
}
Se hai difficoltà a capire, questo codice può aiutarti
private void MyTabLayout(){
TabLayout.Tab myTab = myTabLayout.newTab(); // create a new tab
myTabLayout.addTab(myTab); // add my new tab to myTabLayout
myTab.setText("new tab");
myTab.select(); // select the new tab
}
Puoi anche aggiungere questo al tuo codice:
myTabLayout.setTabTextColors(getColor(R.color.colorNormalTab),getColor(R.color.colorSelectedTab));
Prova in questo modo.
tabLayout.setTabTextColors(getResources().getColor(R.color.colorHintTextLight),
getResources().getColor(R.color.colorPrimaryTextLight));
se stai usando TabLayout senza viewPager questo aiuta
mTitles = getResources().getStringArray(R.array.tabItems);
mIcons = getResources().obtainTypedArray(R.array.tabIcons);
for (int i = 0; i < mTitles.length; i++) {
tabs.addTab(tabs.newTab().setText(mTitles[i]).setIcon(mIcons.getDrawable(i)));
if (i == 0) {
/*For setting selected position 0 at start*/
Objects.requireNonNull(Objects.requireNonNull(tabs.getTabAt(i)).getIcon()).setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary), PorterDuff.Mode.SRC_IN);
}
}
tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
Objects.requireNonNull(tab.getIcon()).setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary), PorterDuff.Mode.SRC_IN);
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
Objects.requireNonNull(tab.getIcon()).setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.white), PorterDuff.Mode.SRC_IN);
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
Correzione di Kotlin
viewPager.currentItem = 0
tabs.setupWithViewPager (viewPager)
TabLayout jobTabs = v.findViewById(R.id.jobTabs);
ViewPager jobFrame = v.findViewById(R.id.jobPager);
jobFrame.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(jobTabs));
questo seleziona la scheda come pagina di scorrimento del pager di visualizzazione
TabLayout.Tab.select()
: "Seleziona questa scheda. Valido solo se la scheda è stata aggiunta alla barra delle azioni."