I wrote this code for login and for chatting;
login is an activity where is chatting is a fragment; here is my activity :
public class Consultant extends AppCompatActivity {
private FirebaseAuth auth;
private Button loginbtn;
private EditText email;
private EditText pass;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_consultant);
auth = FirebaseAuth.getInstance();
loginbtn = (Button) findViewById(R.id.loginbtn);
email = (EditText) findViewById(R.id.email);
pass = (EditText) findViewById(R.id.pass);
loginbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkEmailandpassword();
}
});
}
public boolean checkEmailandpassword() {
if (validate()) {
String CEmail = email.getText().toString().trim();
String CPass = pass.getText().toString().trim();
auth.signInWithEmailAndPassword(CEmail, CPass).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Toast.makeText(Consultant.this, "welcome", Toast.LENGTH_LONG).show();
Intent i = new Intent(Consultant.this,Consultant_Home_Chatting.class);
startActivity(i);
} else {
Toast.makeText(Consultant.this, "wrong ", Toast.LENGTH_LONG).show();
}
}
});
}
return false;
}
private boolean validate() {
boolean result = false;
String CPass = pass.getText().toString();
String CEmail = email.getText().toString();
if (CPass.isEmpty() || CEmail.isEmpty()) {
Toast.makeText(Consultant.this, "all fields required", Toast.LENGTH_LONG).show();
} else {
result = true;
}
return result;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_nav, menu);
return true;
}
}
and here my fragment :
public class Consultant_Home_Chatting extends Fragment {
private ViewPager mViewP ;
private FirebaseAuth mAuth ;
private TabLayout mTab ;
private TabsPagerAdapter mAdapter ;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_consultant__home__chatting, container, false);
}
public Consultant_Home_Chatting() {
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
mAuth = FirebaseAuth.getInstance();
mViewP = (ViewPager) getView().findViewById(R.id.main_tabs_pager);
mAdapter = new TabsPagerAdapter(getFragmentManager());
mViewP.setAdapter(mAdapter);
mTab = (TabLayout) getView().findViewById(R.id.main_tabs);
mTab.setupWithViewPager(mViewP);
}
I tried to add a new class holding these liens then make a constructor in my fragment and onCreatOptions method in my activity but it does not work!
I think the solution is to use the Bundle but I don't know how to use it or can I use it and what can I send inside put extra, can you please help?
if (savedInstanceState == null){
getFragmentManager().beginTransaction()
.add(android.R.id.content, new Consultant_Home_Chatting ()).commit();}
to use bundle simple create the instance of your fragment and then create bundle add all data you want and add this bundle to the fragment.
Here is example:
In activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TestFragment testFragment = new TestFragment();
Bundle bundle = new Bundle();
bundle.putString("name", "John");
bundle.putInt("age", 24);
testFragment.setArguments(bundle);
getSupportFragmentManager()
.beginTransaction()
.add(R.id.content, testFragment).commit();
}
In your fragment:
public class TestFragment extends Fragment {
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = getArguments();
if(bundle != null){
String name = bundle.getString("name");
int age =`enter code here` bundle.getInt("age");
}
}
}
Related
My MainAcivity hosts 2 fragments, login and register. I have a LiveData observer on LoginFragment that observes user login live data, after which if user is authenticated MainMenuActivity intent will start. On main menu there's logout button that would start MainActivity and load LoginFragment.
But here's the problem, the observer on LoginFragment triggered immediately after loading the fragment, which straight up start MainMenuActivity intent again.
My LoginFragment:
public class LoginFragment extends Fragment {
public static LoginFragment newInstance(){
return new LoginFragment();
}
private LoginViewModel mLoginViewModel;
private LiveData<UserModelJSONPlaceholder> mUserModelLiveData;
private static final String TAG = "FragLogin";
private Button mBtnLogin;
private EditText mTxtUsername, mTxtPass;
private TextView mTxtRegister;
private CheckBox mCheckBoxRemember;
private TextView mTxtInvalid;
private Callbacks mCallbacks = null;
private ProgressBar mProgressBar;
private UserApiInterface mAPIInterface;
private SharedPreferences mSharedPreferences;
private SharedPreferences.Editor mPreferencesEditor;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_login,container,false);
mBtnLogin = view.findViewById(R.id.btnLogin_login);
mTxtUsername = view.findViewById(R.id.txtUsername);
mTxtPass = view.findViewById(R.id.txtPass);
mCheckBoxRemember = view.findViewById(R.id.checkBoxRememberMe);
mTxtRegister = view.findViewById(R.id.txtRegister_login);
mProgressBar = view.findViewById(R.id.progressBar);
mTxtInvalid = view.findViewById(R.id.txtInvalid);
mProgressBar.setVisibility(View.GONE);
mTxtInvalid.setVisibility(View.GONE);
mAPIInterface = APIClient.getClient().create(UserApiInterface.class);
mSharedPreferences = getContext().getSharedPreferences("login",Context.MODE_PRIVATE);
mPreferencesEditor = mSharedPreferences.edit();
setListener();
return view;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLoginViewModel = new ViewModelProvider(this).get(LoginViewModel.class);
mUserModelLiveData = mLoginViewModel.getUserModelLiveData();
//observer would be triggered right after loading fragment after logout
mUserModelLiveData.observe(this, new Observer<UserModelJSONPlaceholder>() {
#Override
public void onChanged(UserModelJSONPlaceholder userModel) {
Log.d(TAG, "onChanged: Observer: "+userModel.getResponse());
mProgressBar.setVisibility(View.GONE);
String loginAuth = userModel.getResponse();
if(loginAuth.equals("OK")){
mPreferencesEditor.putString("name",userModel.getUserModel().getName());
mCallbacks.login_goMainMenu(userModel.getUserModel().getName());
}else{
mTxtInvalid.setVisibility(View.VISIBLE);
}
}
});
}
private void doLogin(){
mProgressBar.setVisibility(View.VISIBLE);
final String username = mTxtUsername.getText().toString().trim();
final String password = mTxtPass.getText().toString().trim();
mLoginViewModel.authLogin(username,password);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
mCallbacks = (Callbacks) context;
}
private void setListener(){
mBtnLogin.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
doLogin();
}
});
mTxtRegister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCallbacks.login_goRegister();
}
});
mCheckBoxRemember.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(buttonView.isChecked()){
mPreferencesEditor.putBoolean("rememberMe", true).apply();
Log.d(TAG, "onCheckedChanged: Checked");
}else{
mPreferencesEditor.putBoolean("rememberMe", false).apply();
Log.d(TAG, "onCheckedChanged: Unchecked");
}
}
});
}
public interface Callbacks{
void login_goMainMenu(String name);
void login_goRegister();
}
}
My MainMenuActivity:
public class MainMenuActivity extends AppCompatActivity {
private static final String ARG_NAME = "arg_name";
private Button mBtnEnterQ,mBtnCreateQ;
private TextView mTxtName;
private Toolbar mToolbar;
private SharedPreferences mSharedPreferences;
private SharedPreferences.Editor mEditor;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu);
mBtnEnterQ = findViewById(R.id.btnEnterQ);
mBtnCreateQ = findViewById(R.id.btnCreateQ);
mTxtName = findViewById(R.id.txtUsername);
mToolbar = findViewById(R.id.toolbar);
mSharedPreferences = getSharedPreferences("login",MODE_PRIVATE);
mEditor = mSharedPreferences.edit();
setSupportActionBar(mToolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar_menu,menu);
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.itemLogout:
doLogout();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void doLogout(){
mEditor.remove("rememberMe");
mEditor.apply();
Intent i = new Intent(this, MainActivity.class);
startActivity(i);
finish();
}
}
and here's my ViewModel and Repo for LoginFragment:
public class LoginViewModel extends ViewModel {
private static final String TAG = "LoginVM";
private UserRepository mUserRepository;
LiveData<UserModelJSONPlaceholder> mUserModelLiveData;
public LoginViewModel() {
mUserRepository = UserRepository.getInstance();
}
public void authLogin(String username, String password){
mUserRepository.authLogin(username,password);
}
public LiveData<UserModelJSONPlaceholder> getUserModelLiveData() {
return mUserRepository.getUserModelLiveData();
}
}
public class UserRepository {
private static UserRepository instance;
private static final String TAG = "RepoUser";
private UserApiInterface mUserApiInterface;
MutableLiveData<UserModelJSONPlaceholder> userModelLiveData;
public static UserRepository getInstance(){
if(instance==null){
instance=new UserRepository();
}
return instance;
}
private UserRepository(){
mUserApiInterface = APIClient.getClient().create(UserApiInterface.class);
Log.d(TAG, "UserRepository: repoInit");
}
public void authLogin(String username, String password){
Log.d(TAG, "authLogin: REQUEST INIT");
Log.d(TAG, "authLogin: SERVER: "+ CONFIG.SERVER);
mUserApiInterface.getUser(username,password).enqueue(new Callback<UserModelJSONPlaceholder>() {
#Override
public void onResponse(Call<UserModelJSONPlaceholder> call, Response<UserModelJSONPlaceholder> response) {
if(response.isSuccessful()){
UserModelJSONPlaceholder r = response.body();
userModelLiveData.postValue(response.body());
}else{
Log.d(TAG, "onResponse: FAILED. "+response.errorBody());
}
}
#Override
public void onFailure(Call<UserModelJSONPlaceholder> call, Throwable t) {
Log.d(TAG, "onFailure: "+t.getMessage());
}
});
}
public LiveData<UserModelJSONPlaceholder> getUserModelLiveData() {
if(userModelLiveData == null)
userModelLiveData = new MutableLiveData<>();
return userModelLiveData;
}
}
Your problems is you make UserRepository is Singleton instance and always keep value of userModelLiveData easy way to fix it change method to this
public LiveData<UserModelJSONPlaceholder> getUserModelLiveData() {
userModelLiveData = new MutableLiveData<>();
return userModelLiveData;
}
I am using the following components in my application
Activity
Fragment
WebView
Goal - I don't want to reload the webview on orientation change.
Issue - Currently I see the following error on orientation change "Webpage was not available. The webpage at https://fakeurls.org could not be loaded because net::ERR_CACHE_MISS"
Steps to Reproduce
Application was opened in device portrait mode.
Content of given URL was loaded in webview successfully
Device was turned to landscape mode
Webview shows error
Code - Android application makes a post request in a webview to url https://fakeurls.org. Below is the code for MyActivity and MyFragment class
MyFragment.java
public class MyFragment extends Fragment {
private ProgressBar mProgressBar;
private WebView mWebView;
private String mUrl = null;
private String mPostData = null;
public MyFragment() {
// Required empty public constructor
}
public static MyFragment newInstance(#android.support.annotation.NonNull String url, String postData) {
MyFragment MyFragment = new MyFragment();
Bundle bundle = new Bundle();
bundle.putString("URL", url);
bundle.putString("POSTDATA", postData);
MyFragment.setArguments(bundle);
return MyFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.my_fragment, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
instantiateWebView(view);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
mWebView.restoreState(savedInstanceState);
} else {
Bundle args = getArguments();
if (args == null) {
return;
}
mUrl = args.getString("URL");
mPostData = args.getString("POSTDATA");
mWebView.postUrl("https://fakeurls.org/", EncodingUtils.getBytes(mPostData, "BASE64"));
}
}
#Override
public void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
if (mWebView != null) {
mWebView.saveState(outState);
}
}
#Override
public void onDestroy() {
super.onDestroy();
mWebView.destroy();
}
private void instantiateWebView(View view) {
mWebView = (WebView) view.findViewById(R.id.webView);
mWebView.setWebViewClient(new WebViewClient());
mWebView.getSettings().setJavaScriptEnabled(true);
}
}
MyActivity.java
public class MyActivity extends AppCompatActivity {
private MyFragment mMyFragment;
#NonNull
public static Intent createIntent(Context context, String url, String postData) {
return new Intent(context, MyActivity.class).putExtra("URL", url)
.putExtra("POSTDATA", postData);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_link_viewer);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
mMyFragment = (MyFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_frame);
if (mMyFragment == null) {
final String url = getIntent().getStringExtra("URL");
final String postData = getIntent().getStringExtra("POSTDATA");
mMyFragment = MyFragment.newInstance(url, postData);
getSupportFragmentManager()
.beginTransaction()
.add(R.id.fragment_frame, mMyFragment)
.commitNow();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void finish() {
mMyFragment.cancelTasks();
super.finish();
}
}
Please let me know how to resolve the issue and not reload the webview but retain display on orientation change. Any help is appreciated.
The current fragment is redirecting to the started activity after i change the data in Firebase. I need to change the visiblity of the button in ManageTeam fragment.The flow of the application is
LoginActivity -> MainActivity -> ManageTeam
LoginActivity.java
public class LoginActivity extends AppCompatActivity {
private MaterialEditText etEmail,etPassword;
private Button btnLogin,btnSignUp;
private FirebaseAuth firebaseAuth;
LinearLayout linearLayout;
private String role;
private User student;
private ProgressDialog progressDialog;
DatabaseReference databaseReference;
ValueEventListener valueEventListener;
private static String user_field = "user";
private static String pwd_field = "pwd";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
Paper.init(this);
progressDialog = new ProgressDialog(LoginActivity.this);
progressDialog.setTitle("MTCHY");
progressDialog.setMessage("Login");
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
etEmail = (MaterialEditText) findViewById(R.id.etLoginEmail);
etPassword = (MaterialEditText) findViewById(R.id.etLoginPassword);
btnLogin = (Button) findViewById(R.id.btnLogin);
btnSignUp = (Button) findViewById(R.id.btnLoginSignUp);
firebaseAuth = FirebaseAuth.getInstance();
linearLayout = (LinearLayout) findViewById(R.id.loginLayout);
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final String email = etEmail.getText().toString().trim();
String password = etPassword.getText().toString().trim();
if (TextUtils.isEmpty(email) || TextUtils.isEmpty(password))
{
AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this);
builder.setMessage("Please enter an email and password").setTitle("Warning").setPositiveButton("OK",null);
AlertDialog dialog = builder.create();
dialog.show();
}
else
{
progressDialog.show();
firebaseAuth.signInWithEmailAndPassword(email,password).addOnCompleteListener(LoginActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful())
{
databaseReference = FirebaseDatabase.getInstance().getReference();
valueEventListener = databaseReference.child("Users").orderByChild("email").equalTo(email).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Paper.book().write(user_field,etEmail.getText().toString());
Paper.book().write(pwd_field,etPassword.getText().toString());
for(DataSnapshot userDataSnapshot : dataSnapshot.getChildren())
{
student = userDataSnapshot.getValue(User.class);
role = student.getUserRole();
if (role.equals("Player"))
{
progressDialog.dismiss();
startActivity(new Intent(LoginActivity.this,MainActivity.class));
finish();
}
if (role.equals("Captain"))
{
progressDialog.dismiss();
startActivity(new Intent(LoginActivity.this,MainActivity.class));
finish();
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this);
builder.setMessage(databaseError.getMessage()).setTitle("Database Error").setPositiveButton("OK",null);
AlertDialog dialog = builder.create();
dialog.show();
}
});
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
progressDialog.dismiss();
AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this);
builder.setMessage(e.getMessage()).setTitle("Login Error").setPositiveButton("OK",null);
AlertDialog dialog = builder.create();
dialog.show();
}
});
}
}
});
btnSignUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(LoginActivity.this,SignupActivity.class);
startActivity(intent);
}
});
String papsuser = Paper.book().read(user_field);
String pappwd = Paper.book().read(pwd_field);
System.out.println(papsuser);
System.out.println(pappwd);
if (papsuser != null && pappwd != null)
{
if(!TextUtils.isEmpty(papsuser) && !TextUtils.isEmpty(pappwd))
{
autoLogin(papsuser,pappwd);
}
}
}
#Override
protected void onDestroy() {
super.onDestroy();
databaseReference.removeEventListener(valueEventListener);
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private BottomNavigationView navigation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AHBottomNavigation bottomNavigation = (AHBottomNavigation) findViewById(R.id.bottom_navigation);
AHBottomNavigationItem item1 = new AHBottomNavigationItem("Home", R.drawable.common_google_signin_btn_icon_dark_focused, R.color.colorBottomNavigationDisable);
AHBottomNavigationItem item2 = new AHBottomNavigationItem("Manage Team", R.drawable.common_google_signin_btn_icon_dark_focused, R.color.colorAccent);
AHBottomNavigationItem item3 = new AHBottomNavigationItem("Setting", R.drawable.common_google_signin_btn_icon_dark_focused,R.color.colorPrimary);
bottomNavigation.addItem(item1);
bottomNavigation.addItem(item2);
bottomNavigation.addItem(item3);
bottomNavigation.setDefaultBackgroundColor(getResources().getColor(R.color.colorBackgroud));
bottomNavigation.setCurrentItem(0);
bottomNavigation.setAccentColor(getResources().getColor(R.color.colorPrimary));
bottomNavigation.setInactiveColor(getResources().getColor(R.color.colorAccent));
bottomNavigation.setForceTint(true);
bottomNavigation.setTitleState(AHBottomNavigation.TitleState.ALWAYS_SHOW);
AFragment aFragment = new AFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.content, aFragment).commit();
bottomNavigation.setOnTabSelectedListener(new AHBottomNavigation.OnTabSelectedListener() {
#Override
public boolean onTabSelected(int position, boolean wasSelected) {
if(position == 0) {
AFragment aFragment = new AFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.content, aFragment).commit();
return true;
}
else if(position == 1 )
{
ManageTeam manageTeam = new ManageTeam();
getSupportFragmentManager().beginTransaction().replace(R.id.content,manageTeam).commit();
return true;
}
return false;
}
});
}
}
ManageTeam.java
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
btn = (Button) getView().findViewById(R.id.btnJohn);
users = FirebaseDatabase.getInstance().getReference("Users");
value = users.orderByChild("email").equalTo("viginesjohn2#gmail.com").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot clubDataSnapshot : dataSnapshot.getChildren())
{
User user = clubDataSnapshot.getValue(User.class);
if (user.getHasTeam() == true)
{
btn.setVisibility(View.GONE);
}
if (user.getHasTeam() == false)
{
btn.setVisibility(View.VISIBLE);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
users.removeEventListener(value);
}
Firebase
My firebase data
UI
Android UI
Based on the UI , the activity will start on Home. After i change the the hasTeam field to true or false in Firebase. The Fragment updates the UI but it will redirect back to Home Activity.
I have two tabs which contain two different fragments. Tab1 for fragment1 and tab2 for fragment2. From fragment1, I want to pass a string value in fragment2's TextView by clicking on a Button.
However, the UI of fragment2 is not being updated. Sample code has given below.
In MainActivity :
private Fragment1 fragment1;
private Fragment2 fragment2;
private TabLayout tabLayout;
protected void onCreate(Bundle savedInstanceState) {
fragment1 = new Fragment1();
fragment2 = new Fragment2();
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_holder, fragment1).commit();
tabLayout = (TabLayout) findViewById(R.id.tab);
tabLayout.getTabAt(0).select();
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
if (tab.getPosition() == 0) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_holder, fragment1).commit();
} else if (tab.getPosition() == 1) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_holder, fragment2).commit();
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
}
}
public void showFragment2(final String data) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_holder, fragment2).commit();
tabLayout.getTabAt(1).select();
if (!TextUtils.isEmpty(data)) {
if (fragment2 != null) {
fragment2.setData(data);
}
}
}
In Fragment1 :
private Button button;
protected void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
button = (Button) view.findViewById(R.id.btn);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((MainActivity)getActivity()).showFragment2("Updated Data");
}
});
}
In Fragment2 :
private TextView tv;
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
tv = (TextView) view.findViewById(R.id.tv);
}
public void setData(String data){
tv.setText(data);
}
Important Update:
If I update the UI in Handler. Then it works. But, seems it's not the proper way.
handler.postDelayed(new Runnable() {
#Override
public void run() {
tabLayout.getTabAt(1).select();
if(!TextUtils.isEmpty(data)){
if(fragment2 != null){
fragment2.setData(data);
}
}
}
},500);
Use .executePendingTransactions() which would work synchronously along with .commit() which works Asynchronously.
After a FragmentTransaction is committed with
FragmentTransaction.commit(), it is scheduled to be executed
asynchronously on the process's main thread. If you want to
immediately executing any such pending operations, you can call this
function (only from the main thread) to do so. Note that all callbacks
and other related behavior will be done from within this call, so be
careful about where this is called from.
DO:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_holder, fragment2).commit();
getSupportFragmentManager().executePendingTransactions();
tabLayout.getTabAt(1).select();
if(!TextUtils.isEmpty(data)){
if(fragment2 != null){
fragment2.setData(data);
}
}
Hey hi i am not sure but try this:
public void showFragment2(final String data) {
if (!TextUtils.isEmpty(data)) {
if (fragment2 != null) {
// fragment2.setData(data);
Bundle arguments = new Bundle();
arguments.putString( "string_key" , data);
fragment2.setArguments(arguments);
}
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_holder, fragment2).commit();
tabLayout.getTabAt(1).select();
}
and In Fragment2 :
private TextView tv;
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Bundle arguments = getArguments();
String desired_string = arguments.getString("string_key");
tv = (TextView) view.findViewById(R.id.tv);
setData(desired_string);
}
public void setData(String data){
tv.setText(data);
}
set the data in activity method from fragment 1 and while loading fragment get the data from activity and set it in fragment 2
mainActivity(){
string fragment1Data;
public void setFragment1Data(string data){
fragment1Data = data;
}
public string getFragment1Data(){
return fragment1Data
}
}
in Fragment 1
private Button button;
protected void onViewCreated(View view, #Nullable Bundle savedInstanceState)
{
button = (Button) view.findViewById(R.id.btn);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((MainActivity)getActivity()).showFragment2("Updated Data");
((MainActivity)getActivity()).setFragment1Data("data");
}
});
}
in Fragment 2
private TextView tv;
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
tv = (TextView) view.findViewById(R.id.tv);
tv.setText(((MainActivity)getActivity()).getFragment1Data());
}
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 { *; }