1

Я знаю, что есть несколько других сообщений по этой теме, но я хотел вставить свой код, потому что я считаю, что в нем может быть ошибка, которая вызывает мою проблему. Мой FragmentStatePagerAdapter возвращает неправильную позицию, и я не уверен, почему.FragmentStatePagerAdapter - getItem

Вот код моей основной деятельности.

Main.java

import android.content.Context; 
    import android.content.Intent; 
    import android.graphics.Typeface; 
    import android.os.Bundle; 
    import android.support.design.widget.TabLayout; 
    import android.support.v4.app.Fragment; 
    import android.support.v4.app.FragmentTabHost; 
    import android.support.v4.content.ContextCompat; 
    import android.support.v4.view.ViewPager; 
    import android.support.v7.app.ActionBar; 
    import android.support.v7.app.AppCompatActivity; 
    import android.support.v7.widget.Toolbar; 
    import android.view.LayoutInflater; 
    import android.view.MenuItem; 
    import android.view.View; 
    import android.widget.Button; 
    import android.widget.ImageButton; 
    import android.widget.ImageView; 
    import android.widget.TabHost.OnTabChangeListener; 
    import android.widget.TextView; 
    import android.widget.Toast; 

    import com.google.android.gms.common.ConnectionResult; 
    import com.google.android.gms.common.GoogleApiAvailability; 
    import com.google.android.gms.gcm.GoogleCloudMessaging; 
    import com.microsoft.windowsazure.notifications.NotificationsManager; 

    import java.util.ArrayList; 

    public class Main extends AppCompatActivity { 

     public static TextView txtViewHeading; 
     public static TextView tab1TabBadge; 
     public static TextView tab2TabBadge; 
     public static TextView tab3TabBadge; 
     public static TextView tab4TabBadge; 
     public static TextView tab5TabBadge; 
     public static Button btnBack; 
     public static ImageButton btnShare; 
     public static Main mainActivity; 
     public static Context mainActivityContext; 
     public static Boolean isVisible = false; 
     private FragmentTabHost mTabHost; 
     private GoogleCloudMessaging gcm; 
     private ActionBar actionBar; 
     private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000; 

     private TabGroupAdapter mTabGroupAdapter; 
     private ViewPager mViewPager; 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.main); 

      // Set up Push notifications 
      mainActivity = this; 
      mainActivityContext = Main.this; 
      NotificationsManager.handleNotifications(this, NotificationSettings.SenderId, PushHandler.class); 
      registerWithNotificationHubs(); 

      // Set up the views for each tab - custom view used for Badge icon 
      LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

      // Bind the Toolbar 
      Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
      setSupportActionBar(toolbar); 

      // Set up the ActionBar 
      actionBar = getSupportActionBar(); 
      if (actionBar!=null) { 
       actionBar.setDisplayHomeAsUpEnabled(true); 
       actionBar.setHomeButtonEnabled(true); 
      } 

      // Create the adapter that will return a fragment for each of the primary "tabs" 
      mTabGroupAdapter = new TabGroupAdapter(getSupportFragmentManager()); 

      // Set up the ViewPager with the sections adapter. 
      mViewPager = (ViewPager) findViewById(R.id.container); 
      mViewPager.setAdapter(mTabGroupAdapter); 

      TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); 
      tabLayout.setupWithViewPager(mViewPager); 

      // tab1 Tab 
      View tab1TabView = inflater.inflate(R.layout.tab, null); 
      ImageView tab1TabIcon = (ImageView) tab1TabView.findViewById(R.id.tabIcon); 
      tab1TabIcon.setImageResource(R.drawable.tab_first); 
      TextView tab1TabText = (TextView) tab1TabView.findViewById(R.id.tabText); 
      tab1TabText.setText("tab1"); 
      tab1TabText.setTypeface(arialTypeface); 
      tab1TabBadge = (TextView) tab1TabView.findViewById(R.id.tabBadge); 
      tab1TabBadge.setTypeface(arialTypeface); 
      tabLayout.getTabAt(0).setCustomView(tab1TabView); 
      // Also set this tab as Active be default 
      tabLayout.getTabAt(0).getCustomView().setSelected(true); 
      mViewPager.setCurrentItem(0); 

      // tab2 Tab 
      View tab2TabView = inflater.inflate(R.layout.tab, null); 
      ImageView tab2TabIcon = (ImageView) tab2TabView.findViewById(R.id.tabIcon); 
      tab2TabIcon.setImageResource(R.drawable.tab_second); 
      TextView tab2TabText = (TextView) tab2TabView.findViewById(R.id.tabText); 
      tab2TabText.setText("Odometer"); 
      tab2TabText.setTypeface(arialTypeface); 
      tab2TabBadge = (TextView) tab2TabView.findViewById(R.id.tabBadge); 
      tab2TabBadge.setTypeface(arialTypeface); 
      tabLayout.getTabAt(1).setCustomView(tab2TabView); 

      // tab3 Tab 
      View tab3TabView = inflater.inflate(R.layout.tab, null); 
      ImageView tab3TabIcon = (ImageView) tab3TabView.findViewById(R.id.tabIcon); 
      tab3TabIcon.setImageResource(R.drawable.tab_third); 
      TextView tab3TabText = (TextView) tab3TabView.findViewById(R.id.tabText); 
      tab3TabText.setText("tab3"); 
      tab3TabText.setTypeface(arialTypeface); 
      tab3TabBadge = (TextView) tab3TabView.findViewById(R.id.tabBadge); 
      tab3TabBadge.setTypeface(arialTypeface); 
      tabLayout.getTabAt(2).setCustomView(tab3TabView); 

      // tab4 Tab 
      View tab4TabView = inflater.inflate(R.layout.tab, null); 
      ImageView tab4TabIcon = (ImageView) tab4TabView.findViewById(R.id.tabIcon); 
      tab4TabIcon.setImageResource(R.drawable.tab_fourth); 
      TextView tab4TabText = (TextView) tab4TabView.findViewById(R.id.tabText); 
      tab4TabText.setText("tab4"); 
      tab4TabText.setTypeface(arialTypeface); 
      tab4TabBadge = (TextView) tab4TabView.findViewById(R.id.tabBadge); 
      tab4TabBadge.setTypeface(arialTypeface); 
      tabLayout.getTabAt(3).setCustomView(tab4TabView); 

      // tab5 Tab 
      View tab5TabView = inflater.inflate(R.layout.tab, null); 
      ImageView tab5TabIcon = (ImageView) tab5TabView.findViewById(R.id.tabIcon); 
      tab5TabIcon.setImageResource(R.drawable.tab_fifth); 
      TextView tab5TabText = (TextView) tab5TabView.findViewById(R.id.tabText); 
      tab5TabText.setText("tab5"); 
      tab5TabText.setTypeface(arialTypeface); 
      tab5TabBadge = (TextView) tab5TabView.findViewById(R.id.tabBadge); 
      tab5TabBadge.setTypeface(arialTypeface); 
      tabLayout.getTabAt(4).setCustomView(tab5TabView); 

      // Tab listener 
      /* 
      tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { 
       @Override 
       public void onTabSelected(TabLayout.Tab tab) { 
        txtViewHeading.setText(tab.getText()); 
       } 

       @Override 
       public void onTabUnselected(TabLayout.Tab tab) { 

       } 

       @Override 
       public void onTabReselected(TabLayout.Tab tab) { 

       } 
      }); 
      */ 

     } 

     @Override 
     public boolean onOptionsItemSelected(MenuItem item) { 
      int id = item.getItemId(); 
      if (id == android.R.id.home) { 
       if(mViewPager.getCurrentItem()==0){ 
        onBackPressed(); 
       } 
       else{ 
        mViewPager.setCurrentItem(mViewPager.getCurrentItem()-1); 
       } 
      } 
      return super.onOptionsItemSelected(item); 
     } 

     @Override 
     protected void onPause() { 
      super.onPause(); 
      isVisible = false; 
     } 

     @Override 
     protected void onResume() { 
      super.onResume(); 
      isVisible = true; 
     } 

     @Override 
     protected void onStop() { 
      super.onStop(); 
      isVisible = false; 
     } 

     private boolean checkPlayServices() { 
      GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance(); 
      int resultCode = apiAvailability.isGooglePlayServicesAvailable(this); 
      if (resultCode != ConnectionResult.SUCCESS) { 
       if (apiAvailability.isUserResolvableError(resultCode)) { 
        apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST) 
          .show(); 
       } else { 
        ToastNotify("This device is not supported by Google Play Services."); 
        finish(); 
       } 
       return false; 
      } 
      return true; 
     } 

     public void ToastNotify(final String notificationMessage) { 
      runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        Toast.makeText(Main.this, notificationMessage, Toast.LENGTH_LONG).show(); 
       } 
      }); 
     } 

     private void registerWithNotificationHubs() 
     { 
      if (checkPlayServices()) { 
       // Start IntentService to register this application with GCM. 
       Intent intent = new Intent(this, RegistrationIntentService.class); 
       startService(intent); 
      } 
     } 

    } 

