Fragment with Webview utilize harware back button to go to previous webpage - android

This appears to have been asked a lot on stack overflow, but with answers which appear to no longer be implementable with changes to the SDK (I may be wrong!).
I have been trying to allow a fragment inside my MainActivity to use the hardware button to go back to the previous page inside a webview in the fragment.
I have tried using return super.onKeyDown(keyCode, event);
as part of a function but onKeyDown does not come up as valid in my project.
This is my BlogFragment containing the webview:
public class BlogFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
WebView wv;
private OnFragmentInteractionListener mListener;
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment blog.
*/
// TODO: Rename and change types and number of parameters
public static BlogFragment newInstance(String param1, String param2) {
BlogFragment fragment = new BlogFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public static boolean canGoBack(){
return wv.canGoBack();
}
public static void goBack(){
wv.goBack();
}
public BlogFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_blog, null);
wv = (WebView) view.findViewById(R.id.webview);
WebSettings settings = wv.getSettings();
wv.setWebChromeClient(new WebChromeClient() {
});
final String mimeType = "text/html";
final String encoding = "UTF-8";
String html = getHTML();
settings.setJavaScriptEnabled(true);
wv.loadDataWithBaseURL("http://www.bbc.co.uk", html, mimeType, encoding, "");
return view;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public String getHTML() {
String html = "<iframe width=\"100%\" height=\"100%\" src=\"http://blog.mrgyro.co.uk\" frameborder=\"0\" allowfullscreen></iframe>";
return html;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
}
Activity:
public class MainActivity extends ActionBarActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks, BlogFragment.OnFragmentInteractionListener, HomeFragment.OnFragmentInteractionListener {
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in {#link #restoreActionBar()}.
*/
private CharSequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
#Override
public void onBackPressed() {
if(BlogFragment.canGoBack()){
BlogFragment.goBack();
}else{
super.onBackPressed();
}
}
#Override
public void onNavigationDrawerItemSelected(int position) {
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
switch (position) {
case 0:
HomeFragment homeFragment = new HomeFragment();
transaction.replace(R.id.container, homeFragment);
break;
case 1:
BlogFragment blogFragment = new BlogFragment();
transaction.replace(R.id.container, blogFragment);
break;
}
transaction.commit();
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
case 4:
mTitle = getString(R.string.title_section4);
break;
}
}
public void restoreActionBar() {
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.main, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
//if (id == R.id.action_settings) {
// return true;
// }
return super.onOptionsItemSelected(item);
}
#Override
public void onFragmentInteraction(Uri uri) {
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = null;
rootView = inflater.inflate(R.layout.fragment_home, container, false);
switch(getArguments().getInt(ARG_SECTION_NUMBER)) {
case 1:
rootView = inflater.inflate(R.layout.fragment_home, container, false);
break;
case 2:
rootView = inflater.inflate(R.layout.fragment_blog, container, false);
break;
case 3:
// rootView = inflater.inflate(R.layout.fragment_test, container, false);
break;
case 4:
//rootView = inflater.inflate(R.layout.fragment_info, container, false);
break;
default:
Log.e("TAG", "Unrecognized section: " + getArguments().getInt(ARG_SECTION_NUMBER));
}
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MainActivity) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
}
}
Thanks in advance.
EDIT: I have updated the blog fragment with my most recent attempt, however when trying to static wv.canGoBack() and wv.goBack() both return the error "Non-Static field 'wv' cannot be referenced from a static context

Try overriding onBackPressed() in your Activity and make it poke the WebView.
BTW - you could post the piece of Activity containing the onKeyDown method as well.
EDIT: Instead of making your methods static and accessing them the way you do now (BlogFragment.canGoBack()), first instantiate the fragment:
BlogFragment blogFragment = new BlogFragment();
blogFragment.canGoBack();
and then just remove the static from your methods. :)
OPs implementation (with thanks to Klotor)
At the head of MainActivity implement:
BlogFragment blogFragment = new BlogFragment();
Then implement:
public void onBackPressed() {
blogFragment.canGoBack();
if(blogFragment.canGoBack()){
blogFragment.goBack();
}else{
super.onBackPressed();
}
}
The fragment is instantiated outside of the onBackPressed in order to prevent crashing when using a method to navigate between fragments.
In this case you need to instantiate a newinstance of the fragment, rather than a whole new fragment.

