如何从ViewPage2中的EditText获取文本



我有一个ViewPager2,有两个页面。一个是收到电子邮件,另一个是得到电话号码。为了获得值,我在适配器中添加了两个get方法,但我不确定这是正确和最安全的方法

public class PhoneEmailFragment extends Fragment {
private View view;
private final String[] tabs = {"Phone", "Email"};
private User user;
private int pageSelected = 0;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_phone_email, container, false);
return view;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
assert getArguments() != null;
user = getArguments().getParcelable("user");
}
@Override
public void onStart() {
super.onStart();
viewpagerSetup();
}
private void viewpagerSetup() {
TabLayout tabLayout = view.findViewById(R.id.register_phone_email_tab);
ViewPager2 viewPager2 = view.findViewById(R.id.register_viewpager);
SwipeAdapter adapter = new SwipeAdapter(this);
viewPager2.setAdapter(adapter);
viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
pageSelected = position;
}
});
new TabLayoutMediator(
tabLayout,
viewPager2,
(tab, position) -> tab.setText(tabs[position])
).attach();
}
public void saveValue() {
switch (pageSelected) {
case 0:
user.setUserPhoneNumber();
break;
case 1:
user.setUserEmail();
break;
}
}
static class SwipeAdapter extends FragmentStateAdapter {
public SwipeAdapter(@NonNull Fragment fragment) {
super(fragment);
}
@NonNull
@Override
public Fragment createFragment(int position) {
Fragment fragment = new Fragment();
switch (position) {
case 0:
fragment = new PhoneFieldFragment();
break;
case 1:
fragment = new EmailFieldFragment();
break;
}
return fragment;
}
@Override
public int getItemCount() {
return 2;
}
}

}

我想在saveValue((方法上使用EditText中的值。

应该在片段类中获取EditText的值。为了从片段中获得EditText的值,应该从SwipeAdapter类中删除2个get方法,并将findViewById()调用放在片段类中,如下所示:

public class EmailFieldFragment extends Fragment {
private MainViewModel mainViewModel;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainViewModel = new ViewModelProvider(requireActivity()).get(MainViewModel.class);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_email_field, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Do this after an action, example - after a button click
EditText emailEt = view.findViewById(R.id.email_et);
emailEt.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (count < 1) { // i.e - no user input
mainViewModel.setEmail("");
} else {
mainViewModel.setEmail(s.toString());
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
}

我更新了SwipeAdapter以接受如下片段列表:

public class SwipeAdapter extends FragmentStateAdapter {
private final List<Fragment> fragments;
public SwipeAdapter(@NonNull FragmentActivity fragmentActivity, 
List<Fragment> fragmentList) {
super(fragmentActivity);
this.fragments = fragmentList;
}
@NonNull
@Override
public Fragment createFragment(int position) {
return fragments.get(position);
}
@Override
public int getItemCount() {
return fragments.size();
}
}

我创建了一个viewModel类,它保存LiveData对象中EditText字段的值。然后从活动(或片段(中观察这些场。请参阅以下代码:

public class MainViewModel extends ViewModel {
private final MutableLiveData<String> _email = new 
MutableLiveData<>();
public LiveData<String> email = _email;
private final MutableLiveData<String> _phone = new 
MutableLiveData<>();
public LiveData<String> phone = _phone;
public void setEmail(String email) {
_email.setValue(email);
}
public void setPhone(String phone) {
_phone.setValue(phone);
}
}

我还添加了生命周期依赖项。

最后,这是下面活动的代码:

public class MainActivity extends AppCompatActivity {
private String email = "";
private String phone = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainViewModel mainViewModel = new ViewModelProvider(this).get(MainViewModel.class);
PhoneFieldFragment phoneFieldFragment = new PhoneFieldFragment();
EmailFieldFragment emailFieldFragment = new EmailFieldFragment();
List<Fragment> fragmentList = new ArrayList<>();
fragmentList.add(phoneFieldFragment);
fragmentList.add(emailFieldFragment);
SwipeAdapter swipeAdapter = new SwipeAdapter(this, fragmentList);
ViewPager2 viewPager = findViewById(R.id.viewPager);
viewPager.setAdapter(swipeAdapter);
Button button = findViewById(R.id.get_field_button);
mainViewModel.email.observe(MainActivity.this, new Observer<String>() {
@Override
public void onChanged(String s) {
email = s;
}
});
mainViewModel.phone.observe(MainActivity.this, new Observer<String>() {
@Override
public void onChanged(String s) {
phone = s;
}
});
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "Email: " + email + "nPhone: " + phone, Toast.LENGTH_SHORT).show();
// Both email and phone number are available here, so you can call your setValue() method here
}
});
}
}

这是github 上整个代码库的链接

编辑

我使用了一个共享的viewModel类,它连接了viewPager片段和它们的宿主活动(或者另一个片段,视情况而定(。当用户使用TextWatcher输入时,我从EditText中获取文本。

在Fragment代码中进行此操作。它将是干净的,便于维护。

更好的方法是使用SharedViewModel。

它对我有效。

findViewById<AppCompatEditText>(R.id.notesET).apply {
tag = position
doAfterTextChanged {
if (tag == position) {
model.answer = "#$it"
}
}
}

最新更新