早上好
我有一个Fragment,其布局具有ViewPager,我提供了一个自定义PageAdapter来显示两个子布局。一种布局是填充个人数据,另一种布局是填充用户的地址数据。在我的片段上,我想同时获取两个布局数据,并用属性Endereco(地址)填充对象Pessoa(Person)。到目前为止,我的ViewPager可以正常工作,并且两种布局都可以显示,但是当我尝试使用:
在onCreateView或onResume片段的方法上获取两种布局上的字段时, viewpager.getChildAt(0).findViewById(R.id.txt1)
我有一个NullPointerException,但是如果我添加一个OnPageChangeListener可以工作,我不确定这是否是最好的方法。有没有最佳的地方来检索对viewpager孩子的布局的引用?
Ps。我不想使用其他两个片段来显示每个布局。
PageAdapter
public class ViewPagerCadastroPessoaAdapter extends PagerAdapter {
private Context context;
private int[] views = {R.layout.layout_cadastro_dados_pessoais,R.layout.layout_cadastro_endereco };
public ViewPagerCadastroPessoaAdapter(Context context) {
this.context = context;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater inflater = LayoutInflater.from(this.context);
View layout = inflater.inflate(views[position], container, false);
container.addView(layout, position);
return layout;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
@Override
public int getCount() {
return 2;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0:
return "Dados Pessoais";
case 1:
return "Endereço";
}
return super.getPageTitle(position);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}}
ViewPager的持有人片段
public class CadastroPessoaFragment extends Fragment {
private ViewPager viewPagerCadastroPessoa;
private TabLayout tabLayoutCadastroPessoa;
public CadastroPessoaFragment() {
}
public static CadastroPessoaFragment newInstance() {
return new CadastroPessoaFragment();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_cadastro_pessoa, container, false);
tabLayoutCadastroPessoa = root.findViewById(R.id.tabLayoutCadastroPessoa);
viewPagerCadastroPessoa = root.findViewById(R.id.viewPagerCadastroPessoa);
viewPagerCadastroPessoa.setOffscreenPageLimit(2);
viewPagerCadastroPessoa.setAdapter(new ViewPagerCadastroPessoaAdapter(getContext()));
tabLayoutCadastroPessoa.setupWithViewPager(viewPagerCadastroPessoa);
int cor = ContextCompat.getColor(getContext(), android.R.color.white);
tabLayoutCadastroPessoa.setTabTextColors(cor, cor);
//get a null pointer
viewPagerCadastroPessoa.getChildAt(0).findViewById(R.id.txt1);
viewPagerCadastroPessoa.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
//works fine
viewPagerCadastroPessoa.getChildAt(0).findViewById(R.id.txt1);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
return root;
}
@Override
public void onResume() {
super.onResume();
//get a null pointer
viewPagerCadastroPessoa.getChildAt(0).findViewById(R.id.txt1);
}
}
谢谢大家
更新 根据
安东·马利舍夫(Anton Malyshev)回答 Viewpager创建其页面的方式有点“不同步”,因此我使用以下方法来解决我的问题:
在我的自定义适配器上,我使用单一方法onViewPagerReady()定义了一个接口,因为Viewpager始终只有两页,在InstantiateItem内部,我检查位置为1(位置从0开始)(如果position == 1)我将片段viewpager的持有人实现的onViewPagerReady方法称为调用方法,因此在此方法中,我检索了viewpager子级的布局
public class ViewPagerCadastroPessoaAdapter extends PagerAdapter {
public interface ViewPagerObserver{
void onViewPagerReady();
}
private Context context;
private int[] views = {R.layout.layout_cadastro_dados_pessoais,R.layout.layout_cadastro_endereco };
private ViewPagerObserver observer;
public ViewPagerCadastroPessoaAdapter(Context context, ViewPagerObserver observer) {
this.context = context;
this.observer = observer;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater inflater = LayoutInflater.from(this.context);
View layout = inflater.inflate(views[position], container, false);
container.addView(layout, position);
if(position == 1){
observer.onViewPagerReady();
}
return layout;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
@Override
public int getCount() {
return 2;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0:
return "Dados Pessoais";
case 1:
return "Endereço";
}
return super.getPageTitle(position);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}
片段查看器的支架
@Override
public void onViewPagerReady() {
View rootCadastroDadosPessoais = viewPagerCadastroPessoa.getChildAt(0);
View rootCadastroEnderecos =viewPagerCadastroPessoa.getChildAt(1);
}
谢谢大家。
答案 0 :(得分:1)
请等到viewPagerCadastroPessoa.getChildCount()
大于0。尚未在onResume
中创建ViewPager中的页面(它们是异步创建的)。