** In your Fragment Class Inside OnCreateView put below code**
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.your_layout, container, false);
mWebView = (WebView) view.findViewById(R.id.webView);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(new MyWebViewClient());
mWebView.loadUrl(expertsUrl);
return view;
}
private class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
**In MainActivity class put below code **
#Override
public void onBackPressed() {
if (WebViewFragment.mWebView!=null) {
if (WebViewFragment.mWebView.canGoBack()) {
WebViewFragment.mWebView.goBack();
}
else {
super.onBackPressed();
}
}
}
Replace WebViewFragment -> with your Fragment
mWebView -> with your webview
Hope this will help you!!!!

Related

When back pressed go to main Activity from fragment (Navigation view)

Tried many ways, but none works perfectly. I want to get main activity from the fragments set up in a navigation view.
I tried
#Override
public void onBackPressed() {
startActivity(new Intent(this, MainActivity.class));
}
but it won't function properly. I want it like when I'm in a fragmented activity it returns back to main and while clicking back again it quits (I already did this), help me out with when back pressed get back to main activity
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final int PERMISSION_REQUEST_CODE = 1000 ;
private static final String TAG = "MainActivity";
private AdView mAdView;
ImageView imageView;
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
List<Item> items;
CustomAdapter adapter;
private long backpressedtime;
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case PERMISSION_REQUEST_CODE:
{
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();
else
Toast.makeText(this,"Permission Denied", Toast.LENGTH_SHORT).show();
}
break;
}
}
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mToggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String str="Click on Wallpaper to set Wallpaper";
Toast.makeText(getApplicationContext(), str, Toast.LENGTH_LONG).show();
imageView=(ImageView)findViewById(R.id.imageView);
mDrawerLayout=(DrawerLayout) findViewById(R.id.dl);
mToggle=new ActionBarDrawerToggle(this,mDrawerLayout,R.string.open,R.string.close);
mDrawerLayout.addDrawerListener(mToggle);
mToggle.syncState();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
NavigationView navigationView = (NavigationView) findViewById(R.id.Navigation_v);
setupDrawerContent(navigationView);
ActionBar actionBar = getSupportActionBar();
recyclerView =(RecyclerView)findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
imageView=(ImageView)findViewById(R.id.imageView);
initItem();
//start service and play music
startService(new Intent(MainActivity.this, SoundService.class));
}
public void toast(View v) {
Toast.makeText(MainActivity.this, "Wallpaper Set", Toast.LENGTH_LONG).show();
}
private void initItem() {
items = new ArrayList<>();
items.add(new Item(0,"Wide","https://images8.alphacoders.com/532/thumb-1920-532407.jpg"));
items.add(new Item(1, "Wide","https://images5.alphacoders.com/394/thumb-1920-394511.jpg"));
items.add(new Item(1,"Wide","https://images5.alphacoders.com/408/thumb-1920-408539.jpg"));
adapter = new CustomAdapter(this,items);
recyclerView.setAdapter(adapter);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
protected void onDestroy() {
//stop service and stop music
stopService(new Intent(MainActivity.this, SoundService.class));
super.onDestroy();
}
public void selectItemDrawer(MenuItem menuItem){
Fragment myFragment = null;
Class fragmentClass;
switch (menuItem.getItemId()) {
case R.id.walkthrough:
fragmentClass = Walkthrough.class;
break;
case R.id.info:
fragmentClass = About.class;
break;
default:
fragmentClass = Walkthrough.class;
}
try {
myFragment = (Fragment) fragmentClass.newInstance();
}
catch (Exception e) {
e.printStackTrace();
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.flcontent,myFragment).commit();
setTitle(menuItem.getTitle());
mDrawerLayout.closeDrawers();
}
private void setupDrawerContent(NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
selectItemDrawer(item);
return true;
}
});
}
#Override
public void onBackPressed() {
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("Are you sure you want to exit?");
builder.setCancelable(true);
builder.setNegativeButton("No Stay ;-)", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
builder.setPositiveButton("Yes :'-(", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
Walkthrough.java
public class Walkthrough extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public Walkthrough() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment Walkthrough.
*/
// TODO: Rename and change types and number of parameters
public static Walkthrough newInstance(String param1, String param2) {
Walkthrough fragment = new Walkthrough();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_walkthrough, container, false);
WebView webView = (WebView)v.findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true); //enable javascript
webView.setWebViewClient(new WebViewClient()); //important to open url in your app
webView.loadUrl("http://ign.com/wikis/the-last-of-us/Prologue");
return v;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
If you want to go back to the MainActivity onBack click of WalkthroughFragment then while commit your fragment add it to BackStack using this method:
FragmentTransaction addToBackStack (String name)
This method will do the below operation:
Will Add this transaction to the back stack. This means that the transaction will be remembered after it is committed, and will reverse its operation when later popped off the stack.
You can use it like that
FragmentTransaction ftx = getFragmentManager().beginTransaction();
ftx.replace(R.id.my_container_frame, fragment);
ftx.addToBackStack(null);
ftx.commit();
Alternatively you include all the function invocations on a single line
getSupportFragmentManager().beginTransaction().replace('Your Fragment Container ID', new 'Fragment Class Name').addToBackStack(null).commit();
Cheers!

Android SetOnClickListener(this) doesn't work in Fragment

I want to make an App, which has a NavigationView and some fragments. I have no problem to display the different fragments and to navigate inside the application. But I did not manage to implement buttons inside my fragments.
Nothing happens when I click on the button. However I don't have any error.I have searched on Internet and I really don't understand why it doesn't work.I used the same method as in "classic" activity. I guess there is a problem withb.setOnClickListener(this). I pasted my code. I hope one of you will see my error. Thanks a lot for reading.
Accueil.java (mainActivity):
public class Accueil extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener,
HomeFragment.OnFragmentInteractionListener,Settings_accountFragment.OnFragmentInteractionListener {
NavigationView navigationView;
private FragmentTransaction fragmentTransaction;
private FragmentManager fragmentManager;
private static UserLocalStore userLocalStore;
private static User user;
public Intent login;
//private TextView eventName,eventPlace,eventSchedule;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_accueil);
userLocalStore=new UserLocalStore(this);
login=new Intent(this,LoginActivity.class);
navigationView = (NavigationView) findViewById(R.id.nav_view);
fragmentManager = getFragmentManager();
Toolbar myToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(myToolbar);
getSupportActionBar();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, myToolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
loadSelection(0);
}
private void loadSelection(int i){
switch (i){
case 0:
HomeFragment homeFragment = new HomeFragment();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragmentholder,homeFragment);
fragmentTransaction.commit();
break;
case 1:
Settings_accountFragment settings_account = new Settings_accountFragment();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragmentholder,settings_account);
fragmentTransaction.commit();
break;
default:
break;
}
}
#Override
protected void onStop() {
//userLocalStore.clearUserData();
userLocalStore.setUserLoggedIn(false);
userLocalStore.deleteCurrentUser();
super.onStop();
}
#Override
protected void onStart() {
super.onStart();
if(userLocalStore.getUserLoggedIn()) {
user=userLocalStore.getLoggedInUser(userLocalStore.getCurrentUser());
int i=0;
//How to change elements in the header programatically
View headerView = navigationView.getHeaderView(0);
TextView emailText = (TextView) headerView.findViewById(R.id.mail_header);
emailText.setText(user.getMail());
}
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_acc) {
// Handle the camera action
loadSelection(0);
} else if (id == R.id.nav_param) {
} else if (id == R.id.nav_param_compte) {
loadSelection(1);
} else if(id==R.id.logOut){
userLocalStore.setUserLoggedIn(false);
userLocalStore.deleteCurrentUser();
startActivity(login);
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
//getMenuInflater().inflate(R.menu.menu_calendar, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
return super.onOptionsItemSelected(item);
}
public static User getUser() {
return user;
}
public static UserLocalStore getUserLocalStore() {
return userLocalStore;
}
#Override
public void onFragmentInteraction(Uri uri) {
}
/*public void setEventNameText(String name) {
this.eventName.setText(name);
}
public void setEventPlaceText(String place) {
this.eventName.setText(place);
}
public void setEventScheduleText(String schedule) {
this.eventName.setText(schedule);
}*/
/*#Override
public Dialog onCreateDialog (int id) {
Dialog box = null;
switch(id) {
// Quand on appelle avec l'identifiant de la boîte normale
case ID_NORMAL_DIALOG:
box = new Dialog(this);
box.setTitle("Je viens tout juste de naître.");
break;
// Quand on appelle avec l'identifiant de la boîte qui s'énerve
case ID_ENERVEE_DIALOG:
box = new Dialog(this);
box.setTitle("ET MOI ALORS ???");
}
return box;
}
#Override
public void onPrepareDialog (int id, Dialog box) {
if(id == ID_NORMAL_DIALOG && compteur > 1)
box.setTitle("On est au " + compteur + "ème lancement !");
//On ne s'intéresse pas au cas où l'identifiant vaut 1, puisque cette boîte affiche le même texte à chaque lancement
}*/
}
Settings_accountFragment.java :
public class Settings_accountFragment extends Fragment implements View.OnClickListener {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
Button b;
View v;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public Settings_accountFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment Settings_accountFragment.
*/
// TODO: Rename and change types and number of parameters
public static Settings_accountFragment newInstance(String param1, String param2) {
Settings_accountFragment fragment = new Settings_accountFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
v=inflater.inflate(R.layout.fragment_settings_account, container, false);
b=(Button)v.findViewById(R.id.button);
b.setOnClickListener(this);
return inflater.inflate(R.layout.fragment_settings_account, container, false);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.button:
Log.d("coucou","true");
break;
}
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
fragment_settings_account.xml:
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/parametre_compte"
android:background="#color/grey"
android:gravity="center"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/button"
android:layout_gravity="center_horizontal" />
</FrameLayout>
You are not showing the correct view that has the button you set the click listener on because you are inflating the view again and returning it in onCreateView().
Replace
return inflater.inflate(R.layout.fragment_settings_account, container, false);
With
return v;
So that you return the view you already inflated.
In Settings_accountFragment:onCreateView you are inflating the view twice. Remove the second inflate code and just return v;
v=inflater.inflate(R.layout.fragment_settings_account, container, false);
b=(Button)v.findViewById(R.id.button);
b.setOnClickListener(this);
return v;
Also, a side note - it's not common to use '_' in Java class names. SettingsAccountFragment is a better than Settings_accountFragment

Passing data from one fragment to another is not working when passing data

I have a fragment fragmentA on which I have a gridview. The user clicks on a row the grid, I read the value of the first column and pass it to another fragment MapFragment. When I run in debug mode, I can see that the data from fragmentA is passed to the main activity and the app crashes.
What is wrong with code? Am I missing anything?
FATAL EXCEPTION: main
java.lang.NullPointerException
at com.text.MainActivity.SendData(MainActivity.java:51)
at com.test.fragmentAFragment$1.onItemClick(BurnScheduleFragment.java:50)
at android.widget.AdapterView.performItemClick(AdapterView.java:301)
at android.widget.AbsListView.performItemClick(AbsListView.java:1539)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3332)
at android.widget.AbsListView$1.run(AbsListView.java:4554)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5279)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
at dalvik.system.NativeStart.main(Native Method)
I have an interface as
`public interface Communicate {
public void SendData(String place);
}
In MapFragment
public class MapFragment extends Fragment {
private MapView map;
HashMap markerMap = new HashMap();
Marker marker;
public MapFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = this.getArguments();
}
public void Show(String title)
{
Marker showMarkerOnMap = (Marker)markerMap.get(title);
showMarkerOnMap.showInfoWindow();
}
private void CreateMarkers(){
GoogleMap gMap = map.getMap();
gMap.setMyLocationEnabled(true);
gMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
marker = gMap.addMarker(new MarkerOptions().title("One")
.snippet("description")
.position(new LatLng( 0, 0)));
markerMap.put("One", marker);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_map, container, false);
if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity().getApplicationContext()) == ConnectionResult.SUCCESS) {
//Initialze mapview
MapsInitializer.initialize(getActivity());
map = (MapView) view.findViewById(R.id.mapView);
map.onCreate(savedInstanceState);
CreateMarkers();
} else {
Toast.makeText(getActivity(), "Please install google play services", Toast.LENGTH_LONG).show();
}
return view;
}
#Override
public void onResume() {
super.onResume();
map.onResume();
}
#Override
public void onPause() {
super.onPause();
map.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
map.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
map.onLowMemory();
}
}
In My MainAcyivity I have
implemented the SendData as
public void SendData(String place)
{
FragmentManager fragmentManager = getSupportFragmentManager();
MapFragment mapFragment = (MapFragment)fragmentManager.findFragmentById(R.id.mapView);
mapFragment.Show(place);
}
and I have added the method Show in the MapFragment
public void Show(String title)
{
Marker showMarkerOnMap = (Marker)markerMap.get(title);
showMarkerOnMap.showInfoWindow();
}
public class MainActivity extends ActionBarActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks, Communicate {
private NavigationDrawerFragment mNavigationDrawerFragment;
private CharSequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
public void SendData(String place)
{
FragmentManager fragmentManager = getSupportFragmentManager();
MapFragment mapFragment = (MapFragment)fragmentManager.findFragmentById(R.id.mapView);
mapFragment.Show(place);
}
#Override
public void onNavigationDrawerItemSelected(int position)
{
// update the main content by replacing fragments
Fragment fragment = null;
switch (position){
case 0:
fragment= new MapFragment();
break;
case 1:
fragment = new BFragment();
break;
case 2:
break;
default:
fragment = new AFragment();
break;
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, fragment)
.commit();
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
}
}
public void restoreActionBar() {
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.main, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MainActivity) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
}
}
`
Map_fragment.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.google.android.gms.maps.MapView
android:id="#+id/mapView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
Your fragment is null. Otherwise the NullPointerException would be caused by the Fragment and not the Activity. Did you call getFragmentById with the correct ID which is the container ID or the XML-ID?
To pass value from activity to fragment or fragment to fragment, use setArgument.
Bundle bundle = new Bundle();
bundle.putInt(key, value);
fragment.setArguments(bundle);
How to pass values between Fragments
I hope it will help for you.

