Marta Tenés
Marta Tenés

Reputation: 2100

Viewpager + webservice

EDIT: I have found the solution.

I was casting the interface in a wrong way.

It should be:

( (IOnResultObtainedListener) adapter.getItem(i)).onResultObtained(response.getCompetition());

Instead of:

((IOnResultObtainedListener) CompetitionActivity.this).onResultObtained(response.getCompetition());
        }

I have a ViewPager which contains three Fragments with a list. I need to populate them with the data I obtain when my webservice response but I don't know how to notify each Fragment. I have tried to implement an Interface between Activity and Fragments but I obtain this error:

java.lang.ClassCastException:
    com.cuatroochenta.mybets.home.mygames.newGame.CompetitionActivity
    cannot be cast to
    com.cuatroochenta.mybets.home.mygames.newGame.IOnResultObtainedListener

Here is my Activity code:

public class CompetitionActivity extends MyBetsActionBarActivity implements ICompetitionsResponseListener {

private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
Handler handler;

IOnResultObtainedListener onResultObtainedListener;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);

    toolbar = (Toolbar) findViewById(R.id.toolbar);
    toolbar.setTitle("Competiciones");
    setSupportActionBar(toolbar);

    handler = new Handler();

    getSupportActionBar().setDisplayHomeAsUpEnabled(false);

    viewPager = (ViewPager) findViewById(R.id.viewpager);
    setupViewPager(viewPager);
    tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(viewPager);
}

@Override
public void onResume() {
    super.onResume();
    doRequestCompetitions();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate(R.menu.search_menu, menu);

    MenuItem searchItem = menu.findItem(R.id.action_search);

    SearchManager searchManager = (SearchManager) this.getSystemService(Context.SEARCH_SERVICE);

    SearchView searchView = null;
    if (searchItem != null) {
        searchView = (SearchView) searchItem.getActionView();
    }
    if (searchView != null) {
        searchView.setSearchableInfo(searchManager.getSearchableInfo(this.getComponentName()));
    }
    return super.onCreateOptionsMenu(menu);
}

private void setupViewPager(ViewPager viewPager) {
    ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
    adapter.addFragment(new PopularsFragment(), "Populares");
    adapter.addFragment(new CategoriesFragment(), "Categorías");
    adapter.addFragment(new NewsFragment(), "Nuevos");
    viewPager.setOffscreenPageLimit(3);
    viewPager.setAdapter(adapter);
}

class ViewPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public ViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

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

    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }
}

private void doRequestCompetitions(){
    if (NetworkUtils.isNetworkAvailable(this)) {
        CompetitionsService competitionsService = new CompetitionsService();
        competitionsService.setServiceUrl(url);
        competitionsService.getCompetitionsAsync(new CompetitionsRequest(user, password), this);
    } else {
        InfoAlertManager.showInfoDialog(this, "Conexión requerida", "Aceptar");
    }
}

@Override
public void onCompetitionsResponse(final CompetitionsResponse response) {
    if (response.getCompetition() != null) {
        Log.d("onCompetitionsResponse", response.getCompetition().toString());

        // HERE IS WHEN I RECEIVE THE RESPONSE AND I SHOULD NOTIFY IT TO THE FRAGMENTS
        handler.post(new Runnable() {
            @Override
            public void run() {
                ((IOnResultObtainedListener) CompetitionActivity.this).onResultObtained(response.getCompetition());
            }
        });
    }
}

@Override
public void onError(ServiceResponseError serviceResponseError) {
    Log.d("ServiceResponseError", serviceResponseError.getMessage());
}

public void setOnResultObtainedListener(IOnResultObtainedListener onResultObtainedListener){
    this.onResultObtainedListener = onResultObtainedListener;
}

}

And here one of my Fragments code:

public class PopularsFragment extends Fragment implements IOnResultObtainedListener {

RecyclerView rvPopular;
CompetitionAdapter mCompetitionAdapter;

public PopularsFragment() {
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.d("PopularsFragment", "onCreate");
}

@Override
public void onStart() {
    super.onStart();
    Log.d("MyBets", "PopularsFragment Visible");
}

@Override
public void onResume() {
    super.onResume();
    ((CompetitionActivity)getActivity()).setOnResultObtainedListener(this);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_competitions, container, false);
    rvPopular =  (RecyclerView) rootView.findViewById(R.id.rvCompetitions);
    rvPopular.setLayoutManager(new LinearLayoutManager(getActivity()));
    rvPopular.setHasFixedSize(true);
    return rootView;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
}

@Override
public void onResultObtained(Competition competition) {
    mCompetitionAdapter = new CompetitionAdapter(getActivity(), competition, 0);
    rvPopular.setAdapter(mCompetitionAdapter);
}

}

Any ideas? I have searched for similar questions but I haven't found anything that works... Hope you help me. Thanks a lot!

Upvotes: 1

Views: 394

Answers (2)

hata
hata

Reputation: 12483

An Interface which your CompetitionActivity implements is not IOnResultObtainedListener but ICompetitionsResponseListener. Those which implement IOnResultObtainedListener are Fragments under the ViewPager.

The instances of the Fragments are held as mFragmentList by ViewPagerAdapter. So change its modifier to default (or public) that you can access it from outside of the class.

final List<Fragment> mFragmentList = new ArrayList<>();

Also you have to keep the ViewPagerAdapter instance to a field variable instead of a local one to access it out side of the setupViewPager method:

private ViewPagerAdapter pagerAdapter;

private void setupViewPager(ViewPager viewPager) {
    pagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
    ...
}

Then, instead of this line:

((IOnResultObtainedListener) CompetitionActivity.this).onResultObtained(response.getCompetition());

place this code:

for (Fragment fragment : pagerAdapter.mFragmentList) {
    ((IOnResultObtainedListener) fragment).onResultObtained(response.getCompetition());
}

to call each of the Fragments' listeners.

Upvotes: 1

Alexander
Alexander

Reputation: 48272

Probably, easiest would be to use an open source event bus such as Otto

Upvotes: 0

Related Questions