【问题标题】:Communicating Between Activity and ViewPagerAdapter Through ListenerActivity 和 ViewPagerAdapter 通过 Listener 进行通信
【发布时间】:2017-03-14 14:33:31
【问题描述】:

我有一个包含 2 个选项卡的 TabLayout 的 Activity,每个选项卡都有自己的片段。我的活动中有一个 Fab 按钮。当我在选项卡 1 中并单击它时,我想以某种方式向 ViewPagerAdapter 的 getItem() 方法指示“嘿,该按钮已被单击。将选项卡 1 中的现有 Fragment 替换为另一个 Fragment。”

我不知道该怎么做。我在想也许可以添加一个监听器,但又不知道如何实现它。任何帮助将不胜感激。

主要活动:

public class MainActivity extends AppCompatActivity {
private ViewPager viewPager;
private ArrayList<Fragment> fragments = new ArrayList<>();
private ArrayList<String> titles = new ArrayList<>();

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

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    CollapsingToolbarLayout collapsingToolbarLayout = (CollapsingToolbarLayout)findViewById(R.id.collapsing_toolbar);
    setSupportActionBar(toolbar);

    fragments.addAll(Arrays.asList(new Tasks(),new Calendar(),new Contacts()));
    titles.addAll(Arrays.asList(getResources().getString(R.string.fragment_task_title),
            getResources().getString(R.string.fragment_cal_title),getResources().getString(R.string.fragment_contacts_title)));
    TabLayout tabLayout = (TabLayout)findViewById(R.id.tabs);

    final FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab);
    fab.hide();

    viewPager = (ViewPager)findViewById(R.id.container);
    ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(),fragments,titles);
    viewPager.setAdapter(viewPagerAdapter);
    viewPager.setCurrentItem(1);
    viewPager.addOnPageChangeListener(new 
    tabLayout.setupWithViewPager(viewPager);

    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            fabAction();
        }
    });

    if (savedInstanceState==null){
        if (getSupportActionBar()!=null){
            getSupportActionBar().setDisplayShowTitleEnabled(true);
        }
    }
}
public void fabAction(){
    int current = viewPager.getCurrentItem();

    switch (current){
        case 0:{
            //TELL THE VIEWPAGER ADAPTER THAT BUTTON IS CLICKED AND SWITCH FRAGMENTS
            break;
        }
        case 1:{
            Toast.makeText(this, "IN TAB 2", Toast.LENGTH_LONG).show();
            break;
        }
    }
}}

ViewPagerAdapter:

public class ViewPagerAdapter extends FragmentPagerAdapter{
ArrayList<Fragment> fragments;
ArrayList<String> titles;
private Fragment mFragmentAtPos0;
private FragmentManager fragManager;

//NEED TO IMPLEMENT THE LISTENER IN THIS CLASS TELLING ME THAT THE BUTTON WAS CLICKED IN MAIN ACTIVITY
public ViewPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragments, ArrayList<String>titles) {
    super(fm);
    this.fragments = fragments;
    this.titles = titles;
    fragManager = fm;

}

@Override
public Fragment getItem(int position) {
    //Somehow get Indication Here that the button was clicked

    if (position == 0)
    {
        if(mFragmentAtPos0==null){
            mFragmentAtPos0 = new Tasks();
            fragManager.beginTransaction().replace(R.id.container,mFragmentAtPos0).commit();
            notifyDataSetChanged();
        }
        return mFragmentAtPos0;
    }else{
        return fragments.get(position);

    }

}

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

@Override
public CharSequence getPageTitle(int position) {

    return titles.get(position);
}

@Override
public int getItemPosition(Object object)
{
    if (object instanceof Tasks && mFragmentAtPos0 instanceof AddContact)
        return POSITION_NONE;
    return POSITION_UNCHANGED;
}}

这就是我正在尝试发生的事情,并从@wize 对类似问题的回答中得到了我的想法。答案中缺少的部分太多,我无法掌握整个解决方案:Replace Fragment Inside ViewPager

【问题讨论】:

    标签: android android-fragments android-viewpager


    【解决方案1】:

    这确实有点棘手。也许您应该考虑将您的工厂移动到您想要更改的片段,并处理片段内部的更改。如果 fab 必须在 Activity 中,您可以从 Pager Adapter 本身实现添加/删除片段。

    适配器应该如下所示:

        public class CodebaseFragmentPagerAdapter extends FragmentStatePagerAdapter {
    
        private List<Fragment> mFragmentList = new ArrayList<Fragment>();
    
        public CodebaseFragmentPagerAdapter(FragmentManager manager) {
            super(manager);
        }
    
        @Override
        public Fragment getItem(int position) {
            return mFragmentList.get(position);
        }
    
        public void removeItem(int position){
            mFragmentList.remove(position == 0 ? 0 : position - 1);
            this.notifyDataSetChanged();
        }
    
        public void clearAllItems(){
            mFragmentList.clear();
            this.notifyDataSetChanged();
        }
    
        public void updateItem(int position, Fragment fragment){
            mFragmentList.set(position, fragment);
            notifyDataSetChanged();
        }
    
        @Override
        public int getItemPosition(Object object) {
            if (mFragmentList.contains(object)) return mFragmentList.indexOf(object);
            else return POSITION_NONE;
        }
    
        @Override
        public int getCount() {
            return mFragmentList.size();
        }
    
        public void addFrag(Fragment fragment) {
            mFragmentList.add(fragment);
            notifyDataSetChanged();
        } 
    }
    

    注意:以上适配器不支持选项卡布局,因此请随意调整以适应您的需求

    用法:

     mAdapter = new CodebaseFragmentPagerAdapter(getSupportFragmentManager());
     mViewPager.setAdapter(mAdapter);
    
     mAdapter.addFrag(FragmentExample.newInstance());
    

    【讨论】:

    • 这是个好建议。我将 fab 保留在 MainActivity 中的原因是因为我有一个 collapsingtoolbar,如果它位于片段的右下角,它会隐藏 fab。我将尝试使用该布局。
    • 如果你想在滚动时隐藏 fab,你可以创建一个布局类似于这个 not 100%当然,但我认为它应该工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-26
    • 2021-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多