How to Call Navigation Drawer Fragment from Activity?

I have a Navigation Drawer which is created by Android studio. I Called a Activity from the Navigation Drawer.In that Activity, the navigation drawer is not showing up ?
How can i Call the Navigation Drawer from the below Activity ?
PlayerActivity
import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubeStandalonePlayer;
public class PlayerActivity extends Activity {
private static final int REQ_START_STANDALONE_PLAYER = 1;
private static final int REQ_RESOLVE_SERVICE_MISSING = 2;
private static final String PLAYLIST_ID = "PL5BxbbBpI7r";
public static final String DEVELOPER_KEY = "AIwXEZQLS-U";
private NavigationDrawerFragment mNavigationDrawerFragment;
private CharSequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
}
public void Play(View v) {
int startIndex = 0;
int startTimeMillis = 0;
boolean autoplay = true;
boolean lightboxMode = false;
Intent intent = null;
intent = YouTubeStandalonePlayer.createPlaylistIntent(this, DEVELOPER_KEY,
PLAYLIST_ID, startIndex, startTimeMillis, autoplay, lightboxMode);
if (intent != null) {
if (canResolveIntent(intent)) {
startActivityForResult(intent, REQ_START_STANDALONE_PLAYER);
} else {
// Could not resolve the intent - must need to install or update the YouTube API service.
YouTubeInitializationResult.SERVICE_MISSING
.getErrorDialog(this, REQ_RESOLVE_SERVICE_MISSING).show();
}
}
}
private boolean canResolveIntent(Intent intent) {
List<ResolveInfo> resolveInfo = getPackageManager().queryIntentActivities(intent, 0);
return resolveInfo != null && !resolveInfo.isEmpty();
}
}
Navigation.java
public class Navigation extends Activity
implements HomeFragment.OnFragmentInteractionListener, NavigationDrawerFragment.NavigationDrawerCallbacks, NewsFragment.OnFragmentInteractionListener{
#Override
public void onFragmentInteraction(Uri uri) {
}
private NavigationDrawerFragment mNavigationDrawerFragment;
private CharSequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_navigation);
mNavigationDrawerFragment = (NavigationDrawerFragment)getFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getFragmentManager();
switch(position){
case 0:
HomeFragment homeFragment = new HomeFragment();
fragmentManager.beginTransaction().replace(R.id.container, HomeFragment.newInstance("",""))
.commit();
break;
case 1:
NewsFragment newsFragment = new NewsFragment();
fragmentManager.beginTransaction()
.replace(R.id.container, NewsFragment.newInstance("",""))
.commit();
break;
case 2:
Intent intent= new Intent(this,PlayerActivity.class);
startActivity(intent);
break;
}
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
}
}
public void restoreActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.navigation, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_navigation, container, false);
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((Navigation) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
}
}
NavigationDrawer is meant to work with fragments, because the drawer is a fragment itself. You can access that drawer as long as you stay in the same Activity but once you change Activity you can't access to the drawer (Unless you create another instance of the drawer, but then you are missing the whole point of it). In order to accomplish what you want I'd recommend two things.
1) Instead of launching a new Activity make PlayerActivity a fragment.
2) Create a BaseActivity with a drawer and make all your other Activities extend it, that way you only have one single reference to the drawer in your project.
You should use fragment instead of activity! You should have two fragments as default when you create the project. One is for navigation drawer, and the other one is for content. You should replace that content fragment with your new content which you put in second activity..
You need to do the same thing in the PlayerActivity
mNavigationDrawerFragment = (NavigationDrawerFragment)getFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
Also put navigation drawer inside R.layout.activity_player.
Like you did in R.layout.activity_navigation

