I am trying to create a callback from MainActivity to a fragment.
In MainActivity I have 5 tabs. Each tab has a different UI through a fragment. The fragments are added via viewpager. My objective is to inform a fragment when an ad has been loaded in MainAcitivty. After the fragment gets the message it can then display the add itself by calling a method of MainActivity. At the moment I dont want to send any message back to MainActivity.
The code of the MainActivity is:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout drawer;
private ViewPager viewPager = null;
private RewardedVideoAd mRewardedVideoAd;
private NavigationView navigationView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
this.setTitle(R.string.app_title);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText(R.string.Tab1));
tabLayout.addTab(tabLayout.newTab().setText(R.string.Tab2));
tabLayout.addTab(tabLayout.newTab().setText(R.string.Tab3));
tabLayout.addTab(tabLayout.newTab().setText(R.string.Tab4));
tabLayout.addTab(tabLayout.newTab().setText( R.string.Tab5));
viewPager = (ViewPager) findViewById(R.id.pager);
final PagerAdapter adapter = new PagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
drawer = (DrawerLayout) findViewById(R.id.drawerLayout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
//handling navigation view item event
navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setItemIconTintList(null);
assert navigationView != null;
navigationView.setNavigationItemSelectedListener(this);
MobileAds.initialize(this, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
mRewardedVideoAd = MobileAds.getRewardedVideoAdInstance(this);
mRewardedVideoAd.setRewardedVideoAdListener(new RewardedVideoAdListener() {
#Override
public void onRewarded(RewardItem rewardItem) {
Toast.makeText(getApplication(),"Ad Rewarded.", Toast.LENGTH_SHORT).show();
loadRewardedVideoAd();
}
#Override
public void onRewardedVideoAdLoaded() {
Toast.makeText(getApplication(),"Ad loaded.", Toast.LENGTH_SHORT).show();
}
#Override
public void onRewardedVideoAdOpened() {
Toast.makeText(getApplication(),"Ad opened.", Toast.LENGTH_SHORT).show();
}
#Override
public void onRewardedVideoStarted() {
Toast.makeText(getApplication(),"Ad started", Toast.LENGTH_SHORT).show();
}
#Override
public void onRewardedVideoCompleted() {
Toast.makeText(getApplication(),"Ad completed.", Toast.LENGTH_SHORT).show();
}
#Override
public void onRewardedVideoAdClosed() {
Toast.makeText(getApplication(),"Ad closed.", Toast.LENGTH_SHORT).show();
}
#Override
public void onRewardedVideoAdLeftApplication() {
Toast.makeText(getApplication(),"Ad left application.", Toast.LENGTH_SHORT).show();
}
#Override
public void onRewardedVideoAdFailedToLoad(int i) {
Toast.makeText(getApplication(),"Ad failed to load.", Toast.LENGTH_SHORT).show();
}
});
loadRewardedVideoAd();
}
public void loadRewardedVideoAd() {
mRewardedVideoAd.loadAd("xxxxxxxxxxxxxxxxxxxxxxxxxxxx",new AdRequest.Builder().build());
}
public void showRewardedVideoAd() {
mRewardedVideoAd.show();
}
#Override
public void onResume() {
mRewardedVideoAd.resume(getParent());
super.onResume();
}
#Override
public void onPause() {
mRewardedVideoAd.pause(getParent());
super.onPause();
}
#Override
public void onDestroy() {
mRewardedVideoAd.destroy(getParent());
super.onDestroy();
}
public interface onToggledListener{
void onToggled();
}
private onToggledListener toggledListener;
public void setOnToggledlistener(onToggledListener listener){
toggledListener = listener;
}
}//end of MainActivity
The code of the fragment is:
public class Tab1 extends Fragment implements MainActivity.onToggledListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tab1, container, false);
buttonVideo = (Button) view.findViewById(R.id.videoAd);
fab =(FloatingActionButton) view.findViewById(R.id.fab);
return view;
}
//method implemented here
#Override
public void onToggled(){
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
buttonVideo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showad();// some method
}
});
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
add();//some method
}
});
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
}
}// end of fragment class
This is how I am trying to achieve my objective but I am not getting the result. Callback is not working
You not call method setOnToggledlistener which initialize your interface & then you can get call back from MainActivity to Fragment.
So, call setOnToggledlistener from activity .
In activity :
#Override
public void onRewardedVideoAdLoaded() {
toggledListener.onToggled(); //trigger callback when video loaded.
}
In fragment:
#Override
public void onResume() {
super.onResume();
getActivity().setOnToggledlistener(this); //register callback
}
Related
if the page is loaded, the button is active, if not, how can I do passive control?
What I want to do is, if the Viewpager Page is loaded, the button is active, if not, the Button is Passive. But I couldn't do any kind.
Is there anyone who can help?
If viewpager2 is installed Button enabled, if viewpager2 is not installed button false;
List<Movie> movieList = new ArrayList<>();
private ImageButton btn_down, btn_fav;
private Button btn_setter;
private DatabaseReference movies;
private IFirebaseLoadDone iFirebaseLoadDone;
public CartoonFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_cartoon, container, false);
movies = FirebaseDatabase.getInstance().getReference("Sports");
movies.keepSynced(true);
iFirebaseLoadDone = this;
loadMovie();
viewPager2 = view.findViewById(R.id.viewPager2_);
btn_down = view.findViewById(R.id.btn_down);
btn_setter = view.findViewById(R.id.btn_setter);
btn_fav = view.findViewById(R.id.btn_fav);
btn_down.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SaveToGallery();
}
});
btn_setter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
btn_fav.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
return view;
}
private void loadMovie() {
movies.addValueEventListener(this);
}
#Override
public void onFirebaseLoadSuccess(List<Movie> movieList) {
viewPagerAdapter = new ViewPagerAdapter(getContext(), movieList, viewPager2);
viewPager2.setAdapter(viewPagerAdapter);
}
#Override
public void onFirebasLoadFailed(String message) {
}
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot moviesSnapShot : dataSnapshot.getChildren())
movieList.add(moviesSnapShot.getValue(Movie.class));
Collections.reverse(movieList);
iFirebaseLoadDone.onFirebaseLoadSuccess(movieList);
viewPagerAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
iFirebaseLoadDone.onFirebasLoadFailed(databaseError.getMessage());
}
#Override
public void onDestroy() {
movies.removeEventListener(this);
super.onDestroy();
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onStop() {
movies.removeEventListener(this);
super.onStop();
}
}
Replace your methods with mine.
private void loadMovie() {
movies.addValueEventListener(this);
btn_down.setEnabled(false);
btn_fav.setEnabled(false);
btn_setter.setEnabled(false);
}
Firebase methods
#Override
public void onFirebaseLoadSuccess(List<Movie> movieList) {
viewPagerAdapter = new ViewPagerAdapter(getContext(), movieList, viewPager2);
viewPager2.setAdapter(viewPagerAdapter);
if(movieList!=null && !movieList.isEmpty()){
btn_down.setEnabled(true);
btn_fav.setEnabled(true);
btn_setter.setEnabled(true);
}
}
#Override
public void onFirebasLoadFailed(String message) {
btn_down.setEnabled(false);
btn_fav.setEnabled(false);
btn_setter.setEnabled(false);
}
There was an error loading
private void loadMovie() {
movies.addValueEventListener(this);
btn_down.setEnabled(false);
btn_fav.setEnabled(false);
btn_setter.setEnabled(false);
}
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageButton.setEnabled(boolean)' on a null object reference
at com.example.duvarlar.Fragment.CartoonFragment.loadMovie(CartoonFragment.java:386)
at com.example.duvarlar.Fragment.CartoonFragment.onCreateView(CartoonFragment.java:90)
I use mvp architecture.
I have the setupViews () method in which the buttons and ... are defined
how i can use setOnclickListener for Button in "presenter" and call it in SetupViews in "activity".
I do not want to use it directly in "view",I want to tell the presenter that the click is done and the presenter will do the job.
My interface:
public interface HomeContract {
interface View extends BaseView {
void showNews(List<News> newsList);
void showError(String error);
}
interface Presenter extends BasePresenter<View> {
void getNewsList();
} }
presenter class :
public class HomePresenter implements HomeContract.Presenter {
private HomeContract.View view;
private NewsDataSourse newsDataSourse;
CompositeDisposable compositeDisposable = new CompositeDisposable();
public HomePresenter(NewsDataSourse newsDataSourse) {
this.newsDataSourse = newsDataSourse;
}
#Override
public void getNewsList() {
newsDataSourse.getNews().subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SingleObserver<List<News>>() {
#Override
public void onSubscribe(Disposable d) {
compositeDisposable.add(d);
}
#Override
public void onSuccess(List<News> news) {
view.showNews(news);
}
#Override
public void onError(Throwable e) {
view.showError(e.toString());
}
});
}
#Override
public void attachView(HomeContract.View view) {
this.view = view;
getNewsList();
}
#Override
public void detachView() {
this.view = null;
if (compositeDisposable != null && compositeDisposable.size() > 0) {
compositeDisposable.clear();
}
}}
my view :
public class HomeActivity extends BaseActivity implements HomeContract.View {
private HomeContract.Presenter presenter;
private NewsRepository newsRepository = new NewsRepository();
private RecyclerView recyclerView;
private RecyclerAdapter recyclerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
presenter = new HomePresenter(newsRepository);
}
#Override
public void setupViews() {
Button btn_Ok = (Button) findViewById(R.id.btn_Ok);
recyclerView = (RecyclerView) findViewById(R.id.recycler);
recyclerView.setLayoutManager(new LinearLayoutManager(getViewContext(), LinearLayout.VERTICAL, false));
// btn_Ok.setOnClickListener();
}
#Override
public void showNews(List<News> newsList) {
setupViews();
recyclerView.setAdapter(new RecyclerAdapter(newsList, getViewContext()));
if (newsList.size() > 0) {
Toast.makeText(getViewContext(), "ok", Toast.LENGTH_SHORT).show();
Toast.makeText(getViewContext(), newsList.get(0).getName(), Toast.LENGTH_SHORT).show();
} else
Toast.makeText(getViewContext(), "not Ok", Toast.LENGTH_SHORT).show();
}
#Override
public void showError(String error) {
Toast.makeText(getViewContext(), error, Toast.LENGTH_SHORT).show();
}
#Override
public Context getViewContext() {
return getApplicationContext();
}
#Override
protected void onStart() {
super.onStart();
presenter.attachView(this);
}
#Override
protected void onStop() {
super.onStop();
presenter.detachView();
}
}
i want to use btn_Ok.setOnClickListener(presenter....); in view Or any better solution you need to do this
In your presenter interface type a method :
interface Presenter extends BasePresenter<View> {
void getNewsList();
void onButtonClicked();
}
And than in your HomePresenter class use it :
#Override
public void onButtonClicked(){
// continue logic here
}
If you don't override it the class will show an error
activity take more time to launch. Here is my code
Intent intent =new Intent(getActivity(), McallContactsActivity.class);
startActivity(intent);
I have disabled instant run, then tried. But it will take more time to lanch activity.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mcall_contacts_activity);
toolbar = (android.support.v7.widget.Toolbar)
findViewById(R.id.toolbar);
recycleListFriend = (RecyclerView)
findViewById(R.id.recycleListFriend);
swipeRefreshLayout = (SwipeRefreshLayout)
findViewById(R.id.swipeRefreshLayout);
phoneContact = new PhoneContact();
if(toolbar != null) {
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Users");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
}
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
checkContactPermission();
setupAdapter();
phoneContactList = getContacts(McallContactsActivity.this);
DatabaseReference ref =
FirebaseDatabase.getInstance().getReference().child("user");
ref.addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
dataSnapshot.getValue().keySet().iterator().next().toString();
String id = ((HashMap)
dataSnapshot.getValue()).keySet().iterator().next().toString();
collectPhoneNumbers((Map<String,Object>)
dataSnapshot.getValue());
}
#Override
public void onCancelled(DatabaseError databaseError) {
//handle databaseError
}
});
}
This is MCallContactsActivity's onCreate method. No onResume() method for this activity
class getContects extends AsyncTask<Void,Void,Void>{
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
#Override
protected Void doInBackground(Void voids) {
// Your Code Here
return null;
}
}
getContacts Taking too much to load thats why activity taking time to load so use Async task when activity created
I have an application with a RecyclerView and a DialogFragment, in the Dialog I add data to the database and display it in the RecyclerView. I tried to refresh the RecyclerView when I clicked in to add.
This is the Fragment
public class addAction extends DialogFragment implements View.OnClickListener {
EditText addTitle, addDesc;
Button add, clear,close;
Context context;
private DatabaseHelpher db;
String Title,Des;
public addAction() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.addaction, container, false);
addTitle = (EditText) rootView.findViewById(R.id.todotitle);
addDesc = (EditText) rootView.findViewById(R.id.tododescription);
add = (Button) rootView.findViewById(R.id.addbutton);
add.setOnClickListener(this);
close = (Button) rootView.findViewById(R.id.Close);
close.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dismiss();
}
});
clear = (Button) rootView.findViewById(R.id.clear);
clear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
addTitle.setText("");
addDesc.setText("");
}
});
return rootView;
}
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getDialog().setTitle("Add Action");
db = new DatabaseHelpher(getContext());
}
private void insert() {
Title = addTitle.getText().toString();
Des= addDesc.getText().toString();
db.insertIntoDB(Title, Des);
}
#Override
public void onClick(View v) {
if (addTitle.getText().toString().trim().equals("")) {
addTitle.setError(" Title is required!");
} else if (addDesc.getText().toString().trim().equals("")) {
addDesc.setError(" Postion is required!");
}
insert();
}
}
and this is the MainActivity
public class MainActivity extends AppCompatActivity {
List<ToDoModule> dbList;
RecyclerView mRecyclerView;
DatabaseHelpher helpher;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().hide();
helpher = new DatabaseHelpher(this);
dbList= new ArrayList<ToDoModule>();
dbList = helpher.getDataFromDB();
mRecyclerView = (RecyclerView)findViewById(R.id.AppRecyclerView);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new RecyclerAdapter(this,dbList);
mAdapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mAdapter);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setImageResource(R.drawable.ic_action_name);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentManager fm = getSupportFragmentManager();
addAction add = new addAction();
add.show(fm, "fragment_edit_name");
}
});}
#Override
protected void onResume() {
super.onResume();
dbList = helpher.getDataFromDB();
mAdapter.notifyDataSetChanged();
}
}
Call mAdapter.notifyDataSetChanged(); in your Activity's onResume() method.
First Solution
cast activity and call your method like this:
in your activity add this method
public void myMethod(){
runOnUiThread(new Runnable() {
#Override
public void run() {
//your code here
}
});
}
in your DialogFragment call the activity method after you cast it.
((YourActivity)getActivity()).myMethod();
Second Solution
add eventbus to your gradle
compile 'org.greenrobot:eventbus:3.0.0'
make a class that you want to pass to activity
public class MessageEvent {
public final String message;
public MessageEvent(String message) {
this.message = message;
}
}
listen to events in your activity
// This method will be called when a MessageEvent is posted (in the UI thread for Toast)
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();
}
register EventBus in your Activity
#Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
#Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
finally send in Event from Dialog to your Activity
EventBus.getDefault().post(new MessageEvent("Hello everyone!"));
don't forgot adding this to proguard file
-keepattributes *Annotation*
-keepclassmembers class ** {
#org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
I set up a NavigationDrawer but the NavigationDrawer button is not working.
NavigationDrawerFragment.java
public class NavigationDrawerFragment extends Fragment {
public static final String PREF_FILE_NAME="testpref";
public static final String USER_LEARNED_DRAWER="user_learned_drawer";
public ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private View containerView;
//for disapper drawer when screen rotate
private boolean mUserLearnedDrawer;
private boolean mFromSavedInstanceState;
public NavigationDrawerFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mUserLearnedDrawer=Boolean.valueOf(readFromPreference(getActivity(),USER_LEARNED_DRAWER,"false"));
if (savedInstanceState!=null){
mFromSavedInstanceState=true;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
}
public void setUp(int fragmentId,DrawerLayout drawerlayout) {
containerView=getActivity().findViewById(fragmentId);
mDrawerLayout=drawerlayout;
mDrawerToggle=new ActionBarDrawerToggle(getActivity(),drawerlayout,R.string.drawer_open,R.string.drawer_close){
#Override
public void onDrawerOpened(View drawerView) {
if (!mUserLearnedDrawer){
mUserLearnedDrawer=true;
saveToPreference(getActivity(),PREF_FILE_NAME,mUserLearnedDrawer+"");
}
getActivity().invalidateOptionsMenu();
super.onDrawerOpened(drawerView);
}
#Override
public void onDrawerClosed(View drawerView) {
getActivity().invalidateOptionsMenu();
super.onDrawerClosed(drawerView);
}
};
if (!mUserLearnedDrawer&& !mFromSavedInstanceState){
mDrawerLayout.openDrawer(containerView);
}
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerLayout.post(new Runnable() {
#Override
public void run() {
mDrawerToggle.syncState();
}
});
}
public static void saveToPreference(Context context,String preferenceName,String preferenceValue){
SharedPreferences sharedPreferences=context.getSharedPreferences(PREF_FILE_NAME,Context.MODE_PRIVATE);
SharedPreferences.Editor editor=sharedPreferences.edit();
editor.putString(preferenceName,preferenceValue);
editor.apply();
}
public static String readFromPreference(Context context, String preferenceName, String defaultValue){
SharedPreferences sharedPreferences=context.getSharedPreferences(PREF_FILE_NAME,Context.MODE_PRIVATE);
return sharedPreferences.getString(preferenceName,defaultValue);
}
}
MainActivity.java:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
NavigationDrawerFragment drawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.fragment_navigation);
drawerFragment.setUp(R.id.fragment_navigation,(DrawerLayout) findViewById(R.id.drawer_layout));
}
}
Add the below line of code at the last in your setUp method
mDrawerLayout.addDrawerListener(mDrawerToggle);