... и вот код для моего FragmentStatePagerAdapter

TabGroupAdapter

import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.FragmentPagerAdapter; 
import android.support.v4.app.FragmentStatePagerAdapter; 
import android.util.Log; 

import java.util.ArrayList; 


public class TabGroupAdapter extends FragmentStatePagerAdapter { 

    private static int fragmentSize = 5; 
    private static ArrayList<String> fragmentTitles = new ArrayList<String>() { 
     { 
      add("tab1"); 
      add("tab2"); 
      add("tab3"); 
      add("tab4"); 
      add("tab5"); 
     } 
    }; 

    public TabGroupAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     Log.d("tag","POSITION: " + position); 
     switch (position) { 
      case 0: 
      default: 
       return new Tab1Fragment(); 
      case 1: 
       return new Tab2Fragment(); 
      case 2: 
       return new Tab3Fragment(); 
      case 3: 
       return new Tab4Fragment(); 
      case 4: 
       return new Tab5Fragment(); 
     } 
    } 

    @Override 
    public int getCount() { 
     return fragmentSize; 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     return fragmentTitles.get(position); 
    } 


} 

Подводя итог, когда мои приложения нагрузок , первая вкладка пуста. Просто пустой экран. Это не мой Tab1Fragment, как и должно быть. Также, когда я щелкаю по моим вкладкам, позиция должна показывать слева направо 0,1,2,3,4, так как у меня есть 5 вкладок. Это не так. У меня есть оператор Log.d в моем методе getItem (position), в котором я регистрирую текущую позицию на консоли. Когда мое приложение загружается, оно показывает Position: 0, а затем Position: 1 all on load, что является странным, поскольку оно должно показывать только позицию 0, поскольку это вкладка по умолчанию (tab1). Затем, когда я нажимаю, вкладка 2 показывает позицию 2, вкладка 3 показывает позицию 3, вкладка 4 показывает позицию 4, а вкладка 5 вообще не регистрируется. Затем, работая от вкладки 5 до вкладки 1, позиции все не в порядке, и когда я добираюсь до вкладки 1, она не регистрируется. Это довольно странно. Кроме того, моя обратная стрелка в моем фрагменте, которая ДОЛЖНА появляться только в том случае, если я не на корневом фрагменте вкладки, вместо этого появляется все время.

