检索ViewPager子级布局的最佳位置是什么?

时间:2018-08-22 15:07:33

标签: android android-viewpager

早上好

我有一个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);
    }

谢谢大家。

1 个答案:

答案 0 :(得分:1)

请等到viewPagerCadastroPessoa.getChildCount()大于0。尚未在onResume中创建ViewPager中的页面(它们是异步创建的)。