I'm trying to use Retrofit and OkHttp to make request to a server. I have the next class "AutomaticRequest.java" which has a request to get videos from a server.
public class AutomaticRequest {
public void getVideos(final AutomaticCallback callback){
MediaproApiInterface service = ApiClient.getClient();
Call<List<AutomaticVideo>> call = service.getAllVideos();
call.enqueue(new Callback<List<AutomaticVideo>>() {
#Override
public void onResponse(Call<List<AutomaticVideo>> call, Response<List<AutomaticVideo>> response) {
List<AutomaticVideo> automaticVideoList = response.body();
callback.onSuccessGettingVideos(automaticVideoList);
}
#Override
public void onFailure(Call<List<AutomaticVideo>> call, Throwable t) {
callback.onError();
}
});
}
}
I've created the next class "AutomaticCallback.java" to retrieve data.
public interface AutomaticCallback {
void onSuccessGettingVideos(List<AutomaticVideo> automaticVideoList);
void onError();
}
I'm calling the request from a fragment like the next way:
public class AllVideosFragment extends Fragment {
...
AutomaticCallback callback;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_allvideos, container, false);
new AutomaticRequest().getVideos(callback);
return view;
}
...
}
How I can wait until the callback has data to update the UI?? Thank you.
Just implement the AutomaticCallback interface on your fragment like:
public class AllVideosFragment extends Fragment implements AutomaticCallback {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_allvideos, container, false);
new AutomaticRequest().getVideos(this);
return view;
}
#Override
void onSuccessGettingVideos(List<AutomaticVideo> automaticVideoList){
// use your data here
}
#Override
void onError(){
// handle the error
}
}
Related
I have created a callback via interface with two methods. The callback is between a NonActivity class and a Fragment. The problem is that only one interface method invisible is being called. And the other interface method visible is not called. I have copied the code of interface and both classes. MY OBJECTIVE IS THAT BOTH CALLBACK METHODS INVISIBLE() AND VISIBLE() SHOULD BE CALLED AT DIFFERENT TIMES WHEN TRIGGERED. I am somewhat confused about not getting the particular functionality.
public interface MyCustomListener {
void invisible();
void visible();
}
The NonActivity class code is as follows:
public class Operations {
private Context context;
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private MyCustomListener listener;
public void setMyCustomListener(MyCustomListener listener) {
this.listener = listener;
}
public Operations(Context context, RecyclerView recyclerView) {
this.context = context;
this.recyclerView = recyclerView;
}
public void getView(int number) {
Perform pa = new Perform(context);
Long count = pa.count(number);
if (count > 0) {
ArrayList arrayList = pa.getAllList(number);
adapter = new AdapterMovie(context, arrayList, recyclerView, number);
recyclerView.setAdapter(adapter);
if (listener != null)
listener.invisible();
}
else if (count < 1) {
recyclerView.setAdapter(null);
if (listener != null)
listener.visible();
}
}
}
The Fragment class code is as follows:
public class Frag extends Fragment {
private int fragmentNumber = 0;
private Operations fo;
private RecyclerView recyclerView;
private TextView message;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag, container, false);
fo = new Operations(getActivity(), recyclerView);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
fo.setMyCustomListener(new MyCustomListener() {
#Override
public void invisible() {
Toast.makeText(getActivity(), "invisible", Toast.LENGTH_SHORT).show();
}
#Override
public void visible() {
Toast.makeText(getActivity(), "visible", Toast.LENGTH_SHORT).show();
}
});
}
}
If you want get callback in fragment, you should implements your fragment from MyCustomListener. then you pass fragment to constructor of Operations.
fragment such as below:
public class Frag extends Fragment implements MysCustomListener{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag, container, false);
fo = new Operations(this, recyclerView);
return view;
}
#override
void invisible(){
}
#override
void visible(){
}
}
When I start Android app I login to Realm Object Server and download (sync) data from Realm Server Object.
OK.
Now I got to Fragment that show list of persons.
Here code:
public class PersonsFragment extends Fragment {
private ListView notEmptytsListView;
private Realm realm;
private RealmResults<Person> personsRealmResults;
private PersonsAdapter personsAdapter; // RealmBaseAdapter<Organization>
private RealmChangeListener realmChangeListener;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.persons_fragment, container, false);
init(rootView);
return rootView;
}
private void init(View view) {
realm = Realm.getDefaultInstance();
notEmptytsListView = (ListView) view.findViewById(R.id.notEmptytsListView);
personsRealmResults = realm.where(Person.class).findAllSorted(Person.NAME);
personsAdapter = new PersonsAdapter(personsRealmResults);
notEmptytsListView.setAdapter(personsAdapter);
// NOT CALL WHEN DATA ON REALM OBJECT SERVER WAS CHANGED
realmChangeListener = new RealmChangeListener() {
#Override
public void onChange(Object object) {
personsAdapter.notifyDataSetChanged();
}
};
personsRealmResults.addChangeListener(realmChangeListener);
}
#Override
public void onDestroy() {
super.onDestroy();
realm.removeChangeListener(realmChangeListener);
realm.close();
}
}
If I stay on Fragment and data changed on Realm Object Server (remote Realm) the local data is not sync. Not call method onChanged().
How I can fix this?
public class MyFragment extends Fragment {
RealmResults<Person> personsRealmResults; // <--
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.persons_fragment, container, false);
notEmptytsListView = (ListView) view.findViewById(R.id.notEmptytsListView);
realm = Realm.getDefaultInstance();
personsRealmResults = realm.where(Person.class).findAllSorted(Person.NAME);
personsAdapter = new PersonsAdapter(personsRealmResults);
notEmptytsListView.setAdapter(personsAdapter);
realmChangeListener = new RealmChangeListener() {
#Override
public void onChange(Object object) {
// call when data on Realm Object Server was changed
}
};
personsRealmResults.addChangeListener(realmChangeListener);
return rootView;
}
#Override
public void onDestroyView() {
super.onDestroyView();
realm.removeChangeListener(realmChangeListener);
realm.close();
}
}
Although it'd probably be easier if PersonsAdapter was a RealmBaseAdapter. (see docs)
In my MainActivity class I have view pager with 3 tab fragmentHome class, fragmentHot class and FragmentCategoryclass
Here is fragmentCategory class:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view;
view = inflater.inflate(R.layout.fragmentcategory, container, false);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.category_fragment, new TabCategoryFragment());
transaction.commit();
return view;
}
In TabCategoryFragment class, I have grid category news and when click item grid I called:
FragmentTransaction transaction = getFragmentManager().beginTransaction();
Bundle bundle = new Bundle();
bundle.putString("category", arrDataZone.get(position).getZone_name());
bundle.putString("zoneid", arrDataZone.get(position).getZone_id());
ListCategoryFragment myFrag = new ListCategoryFragment();
myFrag.setArguments(bundle);
transaction.replace(R.id.category_fragment, myFrag,"listFramgnet");
transaction.addToBackStack("grid_category");
transaction.commit();
Now I want call method in ListCategoryFragment from MainActivity or call method in ListCategoryFragment from FragmentCategory.
Because I try call method in FragmentCategory from MainACtivity with:
linearPlayer.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int number=viewPager.getCurrentItem();
Fragment fragment= adapter.getItem(number);
if (number==0) {
((FragmentHome)fragment).playAudioSerVice();
} else if(number==1) {
((FragmentHot)fragment).playAudioSerVice();
} else if( number==2) {
((FragmentNew)fragment).playAudioSerVice();
} else if( number==3) {
((FragmentCategory)fragment).playAudioSerVice();
}
}
});
and it ran. Please give me your idea or code to do it.
You can use Eventbus postSticky to resolve it,you can see the api, eventbus
I wrote a demo to simulate your case.Here is the code.
MainActivity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main22);
getSupportFragmentManager().beginTransaction().replace(R.id.contaner,new MainActivityFragment()).commit();
EventBus.getDefault().register(this);
}
#Subscribe
public void changeFragment(ChangeFragmentEvent event) {
// get event from MainActivityFragment immediately--->EventBus.getDefault().post(new ChangeFragmentEvent());
getSupportFragmentManager().beginTransaction().replace(R.id.contaner,PlusOneFragment.newInstance()).commit();
}
#Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}
MainActivityFragment:
public class MainActivityFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main22, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
View button = view.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
EventBus.getDefault().post(new ChangeFragmentEvent());//notify MainActivity change fragment
EventBus.getDefault().postSticky(new MEvent());//send a msg to PlusOneFragment,when it shown
}
});
}
}
PlusOneFragment:
public class PlusOneFragment extends Fragment {
public PlusOneFragment() {
}
public static PlusOneFragment newInstance() {
PlusOneFragment fragment = new PlusOneFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_plus_one, container, false);
return view;
}
#Subscribe(sticky = true)
public void getMEvent(MEvent event){
// get event from MainActivityFragment when PlusOneFragment show --->EventBus.getDefault().postSticky(new MEvent());
Toast.makeText(getActivity(),"Hello,there",Toast.LENGTH_SHORT).show();
}
#Override
public void onDetach() {
super.onDetach();
EventBus.getDefault().unregister(this);
}
}
i have first fragment and second fragment i want from the second fragment to make some thing in the frist fragent using callback with interface but i find this error
java.lang.NullPointerException: Attempt to invoke interface method
interface:
public interface MyProfileCallback
{
void callbackCall(Context con);
}
first fragment:
public class firstfragment extends Fragment implements MyProfileCallback
{
public firstfragment()
{
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View rootview = inflater.inflate(R.layout.fisrt, container, false);
/
...
/
}
#Override
public void callbackCall(Context con)
{
Toast.makeText(getActivity(), "calllllllllll baaaaaaaaaaaaack",
Toast.LENGTH_SHORT).show();
}
}
second fragment:
public class secondfragment extends Fragment
{
MyProfileCallback mcallback;
public secondfragment()
{
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View rootview = inflater.inflate(R.layout.second, container, false);
mcallback.callbackCall(getContext());
return rootview;
}
Add this in your second Fragment,
mcallback=refernce of your First Frgament;
And Call this method:
mcallback.callbackCall(getContext());
I am working on one application which contains dynamic pages,so that i have taken viewpager.I created one fragment dynamically it creates,in that fragment i am calling webservice after success response i am refreshing data ,but fragment is not updating.I am using StatePagerAdapter.
code:
public class CustomPagerAdapter extends FragmentStatePagerAdapter
{
private ArrayList<InstituteVO> _instituteList;
private ArrayList<CourseItemVO> _courses;
public CustomPagerAdapter(FragmentManager fm, ArrayList<InstituteVO> instituteList)
{
super(fm);
_instituteList = instituteList;
_courses=new ArrayList<>();
}
#Override
public Fragment getItem(int position)
{
PagerItemFragment fragment = new PagerItemFragment();
fragment.setItemInfo(_instituteList.get(position), this);
// fragment.setCourses(_courses);
return fragment;
}
#Override
public int getCount()
{
return _instituteList.size();
}
public int getItemPosition(Object item) {
return super.getItemPosition(item);
}
public class PagerItemFragment extends BaseFragment implements OnWebServiceResponseListener,View.OnClickListener
{
private RecyclerView _courseView;
private CourseCustomRecycleAdapter _adapter;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.institute_pager_layout, null);
return view;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
setData();
}
private void setData()
{
callDataService(_item);
}
private void callDataService(String slug)
{
WebServiceController.getInstance().serviceGET(this, new InstituteProcessor(), url, AppConstants.METHOD_GET, slug);
}
#Override
public void onWebServiceResponseSuccess(OnWebServiceDataProcessListener response)
{
if (response != null && response instanceof InstituteProcessor)
{
_adapter.setData(((InstituteProcessor)response).getInstituteVO().getCourses());
}
}
}