Может ли кто-нибудь помочь мне разобраться, почему это происходит? Если для определения проблемы нужен какой-либо код, я рад опубликовать его, просто сообщите мне, что вам нужно посмотреть.

ответ

1

Попробуйте закомментировать весь код ниже:

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); 
     tabLayout.setupWithViewPager(mViewPager); 

в вашем OnCreate метод. Запустите еще раз и посмотрите, что произойдет.

Ваше заявление о переключении также расположено странным образом. Если у вас определенно будет только 5 случаев, тогда он должен перейти от случая 0-4, в конце которого будет использоваться случай по умолчанию, который печатает ошибку в журнале или генерирует исключение. Я не думаю, что это вызовет вашу проблему, но это хорошая практика.

Также не рекомендуется создавать экземпляры с использованием конструктора по умолчанию. Лучший способ заключается в использовании статического фабричного метода, то есть:

Tab1Fragment fragment = Tab1Fragment.create(); 
return fragment; 

С методом статического создания() в вашем фрагменте, который инициализирует объект. Это дает вам единую точку доступа к фрагменту и означает, что любая инициализация, которую вам нужно сделать (сейчас или в какой-то точке вниз по линии), может быть выполнена в одном месте, что делает вас менее подверженным ошибкам. Android также повторно создает фрагменты с использованием конструктора по умолчанию, поэтому любая инициализация, которую вы выполняете в перегруженном конструкторе, будет проигнорирована. Снова я не думаю, что это причина вашей проблемы, но это стоит иметь в виду.

