In my program, there are many fragments.
In the ActionBar, I have a SearchView, and result of the search is displayed in fragment0.
When I go to fragment2 (that does not have Webview), I must go back fragment0 to show results.
However, when I go back to fragment0 and call the Webview, it is null.
What's problem and solution?
Here is MainActivity (where search query is excuted):
Fragment fragment0 = new SearchScrActivity();
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
ft.replace(R.id.content_frame, fragment0);
ft.commit();
WebView _webview = (WebView) findViewById(R.id.webViewResult);
Here is SearchScrActivity.java
public class SearchScrActivity extends SherlockFragment {
private WebView _webView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_search_screen, container,
false);
_webView = (WebView) rootView.findViewById(R.id.webViewResult);
_webView.setBackgroundColor(0x00000000);
_webView.setLayerType(WebView.LAYER_TYPE_SOFTWARE, null);
String meaning;
meaning = "";
_webView.loadDataWithBaseURL(null, meaning, "text/html",
"utf-8", null);
return rootView;
}
}
Related
I am developing my android application (Java) in android studio i am new to this.
there are two fragments A & B,
fragment A contains multiple buttons (different buttons with different links) and
fragment b contain webview.
I tried but the application is crashing when click the button.
Fragment A code
String[] urls=new String[6];
Bundle bundle;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_external_links, container, false);
LinearLayout fb_link = (LinearLayout) view.findViewById(R.id.fb_link_icon);
fb_link.setOnClickListener(this);
urls[0] ="https://facebook.com";
LinearLayout google_link = (LinearLayout) view.findViewById(R.id.google_link_icon);
google_link.setOnClickListener(this);
urls[1] ="https://google.com";
LinearLayout hotmail_link = (LinearLayout) view.findViewById(R.id.hotmail_link_icon);
hotmail_link.setOnClickListener(this);
urls[2] ="https://hotmail.com";
LinearLayout yahoo_link = (LinearLayout) view.findViewById(R.id.yahoo_link_icon);
yahoo_link.setOnClickListener(this);
// urls[3] ="https://yahoo.com";
return view;
}
#Override
public void onClick(View v) {
Fragment fragment = null;
switch (v.getId()){
case R.id.fb_link_icon:
fragment = new WebViewFragment();
bundle.putString("links" , urls[0]);
fragment.setArguments(bundle);
replaceFragment(fragment);
break;
case R.id.google_link_icon:
fragment = new WebViewFragment();
bundle.putString("links" , urls[1]);
fragment.setArguments(bundle);
replaceFragment(fragment);
break;
case R.id.hotmail_link_icon:
fragment = new WebViewFragment();
bundle.putString("links" , urls[2]);
fragment.setArguments(bundle);
replaceFragment(fragment);
break;
}
}
public void replaceFragment(Fragment Fragment){
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, Fragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
fragment B code
WebView webview;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_web_view, container, false);
webview.findViewById(R.id.webview_frame);
Bundle bundle = this.getArguments();
String website = bundle.getString("links");
String webSite = getActivity().getIntent().getExtras().getString("links");
webview.setWebViewClient(new WebViewClient());
webview.loadUrl(website);
WebSettings websettings = webview.getSettings();
websettings.setJavaScriptEnabled(true);
return view;
}
}
I am new to android, and i am facing this problem when the screen orientation is changed. The fragment gets called twice whenever screen orientation changes. Below is the sample of my code. I checked other posts, but couldnt find answer. Anyone guide me through this.
public class SampleFragment extends Fragment {
static final String TAG_NAME = SampleFragment.class.getSimpleName();
List<PhrToolBar> mToolBarList;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
DaggerHelper.getAppProviderComponent().inject(this);
mRootView = null;
getActivity().setTitle("Personal Health Records");
mRootView = inflater.inflate(R.layout.sample_phr_main_fragment, container, false);
mBinding = DataBindingUtil.bind(mRootView);
mBinding.setViewModel(mViewModel);
setHasOptionsMenu(true);
return mRootView;
}
Simple add this code
if (savedInstanceState == null) {
// only create fragment if activity is started for the first time
mFragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
FragmentOne fragment = new FragmentOne();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
} else {
// do nothing - fragment is recreated automatically
}
My Fragment
public class CustomFrag extends Fragment {
private Button btn;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.button_fragment, container, false);
btn = (Button)view.findViewById(R.id.button1);
return view;
}
public void sendItem(String item) {
btn.setText(item);
}
}
And in my activity
public void loadFragment(String data) {
// Load up new fragment
Fragment fragment = new CustomFrag();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.add(R.id.contentFragment, fragment, "custFrag");
transaction.addToBackStack("custFrag");
transaction.commit();
// Required before calling fragment methods
getSupportFragmentManager().executePendingTransactions();
// Load fragment with data
CustomFrag frag = (CustomFrag) getSupportFragmentManager().findFragmentByTag("custFrag");
frag.sendItem(data);
}
I'm getting a nullpointer exception any time I attempt to use the views of my fragment. If I try to load the view inside the method as well, it will not work
i.e. inside sendItem()
btn = (Button)getView().findViewById(R.id.button1);
My layout (button_fragment) contains the button:
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Because you have executed the transaction does not mean that the fragment has actually created its view. Which is why btn is still null.
To pass data from the activity to the fragment, use the argument bundle:
Fragment fragment = new CustomFrag();
Bundle args = new Bundle();
args.putString("item", data);
fragment.setArguments(args);
Then, in onCreateView:
btn = (Button)view.findViewById(R.id.button1);
btn.setText(getArguments().getString("item"));
See this Best practice for instantiating a new Android Fragment question and the first answer.
The problem here is that the fragment's layout is not drawn yet when sendItem(...) is called. Which means btn is null at that point. Instead, this is how you're supposed to do it (see http://developer.android.com/guide/components/fragments.html):
public class CustomFrag extends Fragment {
private Button btn;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.button_fragment, container, false);
btn = (Button)view.findViewById(R.id.button1);
btn.setText(getArguments.getString("item"));
return view;
}
}
And
public void loadFragment(String data) {
// Load up new fragment
Fragment fragment = new CustomFrag();
Bundle args = new Bundle();
args.putString("item", data);
fragment.setArguments(args);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.add(R.id.contentFragment, fragment, "custFrag");
transaction.addToBackStack("custFrag");
transaction.commit();
// Required before calling fragment methods
getSupportFragmentManager().executePendingTransactions();
}
Edit:
njzk2 was faster, but I hope the details I gave will help you further. In any case, the link he gave explains nicely why you should do it like that.
I'm trying out some fragments right now. I've got a fragment with a button and when I click that button I switch to another fragment. Now when I push on the back button I return to the first fragment that's good. Now when I click again on that button a new fragment is started. So I always start a new fragment. I think thats not the way it needs to be done. Is there a better way to for example resume the already created fragment?
My code:
public static class PlaceholderFragment extends Fragment{
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
Button test = (Button)rootView.findViewById(R.id.button);
test.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View view)
{
Log.d("Test", "Button clicked.");
TestFrag newFragment = new TestFrag();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.container, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
});
return rootView;
}
}
public static class TestFrag extends Fragment {
public TestFrag() {
Log.d("Test","New fragment");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main2, container, false);
return rootView;
}
}
When you use the fragment transaction you can specify a tag for the fragment
fragmentTransaction.add(R.id.main_fragment, newFragment, fragTag);
fragmentTransaction.commit();
Then later you can find a fragment by tag from the fragmentManager
newFragment = fragMan.findFragmentByTag(fragTag);
if newFragment then is null you should create the Fragment since it wasnt found by the tag
Thanks to Joakim:
fragmentTransaction.add(R.id.main_fragment, newFragment, fragTag); fragmentTransaction.commit();
Then later you can find a fragment by tag from the fragmentManager
newFragment = fragMan.findFragmentByTag(fragTag); if newFragment then is null you should create the Fragment since it wasnt found by the tag. If the tag isn't null you can just add and commit the new one.
[UPDATE]
Problem solved : Simply add "addToBackStack(null)" before commit fragment :
Fragment fragment = new WebBrowserFragment();
fragment.setArguments(arguments);
FragmentTransaction fragmentTransaction = getActivity().getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
Here is the code of my fragment. When i am on this fragment and i click on back button, my application is closed.
I would like to go back on the previous loaded fragment.
What can i do to force this behavior ?
public class WebBrowserFragment extends Fragment {
WebView mWebView;
ProgressBar progressB = null;
private String mUrl;
private static String mtitle;
private static String msource;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
LayoutInflater mInflater = (LayoutInflater) getActivity().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View view = (View) mInflater.inflate(R.layout.web_browser_view, null);
MainActivity.setShareButtonToVisible();
Bundle bundle = getArguments();
String url = bundle.getString("URL");
mtitle = bundle.getString("TITRE");
msource = bundle.getString("SOURCE");
mUrl = url;
progressB = (ProgressBar) view.findViewById(R.id.progressBar1);
mWebView = (WebView) view.findViewById(R.id.webViewArticle);
mWebView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
if(progress < 100 && progressB.getVisibility() == ProgressBar.GONE){
progressB.setVisibility(ProgressBar.VISIBLE);
}
progressB.setProgress(progress);
if(progress == 100) {
progressB.setVisibility(ProgressBar.GONE);
}
}
});
mWebView.loadUrl(url);
return view;
}
You have to use FragmentTransaction.addToBackStack method when attaching your fragment to Activity. Here is the quote from documentation
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.