I created an application in which i had 1 ACTIVITY and 8 Fragment in which i am inflating every fragment into the activity. but my problem is that every fragment is overlapping each other. I change the background color of every fragment but when i am clicking the vacant spaces button of my previous fragment get clicked.
please suggest me some thing to get out of this situation.
Main_Activity.class
public class ActRegistration extends AppCompatActivity {
FragmentManager fm;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_registration);
fm = getSupportFragmentManager();
loadFragment(new FragmentRegLogSkip(), FragmentRegLogSkip.FRAGMENT_KEY);
}
public void loadFragment(Fragment fragmentName, String fragmentKey) {
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.add(R.id.id_registration_layout_frame, fragmentName);
fragmentTransaction.addToBackStack(fragmentKey);
fragmentTransaction.commit();
}
}
Frag_1.class
public class FragmentRegLogSkip extends Fragment implements View.OnClickListener {
private Activity activity;
private Context context;
public static final String FRAGMENT_KEY = "fragment_reg_log_skip";
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
context = getContext();
LanguageChanger.changeLanguage(context);
View view = inflater.inflate(R.layout.act_registration_screen_login, container, false);
return view;
}
}
Don't forget to add android:clickable="true" and android:focusable="true" to the parent view of your second fragment so it catches the clicks and they don't get propagated to the fragment below. Something like this:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="true">
You're using fragmentTransaction.add(), which won't remove the previous Fragment - use fragmentTransaction.replace() if you want the other Fragment's view to be removed.
Note FragmentManager automatically restores any previously added Fragments when your Activity is recreated (i.e., when savedInstanceState != null). Therefore you'll want to ensure that you only add your initial Fragment once - when the savedInstanceState is null.
if (savedInstanceState == null) {
loadFragment(new FragmentRegLogSkip(), FragmentRegLogSkip.FRAGMENT_KEY);
}
Inside your second fragment layout file's Parent Tag , add this :-
android:clickable="true"
android:focusable="true"
then when you click on any view , it will not click previous fragment.
Related
I am making a login page with fragments but whenever i run the application i am only getting a white scree,no edittext no buttons nuthing.
LoginFragment
public class LoginFragment extends Fragment {
private View view;
private Button btcancel;
private EditText etpassword;
private Button btlogin;
private EditText etusername;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view=inflater.inflate(R.layout.login_frag,container,false);
return view;
}
private void initialize() {
btcancel = (Button) getActivity().findViewById(R.id.bt_cancel);
etpassword = (EditText) getActivity().findViewById(R.id.et_password);
btlogin = (Button) getActivity().findViewById(R.id.bt_login);
etusername = (EditText) getActivity().findViewById(R.id.et_user_name);
}
}
LoginActivity
public class LoginActivity extends Activity {
private FragmentTransaction fragmentTransaction;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fragmentSetUp();
}
private void fragmentSetUp() {
fragmentTransaction=getFragmentManager().beginTransaction();
LoginFragment loginFragment=new LoginFragment();
fragmentTransaction.add(loginFragment,"login").commit();
}
}
You need to have a parent layout to put a fragment, but in your case you can use the default layout of android as a parent container for the fragment.
solution:
fragmentTransaction=getFragmentManager().beginTransaction();
LoginFragment loginFragment=new LoginFragment();
fragmentTransaction.add(android.R.id.content,loginFragment,"login").commit();
it probably because you missed setContentView for the activity . Inside the layout you should declare a container where you can add/replace Fragments. Also in LoginFragment you are using getActivity to retrieve the Fragment's component. You should use the inflated view. The best way, imo, is to override onCreatedView
You can also use -
fragmentTransaction=getFragmentManager().beginTransaction();
LoginFragment loginFragment=new LoginFragment();
fragmentTransaction.add(0,loginFragment,"login").commit();
Fragment Transaction -
public abstract FragmentTransaction add (int containerViewId, Fragment
fragment, String tag)
Added in API level 11 Add a fragment to the activity state. This
fragment may optionally also have its view (if Fragment.onCreateView
returns non-null) into a container view of the activity.
Parameters
containerViewId - Optional identifier of the container this fragment is
to be placed in. If 0, it will not be placed in a container.
fragment - The fragment to be added. This fragment must not already
be added to the activity.
tag - Optional tag name for the fragment, to later retrieve the
fragment with FragmentManager.findFragmentByTag(String).
Returns - Returns the same FragmentTransaction instance.
I have 2 tabs in my app.Each have single fragment initially.
Scenario 1(Tab 1):
I 'm adding a second fragment in the tab on Button Click from the first fragment & again a third fragment on button click from second fragment.
Scenario 2(Tab 2):
Similar as tab1
Scenario 2(Switch between the Tab):
As I switch between the tab.I'm unable to get same tab fragment which I have added in the respective tab.
Below is my code:(First Fragment Tab1)
public class ArticleFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup view=(ViewGroup) inflater.inflate(R.layout.article_fragment, container,false);
fragmentTabHost.setup(getActivity(), getChildFragmentManager() , R.id.frag_container);
Button article_button = (Button) view.findViewById(R.id.article_btn);
article_button.setOnClickListener( new OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
article_txt.setText("Changed Value");
ArticleDetails articleFragment = new ArticleDetails();
fragmentTransaction.add(ScreenFragmentActivity.getContainertId(), articleFragment, AppConstants.ARTICLE_FRAGMENT_DETAILS);
fragmentTransaction.hide(ArticleFragment.this);
fragmentTransaction.addToBackStack(ArticleFragment.class.getName());
fragmentTransaction.commit();
}
});
return view;
}
}
Second Fragment Tab1:
public class ArticleDetails extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
ViewGroup view=(ViewGroup) inflater.inflate(R.layout.article_details, container,false);
Button article_button = (Button) view.findViewById(R.id.article_details_btn);
article_button.setOnClickListener( new OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
ArticleDetailsWithIn articleFragment = new ArticleDetailsWithIn();
fragmentTransaction.add(ScreenFragmentActivity.getContainertId(), articleFragment,
AppConstants.ARTICLE_FRAGMENT_DETAILS_WITHIN);
fragmentTransaction.hide(ArticleDetails.this);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
return view;
}
My Layout:
<android.support.v4.app.FragmentTabHost
android:id="#+id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TabWidget
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:orientation="horizontal" />
<FrameLayout
android:id="#+id/tabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
So Basically I'm trying to add the new Fragment within the tab .But on Switch I'm not able to retain my respective fragment
You can try this - tag your fragments with some name and store this in any static helper class using getter/setter method. Make your first fragment tag name as default (this is for first time launch). Then at place where you have logic to add new fragments, put the required if-else statements. Same goes for other tab also. (you can even use shared preferences, if you want to remember last seen fragment even when app is closed and restarted again.)
Create a static helper class.
public class HelperClass {
private static string TabOneFragmentOnScreen = "";
public static String getTabOneFragmentOnScreen () {
return TabOneFragmentOnScreen ;
}
public static void setTabOneFragmentOnScreen(
String TabOneFragmentOnScreen) {
HelperClass.TabOneFragmentOnScreen = TabOneFragmentOnScreen;
}
}
When you click one TabOne
if(HelperClass.getTabOneFragmentOnScreen.equals("")){
HelperClass.setTabOneFragmentOnScreen("FragmentOne");
//logic to add fragment one goes here
}
if(HelperClass.getTabOneFragmentOnScreen.equals("FragmentTwo")){
HelperClass.setTabOneFragmentOnScreen("FragmentTwo");
//logic to add fragment two goes here
}
This way it will always remember the last fragment on screen under tab one.
This code is not complete, but you can develop further on this logic.
I have a problem updating menu items of my Activity from a Fragment after an interstitial banner is closed (using "X" or clicking "back" it's the same).
Before android HONEYCOMB everything works well also after interstitial banner, maybe because I use android.support.v4.app.Fragment.
in my activity with this layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<HorizontalScrollView
android:id="#+id/menuContainer"
android:layout_width="match_parent"
android:layout_height="32dp" />
<FrameLayout
android:id="#+id/fragments"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
</LinearLayout>
I add a new fragment and everyting goes fine:
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragments, MyFragment.newInstance());
transaction.addToBackStack(null);
transaction.commit();
This is Fragment code:
public static MyFragment newInstance() {
return new MyFragment();
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
private View mSimpleContainer;
private TextView mSimpleText;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_test, container, false);
mSimpleContainer = view.findViewById(R.id.mSimpleContainer);
mSimpleText = (TextView) view.findViewById(R.id.simpleText);
return view;
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mSimpleText.setText("lorem ipsum");
MyActivity act = (MyActivity) getActivity();
if (act != null) {
HorizontalScrollView menu = (HorizontalScrollView) act.findViewById(R.id.menuContainer);
/**
* menu is null and I get NullPointerException here after interstitial is closed.
* Maybe the activity is paused and resumed but I expect that in onActivityCreated the activity is attached
*/
menu.hideMenuItems();
//This line open an Interstitial banner that when it's closed causes NullPointerException above
act.showInterstitial(); //If I comment this line everything works fine
}
}
When it's the correct time to call findViewById in the activity?
Thanks for any answers
I think you r switching many fragment in the fragments FrameLayout. In that case the fragments are showing and hiding. So if any memory shortage occur fragmentManger is destroying invisible fragments view, but the are still attached to activity. so getActivity() is not returning null, but view is returning null. In this situation you will call getView(), if getView() return null then your fragments view is destroyed by fragmentManager , otherwise call getView().findViewById() it will return you valid view object. There is no problem in support.v4 fragment. May be FragmentManager of support.v4 are more memory concious.
Im new to Android and so far everything went fine. Until i entered the Fragment Terrain.
In my Application I want a user to click a button in a activity. With that Button pressed so far i´m opening a fragment in which the user can change Settings.
Then i want to close, delete, whatever as long as i dont see the fragment anymore, from within the fragment.
So: Activity "A", opens Fragment "a".
- do stuff in the Fragment -
User, calls Method in "a" by Button, to close "a" .
here is my xml file to the fragment "a":
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="145dp"
android:orientation="vertical"
android:background="#EBDDE2" >
//took out a seekbar textview and checkbox for now.
<Button
android:id="#+id/buttonLeaveFragment"
style="#style/buttonredblack"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_below="#+id/seekBar_Radius"
android:onClick="closeFragment" <--- this i want to call in the fragment.
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:layout_marginBottom="10dp"
android:text="#string/button_ok" />
</RelativeLayout>
here is the java file of my fragment "a" activity:
public class SearchingRadiusFragment extends Fragment implements OnSeekBarChangeListener{
public static String username;
public void onAttach(Activity activity){
super.onAttach(activity);
}
public void onCeate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setUpLayout();
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view= inflater.inflate(R.layout.fragment_radius_searching,container, false);
return view;
}
#SuppressLint("NewApi")
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
Bundle bundle = this.getArguments();
if(bundle != null){
username = bundle.getString("username", null);
}
}
public void closeFragment(View v){
((UserProfileActivity)getActivity()).closeSearchingRadiusFragment();
}
}
now the necessary method in the activity "A":
public void closeSearchingRadiusFragment(){
SearchingRadiusFragment frag = new SearchingRadiusFragment();
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.setCustomAnimations(android.R.animator.fade_in,android.R.animator.fade_out);
transaction.remove(frag);
transaction.addToBackStack(null);
transaction.commit();
}
what am i missing?
eclipse gives me a Illegal.State.Expression. Saying the method closeFragment() could not be found in activity "A". Even though i want to use the one in the fragment "a".
If i change the name of the Method buttonLeaveFragment is calling to: closeSearchingFragment
Nothing happens, but the app doesn´t crash either.
You need to replace your visible fragment "A" with a new fragment (for example "B") using:
transaction.replace(R.id.framelayout, fragmentB);
On click button try this:
FragmentTransaction transaction=fragmentManager.beginTransaction();
transaction.setCustomAnimations(android.R.animator.fade_in,android.R.animator.fade_out);
transaction.replace(R.id.framelayout, fragmentB);
transaction.commit();
Your visible fragmentA will be replace from fragmentB
I am trying to use Android fragments in a very simple way, similar to the tutorial on the Android developer website.
I have an Activity (MediaInfoActivity) with the following code:
public class MediaInfoActivity extends FragmentActivity {
private final String TAG = "MediaInfoActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate()");
setContentView(R.layout.media_info_activity_layout);
}
}
Here is the code for the media_info_activity_layout.xml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment class="com.hawkforce.test.MediaInfoFragment"
android:id="#+id/mediaInfoFragment"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp" />
<FrameLayout android:id="#+id/mediaPlayerBarPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<fragment class="com.hawkforce.test.MediaPlayerBarFragment"
android:id="#+id/mediaPlayerBar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
And finally here is the code for MediaInfoFragment:
public class MediaInfoFragment extends Fragment {
private final static String TAG = "MediaInfoFragment";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate()");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.i(TAG, "onCreateView()");
if (container == null) {
Log.i(TAG, "onCreateView(): container = null");
}
return inflater.inflate(R.layout.media_info_fragment_layout, container, false);
}
}
Here is my problem : the container passed in the onCreateView() method of the MediaInfoFragment is null. As I understood, this should only be the case for non-UI Fragments. However, my Fragment has a UI, which is displayed OK on the screen when I launch MediaInfoActivity. It causes problems because no style declared in the xml layout file of the fragment is applied.
Here is my Log:
I/MediaInfoActivity: onCreate()
I/MediaInfoFragment: onCreate()
I/MediaInfoFragment: onCreateView()
I/MediaInfoFragment: onCreateView(): container = null
Am I missing anything obvious here ?
You just have to create a inflater like bellow in your fragment.
View rootView;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (rootView == null) {
rootView = inflater.inflate(R.layout.activity_my_cart, null);
} else {
((ViewGroup) container.getParent()).removeView(rootView);
}
return rootView;
}
I hope it will work as per your question.
I am not sure since I don't have the code of the SDK in front of me but I think that the life-cycle of calling Fragment "onCreateView" function is different between the two cases:
1. Static settings of fragment in layout
2. Loading pragmatically with FragmentManager.
In the first case the debugger get into Fragment.onCreateView() method immediately upon adding the content view to the parent activity as part of onCreate() code:
When calling: setContentView(R.layout.some_layoue);
You will see the debugger get into Fragment.onCreateView() before going to next line
In the second case the Fragment.onCreateView() is being invoked only after the onCreate() of the activity is finished.
This looks like design bug for me but possibly as design feature.
Anyway the container is null when adding fragment statically because the related object was not yet created.
In fact the difference between the two situations is much deeper. In the case of static fragments toggling between fragments will not create the view hierarchy correctly.
For example if you will add button-A to fragment A and button-B to Fragment-B and toggle the fragments with a code looks like this (highlighting only the relevant code):
public void turnOnFragment() {
FragmentManager manager = getFragmentManager();
if (manager != null) {
manager.beginTransaction()
.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out)
.attach(this)
.commit();
}
}
public void turnOffFragment() {
FragmentManager manager = getFragmentManager();
if (manager != null) {
manager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
manager.beginTransaction()
.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out)
.detach(this)
.commit();
}
}
You will see that in the case of static fragments the buttons from both fragments are presented although turning on and off. If however fragments are added programatically the toggle works fine and view hierarchy is cleaned and show only button from relevant fragment.
This is based of my experience with version 4.4.2