Редактировать: Кроме того, когда вы говорите, что выбирают случайные фрагменты «Позиция покажет 0,3,2,0,4,1 просто случайные числа», вы имеете в виду, что это фрагменты, отображаемые на экране, или это те позиции, которые вы регистрируете из аргумента getItem (int position)?

+0

спасибо за ваше понимание. Я прокомментировал код ниже строк, упомянутых выше, но по-прежнему остается той же проблемой. Когда я имел в виду случайную позицию фрагментов, я вызываю Log I из метода getItem. У меня есть Log.d («Mytag», «Position:» + position); из метода getItem. Когда мое приложение загружается, оно записывает «Позиция: 0», а затем Позиция: 1 все при загрузке. Затем, когда я нажимаю вкладку 2, она говорит «Позиция: 2», вкладка 3 говорит, что позиция: 3, вкладка 4 говорит «Позиция»: 4 и вкладка 5 вообще не регистрируется. то, когда я вернусь с вкладки 5 на вкладку 1, последовательность изгоняет – Phil

+0

. Я построил фиктивный проект из кода, который вы разместили здесь, и все работает так, как должно. Адаптер FragmentStatePager загрузит текущую страницу и одну страницу с каждой стороны. Вот почему он регистрирует 0 и 1 одновременно. Когда вы перейдете на страницу 2, он загрузит страницу 3 и сохранит страницу 1 в памяти. Затем, когда вы доберетесь до страницы 4, он ничего не загрузит, поскольку 4 загрузится, когда вы прокрутите до 3, и нет ничего сверх этого. Таким образом, int, который вы даете в getItem(), НЕ является страницей, которая просматривается в данный момент, является той, которая загружается в память. Надеюсь, что это очистит вас. – Dan

+0

Спасибо, Дэн. Ваш комментарий помог мне понять, что моя проблема связана не с возвращенной позицией, а скорее в том фрагменте, который я загружаю. – Phil

0
viewPager = (ViewPager) findViewById(R.id.tabPager); 
adapter = new ViewPagerAdapter(getSupportFragmentManager()); 
     adapter.addFragment(new Fragment1(),"fragment 1"); 
     adapter.addFragment(new Fragment2(),"fragment 2"); 
     viewPager.setAdapter(adapter); 


     viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
      @Override 
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
       return position; 
       } 
      } 

      @Override 
      public void onPageSelected(int position) { 

      } 

      @Override 
      public void onPageScrollStateChanged(int state) { 

      } 
     }); 
tabLayout = (TabLayout) findViewById(R.id.tab_layout); 
     assert tabLayout != null; 
     tabLayout.setupWithViewPager(viewPager); 
     tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE); 
     tabLayout.setTabMode(TabLayout.MODE_FIXED); 
     tabLayout.setTabGravity(TabLayout.GRAVITY_FILL); 

Затем в адаптер

class ViewPagerAdapter extends FragmentPagerAdapter { 
private final List<Fragment> mFragmentList = new ArrayList<>(); 
private final List<String> mFragmentTitleList = new ArrayList<>(); 

     public ViewPagerAdapter(FragmentManager manager) { 
      super(manager); 
     } 

     @Override 
     public Fragment getItem(int position) { 
      return mFragmentList.get(position); 
     } 

     @Override 
     public int getCount() { 
      return mFragmentList.size(); 
     } 

     public void addFragment(Fragment fragment,String title) { 
      mFragmentList.add(fragment); 
mFragmentTitleList.add(title); 

     } 

     @Override 
     public CharSequence getPageTitle(int position) { 
      return mFragmentTitleList.get(position); 
     } 
    } 
+0

ваш метод getPageTitle возвращает фрагмент вместо CharSequence – Phil

Смежные вопросы