Cant Save and Restore variable in fragment

Before I post, I tried to read many topics about restore app state and tried it but it does not solve my problem.
My Class is:
public class MainActivity extends ActionBarActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
private static boolean lv11 = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
if(position == 0)
{
fragmentManager.beginTransaction()
.replace(R.id.container, PlaceholderFragment.newInstance(position + 1))
.commit();
}
else if(position == 1)
{
fragmentManager.beginTransaction()
.replace(R.id.container, PlaceProfile.newInstance(position + 1))
.commit();
}
else if(position == 2)
{
fragmentManager.beginTransaction()
.replace(R.id.container, PlaceLogBook.newInstance(position + 1))
.commit();
}
else if(position == 3)
{
fragmentManager.beginTransaction()
.replace(R.id.container, PlaceBeverages.newInstance(position + 1))
.commit();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK) {
boolean finInfo = data.getBooleanExtra("Done", false);
System.out.println("OnActivityResult = " + finInfo);
if (finInfo == true) {
readIt.setBackgroundColor(R.drawable.abc_ab_bottom_solid_light_holo);
if (readIt.getText() == info1.getText()) {
lv11 = false;
}
}
}
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
case 4:
mTitle = getString(R.string.title_section4);
break;
}
}
public void restoreActionBar() {
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.main, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
InitializeItem();
if(savedInstanceState != null) {
Log.v("","on Creat View");
lv11 = savedInstanceState.getBoolean("Level1");
if (lv11 == false) {
info1.setBackgroundColor(R.drawable.abc_ab_bottom_solid_light_holo);
}
}
//where i create my view ...
return rootView;
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
Log.v("TAG", "In frag's on save instance state ");
savedInstanceState.putBoolean("Level1",false);
super.onSaveInstanceState(savedInstanceState);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MainActivity) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
}
All are working fine but my problem is using onSaveInstantState() method.I used Log.v to check and it called when I press recent button on hardware then I kill it.After that when I run the app again my SaveInstantstate is null.In my case I want to change button color by check boolean that put parameter in save state and restore it back on onCreateView.
I want to know:
what is wrong in my implementation and why I can't call restore my state
How to implement it in the right way
*all code above are in the same class file
Thank you,and sorry for my grammar.
After you killed your application, all you Bundles are destroyed. The onSavedInstanceState() is used to protect state of app from being killed by the OS.
In your case you need to save the state permanently.
The "SharedPreferences" is ideal for that.

Categories

Resources