I have a problem with accessing activity's method from fragment.
Or anything int the activity from the fragment.
Here's fragment code:
public class MainFragment extends Fragment {
private MainActivity ma = (MainActivity) getActivity();
public SipAudioCall call = null;
public SipManager mSipManager = null;
public SipProfile mSipProfile = null;
public MainFragment() {
// TODO Auto-generated constructor stub
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Create a new TextView and set its text to the fragment's section
// number argument value.
LinearLayout mLinearLayout = (LinearLayout) inflater.inflate(R.layout.main_layout, container, false);
final Button callbtn = (Button) mLinearLayout.findViewById(R.id.callbtn);
final Button endbtn = (Button) mLinearLayout.findViewById(R.id.endbtn);
callbtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
callbtn.setVisibility(View.GONE);
endbtn.setVisibility(View.VISIBLE);
ma.initiateCall();
}
});
Maybe casting the activity is wrong?
Thx in advance
I'm guessing that the fragment is not attached to the activity when u call getActivity(). Try to initialize the activity reference in the fragment method onAttach().
So something like this:
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
ma = (MainActivity) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " Not MainActivity class instance");
}
}
Related
I am writing an android app using android studio. So far I have created a tabbed activity to be my main activity, and another activity that would be opened on a click of a button in one of the tabs in my main tabbed activity. The problem is that I have tried to accomplish this in a few ways but it seems like the code in my public View onCreateView just doesn't get executed at all. This is the code I'm trying to run:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
Button mainSignInButton = (Button) view.findViewById(R.id.mainSignInButton);
mainSignInButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getActivity() ,LoginActivity.class);
startActivity(i);
}
});
return view;
}
I have also tried to add a simple toast message to this block of code to see if it gets executed but I didnt see the toast pop up as well...
First of all, delegate to Activity the startActivity(). Try something like follow on your fragment:
public class FragmentMain extends Fragment {
private OnInteractionListener mListener;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
Button mainSignInButton = (Button) view.findViewById(R.id.mainSignInButton);
mainSignInButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mListener.onClickSignInButton()
}
});
return view;
}
public interface OnInteractionListener {
void onClickSignInButton();
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null
}
}
On your Activity try like follow:
public class MyActivity extends AppCompatActivity implements FragmentMain.OnInteractionListener {
...
#Override
public void onClickSignInButton() {
Intent i = new Intent(this, LoginActivity.class);
startActivity(i);
}
}
I have two activities A and B which is extending one Base class Main and this Base class has one Framelayout in its layout which we are including in both of the activities A and B respective layouts.
I am checking the instance creation of fragment in Fragment which I am also inflating when I go into particular acitivity.
Here my code is :
public class BaseAcitvity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_acitvity);
}
}
Here is my FirstActivity::
public class FirstActivity extends BaseAcitvity {
public FirstFragment firstFragment ;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.firstactivitylayout);
firstFragment = new FirstFragment();
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.card_view_layout,firstFragment).commit();
Button buttonclick = (Button)findViewById(R.id.clickfirstactivity);
buttonclick.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(getApplicationContext(),SecondActivity.class);
startActivity(intent);
}
});
}
}
public class SecondActivity extends BaseAcitvity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.secondactivity);
FirstFragment fragment = FirstFragment.getInstance();
if(fragment == null)
{
fragment = new FirstFragment();
}
else {
FragmentManager fragmentManager = getFragmentManager();
if(fragment !=null)
{
fragmentManager.beginTransaction().replace(R.id.card_view_layout,fragment).commit();
}
}
}
}
And The Fragment is ::
public class FirstFragment extends Fragment {
private static FirstFragment currentInstance;
FirstFragment () {
currentInstance = this;
}
public static synchronized FirstFragment getInstance() {
if (currentInstance == null)
currentInstance = new FirstFragment();
return currentInstance;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
return inflater.inflate(R.layout.fragment_one, container, false);
}
}
Now my issue is if I have already created the instance of fragment in FirstActivity and checking the singleInstance in Fragment , the at the time of SecondActivity why the OncreatView() of fragment doesn't call where the instance gives not null.
Please help me..so that is there any way to call OncreateView() to inflate the fragmentLayout.
I have a main activity class, and a private inner class within the main activity. The private inner class has methods that when called will display fragments. This inner class implements an interface defined in the Fragment's class, to be used as a sort of callback. It is probably easiest to show through code.
public class MainActivity extends FragmentActivity {
//on a button clicked
EditItemManger em = new EditItemManager();
em.begin();
private class EditItemManager implements on EditItemFragment.EditedItemClickedListener{
//consructor, other stuff. no onCreate method because this inner class does not (explicity??) extend activty
public void begin(){
EditItemFragment editItemFrag = new EditItemFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(editItemFrag, EDIT_FRAG_TAG)
fragmentTransaction.commit();
}
#Override
public void onEditItemClicked() {
editFinish();
}
public void editFinish()
{
// other stuff
}
}
}
My EditItemFragment class, where the onAttach method always has a null activity parameter
public class EditItemFragment extends DialogFragment {
protected EditedItemClickedListener editedItemClickedListener;
protected ImageButton button;
public EditItemFragment(){}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
final Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.edit_name_fragment, container, false);
button = (ImageButton) view.findViewById(R.id.submit_new_item_button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
editedItemClickedListener.onEditedItemButtonClicked();
}
});
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
editedItemClickedListener= (EditedItemClickedListener) activity;
} catch (ClassCastException e) {
e.printStackTrace();
}
}
public interface OnEditNameButtonClickedListener {
public void onEditNameButtonClicked();
}
So because the parameter in onAttach() in my Fragment class is always null, it eventually causes a null pointer exception. I am wondering if it is because the fragment is called from a class that is not extending activity. The problem is that if this class extends activity, there will be an issue with trying to commit the Fragment Transaction
I guest your onAttach returns nullpointer exception. Its because your parent Activity the main activity doesnt implement your custom interface so it return null. See the code below let me know if it help you:
public class MainActivity extends FragmentActivity implements EditItemFragment.EditedItemClickedListener{
private DialogFragment editItemDialog;
//Do your code here
#Override
public void onEditItemClicked() {
editFinish();
}
public void showDialog(){
//this is for showing your custom dialog fragment
editItemDialog = EditItemFragment.newInstance();
editItemDialog.show(getSupportFragmentManager(),"editItemDialog");
}
}
this is for your EditItemFragment:
public class EditItemFragment extends DialogFragment{
//Do your code here
public static EditItemFragment newInstance(){
EditItemFragment editItemDialog = new EditItemFragment();
return editItemDialog;
}
}
i made an interface in the fragment class kind of like a listener to send a string from the Fragment to the Activity. what is the best way to also send strings in the opposite direction? from activity to fragment? so there is now an interface in the fragment, so do i have to make another interface in the Activity to send strings in the other direction, or is there a better way?
the fragment class:
public class FragmentHeadless extends Activity implements FragmentHeadlessFragment.OnTimeRequestedListener {
FragmentTransaction transaction;
Button button;
TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_headless);
button = (Button) findViewById(R.id.button1);
textView = (TextView) findViewById(R.id.textView1);
FragmentManager fragmentManager = getFragmentManager();
transaction = fragmentManager.beginTransaction();
transaction.add(new FragmentHeadlessFragment(), "processorFragment");
transaction.commit();
}
#Override
public void passString(String stringFromFragment) {
textView.setText(stringFromFragment);
Toast.makeText(this, "String passed from fragment " + stringFromFragment, Toast.LENGTH_SHORT).show();
}
}
the activity class
public class FragmentHeadlessFragment extends Fragment {
private OnTimeRequestedListener listener;
String tempString = "";
Activity activity;
Handler handler;
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
handler = new Handler();
new Thread(){
public void run() {
SystemClock.sleep(3000);
handler.post(new Runnable() {
#Override
public void run() {
// pass string to activity
passData("test string from fragment with 3 second delay");
}
});
} // end run
}.start();
} // end onCreate
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof OnTimeRequestedListener) {
listener = (OnTimeRequestedListener) activity;
} else {
throw new ClassCastException(activity.toString()
+ " must implemenet OnTimeRequestedListener");
}
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
activity = getActivity();
setRetainInstance(true);
}
public interface OnTimeRequestedListener {
public void passString(String timeNumberString);
}
public void passData(String data) {
listener.passString(data);
}
}
since you have an instance to the fragment, you can just call the function you need via the activitiy:
instead of :
transaction.add(new FragmentHeadlessFragment(), "processorFragment");
use:
private FragmentHeadlessFragment mFragment;
...
mFragment=new FragmentHeadlessFragment();
transaction.add(mFragment, "processorFragment");
and when you wish, call:
mFragment.foo(myInt,myString,...) ;
btw, why do you have a field for the transaction?
Im using a fragment that is supposed to display a webview. When I try to instantiate it from the class that uses it I get the following warning in my logcat.
02-21 23:26:46.843: W/System.err(32468): android.content.ActivityNotFoundException: Unable to find explicit activity class {get.scanner/get.scanner.WebFrag}; have you declared this activity in your AndroidManifest.xml?
Im just learning how to use fragments and Ive never tried declaring them in my manifest and I havent seen anywhere telling you to do so.
Heres the WebFrag class.
public class WebFrag extends Fragment{
private WebView viewer = null;
// if we weren't just using the compat library, we could use WebViewFragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
viewer = (WebView) inflater
.inflate(R.layout.webview, container, false);
WebSettings settings = viewer.getSettings();
settings.setJavaScriptEnabled(true);
settings.setDefaultZoom(ZoomDensity.FAR);
return viewer;
}
#Override
public void onPause() {
if (viewer != null) {
viewer.onPause();
}
super.onPause();
}
#Override
public void onResume() {
super.onResume();
if (viewer != null) {
viewer.onResume();
}
}
public void updateUrl(String newUrl) {
if (viewer != null) {
viewer.loadUrl(newUrl);
}
}
}
EDIT: adding WebFrag as an activity to the manifest causes the following error
02-22 00:17:55.711: E/AndroidRuntime(2524): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{get.scanner/get.scanner.WebFrag}: java.lang.ClassCastException: get.scanner.WebFrag
EDIT: Heres the main fragmentactivity where Im trying to use my class
public class GetScannerActivity extends FragmentActivity {
private String mUrl = "http://www.yahoo.com/";
Button scanButton;
Button paint;
Button compTrans;
String yurl = "http://www.yahoo.com/";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
compTrans = (Button) findViewById(R.id.checkCurrentDeals);
compTrans.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
WebFrag viewer = (WebFrag) getSupportFragmentManager()
.findFragmentById(R.id.web_frag);
try{
if (viewer == null || !viewer.isInLayout()) {
Intent showContent = new Intent(getApplicationContext(),
WebFrag.class);
showContent.setData(Uri.parse(yurl));
try{
startActivity(showContent);
}catch(ActivityNotFoundException e){
e.printStackTrace();
}
} else {
viewer.updateUrl(yurl);
}
}catch(Exception e){
e.printStackTrace();
}
}
});
}
}
No don't add it to your manifest. You never need to add fragments to your manifest.
Do you create an Intent somewhere to start the WebActivity? How is it brought to the screen, that is probably where your problem lies.
EDIT
This is your problem:
Intent showContent = new Intent(getApplicationContext(),
WebFrag.class);
startActivity(showContent);
You can't start a Fragment as an Activity, you'll have to wrap the fragment in an Activity that extends FragmentActivity
if you want to go back from activity to Fragment try this
proToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Note: you must give an id to the Main layout of your activity e.g : searchVehicles
((ConstraintLayout) findViewById(R.id.searchVehicles)).removeAllViews();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragment_nearby_vehicles fnv = new fragment_nearby_vehicles();
fragmentTransaction.add(R.id.searchVehicles, fnv).commit();
}
});