Ошибка ViewPager при попытке получить getText из editText во фрагменте - PullRequest
0 голосов
/ 29 октября 2018

У меня есть ViewPager с такими же фрагментами. В каждом фрагменте у меня есть только один editText, и я хочу получить строку из редактирования. Когда я пытаюсь сделать это, у меня есть нулевой указатель.

У меня есть этот код:

Адаптер для ViewPager:

public class SamplePagerAdapter extends FragmentPagerAdapter {
private int size;

public SamplePagerAdapter(FragmentManager fm, int size) {
    super(fm);
    this.size = size;
}

@Override
public Fragment getItem(int position) {
    FragmentForNamePlayers fragment = new FragmentForNamePlayers();
    hashCode();
    return fragment;
}

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

Фрагмент:

public class FragmentForNamePlayers extends Fragment implements FragmentLifecycle  {
private EditText editText;
View rootView;

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
     rootView = inflater.inflate(R.layout.players_name_for_fragment,
            container, false);
    editText=rootView.findViewById(R.id.edForNamePlayers);
    return rootView;
}
@Override
public void onPause() {
    super.onPause();
}
@Override
public void onChangeEditTExt() {
    String s=editText.getText().toString();
}}

Активность: Когда я перемещаюсь к следующему фрагменту в viewPager, мой интерфейс пытается получить текст из editText во фрагменте, и в этот момент мое приложение получает ошибку

public class PopupPlayersName extends AppCompatActivity   {
private  int widht;
private  int height;
private SharedPreferences preferences;
private ViewPager viewPager;
private TextView back;
private TextView cancel;
private TextView next;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.name_players_popup);

    viewPager=findViewById(R.id.ViewPager);
    back=findViewById(R.id.buttonBack);
    cancel=findViewById(R.id.buttonCancel);
    next=findViewById(R.id.buttonNext);

    DisplayMetrics metrics=new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);
    widht=metrics.widthPixels;
    height=metrics.heightPixels;
    getWindow().setLayout((int)(widht*.8),(int)(height*.4));
    preferences=getSharedPreferences(MainActivity.REQUEST_CODE_SHARED,MODE_PRIVATE);
    final int count=preferences.getInt(MainActivity.REQUEST_CODE_SHARED,-1);

    final SamplePagerAdapter adapter=new SamplePagerAdapter(getSupportFragmentManager(),count);
     ViewPager.OnPageChangeListener pageChangeListener = new ViewPager.OnPageChangeListener() {
        int currentPosition = 0;
        @Override
        public void onPageSelected(int newPosition) {
            FragmentLifecycle fragmentToHide = (FragmentLifecycle)adapter.getItem(currentPosition);
            fragmentToHide.onChangeEditTExt();
            currentPosition = newPosition;
        }
        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) { }

        public void onPageScrollStateChanged(int arg0) { }
    };
    viewPager.setAdapter(adapter);
    viewPager.setCurrentItem(0);
    viewPager.addOnPageChangeListener(pageChangeListener);

    back.setTextColor(getResources().getColor(R.color.grey));
    back.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int temp=viewPager.getCurrentItem();
            if(temp==1){
                back.setTextColor(getResources().getColor(R.color.grey));
            }
            if(temp!=0){
                viewPager.setCurrentItem(temp-1,true);
            }
                next.setTextColor(getResources().getColor(R.color.colorAccent));
        }
    });
    cancel.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            finish();
        }
    });
    next.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int temp=viewPager.getCurrentItem();
            if(temp==count-2){
                next.setTextColor(getResources().getColor(R.color.grey));
            }
                back.setTextColor(getResources().getColor(R.color.colorAccent));
            if(temp!=count-1){
                viewPager.setCurrentItem(temp+1,true);
            }
        }
    });
}}

И мой интерфейс:

public interface FragmentLifecycle {
   void onChangeEditTExt();
}

Исключение:

10-29 08:55:42.544 4937-4937/com.glasha.nuar E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.glasha.nuar, PID: 4937
    java.lang.NullPointerException
        at com.glasha.nuar.fragments.FragmentForNamePlayers.onChangeEditTExt(FragmentForNamePlayers.java:36)
        at com.glasha.nuar.activities.PopupPlayersName$1.onPageSelected(PopupPlayersName.java:60)
        at android.support.v4.view.ViewPager.dispatchOnPageSelected(ViewPager.java:1941)
        at android.support.v4.view.ViewPager.scrollToItem(ViewPager.java:680)
        at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:664)
        at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:625)
        at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:617)
        at com.glasha.nuar.activities.PopupPlayersName$4.onClick(PopupPlayersName.java:100)

1 Ответ

0 голосов
/ 30 октября 2018

В вашем SamplePagerAdapter классе.

@Override
public Fragment getItem(int position) {
    FragmentForNamePlayers fragment = new FragmentForNamePlayers();
    hashCode();
    return fragment;
}

Каждый раз, когда пользователи переключаются между страницами на ViewPager, создается новый экземпляр FragmentForNamePlayers.

@Override
public void onPageSelected(int newPosition) {
    FragmentLifecycle fragmentToHide = (FragmentLifecycle)adapter.getItem(currentPosition);
    fragmentToHide.onChangeEditTExt();
    currentPosition = newPosition;
}

Из вашего кода, когда пользователи переходят на следующую страницу, вы вызываете onChangeEditTExt на предыдущей странице, но в это время будет создан новый экземпляр предыдущей страницы, но onCreateView всегда будет вызываться после onChangeEditTExt. Вот почему ваше приложение всегда падает.

Решение: Повторно использовать фрагменты, созданные в данной позиции, в противном случае создать новый.

SamplePagerAdapter

public class SamplePagerAdapter extends FragmentPagerAdapter {
    // A map store fragments which have been created at given position.
    private Map<Integer, Fragment> fragments = new HashMap<>();
    private int size;

    public SamplePagerAdapter(FragmentManager fm, int size) {
        super(fm);
        this.size = size;
    }

    @Override
    public Fragment getItem(int position) {
        // Check fragment in fragments map first.
        FragmentForNamePlayers fragment = (FragmentForNamePlayers) fragments.get(position);
        if (fragment == null) {
            // Create a new fragment instance if it's not found in the fragments map.
            fragment = new FragmentForNamePlayers();
            fragments.put(position, fragment);
        }
        return fragment;
    }

    @Override
    public int getCount() {
        return size;
    }
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...