Changing displaying layout on button click - android

I have a custom circle layout with rotation feature and 4 views as buttons.
On main_activity i have 2 layouts :
-circle layout
-relative layout(Container)
What i want is:
-when the user taps on a button from circle layout, i want the container to be changed with another layout with another views.
This is the initialization of container:
displayLayout = (RelativeLayout) findViewById(R.id.fragment_container);
Initialization of Circle layout:
circleLayout = (CircleLayout) findViewById(R.id.circle_layout);
The tap event occurs on this method:
public void onItemClick(View view) {
displayLayout.removeAllViews();
-- What should i do here? --
}
I want that the new xml (newpage.xml) to be replaced in container.
Any sugestions to be done?
Thanks a lot!

you need to do it with fragments as shown in below, to replace view
check fragments in android(https://developer.android.com/reference/android/app/Fragment.html)
public void onItemClick(View view) {
//displayLayout.removeAllViews();
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack if needed
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
check http://sapandiwakar.in/replacing-fragments/
check example http://notionink.wikidot.com/rajeshbabu

replace code here ,
public void onItemClick(View view) {
// displayLayout.removeAllViews();
circleLayout.setVisibility(View.Gone);
}

Related

how to save android recycler view state (scroll position) in an activity with two fragments

I am new to Android and, as a first step, am building an app, for running in a handset, with an activity in which I put two fragments. The first fragment has a recycler view of items that are supposed to represent article titles. When I click on one, the second fragment opens and shows the title (in a text view) and the content (in another text view) of the article (for the moment, for simplicity, I put the article title as fake titles and I have a setting for which the content is not shown but it is shown the title in the content text view too).
I want to save the scroll position of the recycler view.
When I scroll down, having on top of the screen an article title different from the first, I choose an article and my second fragment opens with the expected contents, and that's ok. When I rotate to landscape, the same fragment contains the same content, ok. So:
1) when I press the back button from the landscape, returning to the first fragment, I get the same setting for the recycler view, ok;
2) when I rotate again to portrait, remaining on the second fragment, it is ok too. Now, if I press the back button to return to the first fragment, to the list of articles, the recycler view is NOT set to start with the item I initially scrolled to. What can I do?
I have this code in the first fragment, the one containing the recycler view:
#Override
public void onSaveInstanceState(Bundle state) {
int lastFirstVisiblePosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
state.putInt(Articles.RECYCLER_POSITION_KEY, lastFirstVisiblePosition);
super.onSaveInstanceState(state);
}
#Override
public void onActivityCreated(Bundle state) {
super.onActivityCreated(state);
if (state != null) {
int lastFirstVisiblePosition = state.getInt(Articles.RECYCLER_POSITION_KEY);
((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPosition(lastFirstVisiblePosition);
}
}
What am I missing? Thanks.
[EDIT] In my listener is this, for invoking the second fragment:
ArticleReaderFrag newFragment = new ArticleReaderFrag();
Bundle args = new Bundle();
args.putString(NEW_FRAG_TITLE_KEY, item);
args.putString(NEW_FRAG_BODY_KEY, itemb);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.main_activity, newFragment);
transaction.addToBackStack(null);
transaction.commit();
Reuse Fragment
When the Activity launches for the first time create a new instance of Fragment and use a TAG to save it with FragmentManager. When the activity gets recreated after orientation change. Retreive the old instance using the Tag.
Here is a sample code which you should have in your activity.
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.first_activity);
fragmentManager = getSupportFragmentManager();
if(savedInstanceState==null) {
userFragment = UserNameFragment.newInstance();
fragmentManager.beginTransaction().add(R.id.profile, userFragment, "TAG").commit();
}
else {
userFragment = fragmentManager.findFragmentByTag("TAG");
}
}
How to save scroll position?
That happens by default. Read this answer for more detail.
EDIT
I believe this is your method
public createSecondFragment(int position){
ArticleReaderFrag newFragment = new ArticleReaderFrag();
Bundle args = new Bundle();
args.putString(NEW_FRAG_TITLE_KEY, item);
args.putString(NEW_FRAG_BODY_KEY, itemb);
newFragment.setArguments(args);
FragmentTransaction transaction =
getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.main_activity, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
Save the position of on rotation and use that position to load the specific fragment.
Call the method when the activity is recreated after orientation change
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.first_activity);
if(savedInstanceState!=null) {
int lastSavedPosition = // Your logic
createSecondFragment(lastSavedPosition )
}
}

how to remove fragment after transition to next fragment

i use fragment As follows :
img_home.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ft = fragmentManager.beginTransaction();
ft.replace(R.id.freamlayout,fragment_home);
ft.remove(fragment_setting);
ft.commit();
}
});
img_setting.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ft = fragmentManager.beginTransaction();
ft.remove(fragment_home);
ft.replace(R.id.freamlayout,fragment_setting);
ft.addToBackStack(null);
ft.commit();
}
});
but when transition to fragment 2 , stays fragment 1
how to fix it ??
img1:
img2:
You only need to call replace() which does both:
Removes the added fragments, and adds the new one you are passing as the second argument.
See:
FragmentTransaction replace
As i can see in documentation for fragmentTransaction.replace()
Replace an existing fragment that was added to a container. This is
essentially the same as calling remove(Fragment) for all currently
added fragments that were added with the same containerViewId and then
add(int, Fragment, String) with the same arguments given here.
Check
Be sure you are using v4 fragments, because app fragments are depricated in android P.
Most easy approach
If nothing works for you, put background on parent node of both of fragment layout. so the old fragment does not appear behind this.

Fragments overlapping while using replace() [duplicate]

I have a fragment inside a group activity and I want to replace it with another fragment:
FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();
SectionDescriptionFragment bdf = new SectionDescriptionFragment();
ft.replace(R.id.book_description_fragment, bdf);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
It works fine when it is done as a seperate project without using activity group, every thing works fine in log cat as control goes inside getview(), but no view is visible, not even any exception arises, I want the book detail fragment to be replaced by section detail fragment.
Xml of book detail fragment has id book_description_fragment and xml for section description fragment has id section_description_fragment.
The above code is in onClick method of an item, I want that when user taps on an item in horizontal scroll view, then the fragment changes.
Fragments that are hard coded in XML, cannot be replaced. If you need to replace a fragment with another, you should have added them dynamically, first of all.
Note: R.id.fragment_container is a layout or container of your choice in the activity you are bringing the fragment to.
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack if needed
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
Please see this Question
You can only replace a "dynamically added fragment".
So, if you want to add a dynamic fragment, see this example.
I've made a gist with THE perfect method to manage fragment replacement and lifecycle.
It only replace the current fragment by a new one, if it's not the same and if it's not in backstack (in this case it will pop it).
It contain several option as if you want the fragment to be saved in backstack.
=> See Gist here
Using this and a single Activity, you may want to add this to your activity:
#Override
public void onBackPressed() {
int fragments = getSupportFragmentManager().getBackStackEntryCount();
if (fragments == 1) {
finish();
return;
}
super.onBackPressed();
}
Use the below code in android.support.v4
FragmentTransaction ft1 = getFragmentManager().beginTransaction();
WebViewFragment w1 = new WebViewFragment();
w1.init(linkData.getLink());
ft1.addToBackStack(linkData.getName());
ft1.replace(R.id.listFragment, w1);
ft1.commit();
Use ViewPager. It's work for me.
final ViewPager viewPager = (ViewPager) getActivity().findViewById(R.id.vp_pager);
button = (Button)result.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
viewPager.setCurrentItem(1);
}
});
hope you are doing well.when I started work with Android Fragments then I was also having the same problem then I read about
1- How to switch fragment with other.
2- How to add fragment if Fragment container does not have any fragment.
then after some R&D, I created a function which helps me in many Projects till now and I am still using this simple function.
public void switchFragment(BaseFragment baseFragment) {
try {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
if (getSupportFragmentManager().findFragmentById(R.id.home_frame) == null) {
ft.add(R.id.home_frame, baseFragment);
} else {
ft.replace(R.id.home_frame, baseFragment);
}
ft.addToBackStack(null);
ft.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
enjoy your code time :)
you can use simple code its work for transaction
Fragment newFragment = new MainCategoryFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame_NavButtom, newFragment);
ft.commit();
You Can Use This code
((AppCompatActivity) getActivity()).getSupportFragmentManager().beginTransaction().replace(R.id.YourFrameLayout, new YourFragment()).commit();
or You Can This Use Code
YourFragment fragments=(YourFragment) getSupportFragmentManager().findFragmentById(R.id.FrameLayout);
if (fragments==null) {
getSupportFragmentManager().beginTransaction().replace(R.id.FrameLayout, new Fragment_News()).commit();
}
I change fragment dynamically in single line code
It is work in any SDK version and androidx
I use navigation as BottomNavigationView
BottomNavigationView btn_nav;
FragmentFirst fragmentFirst;
FragmentSecond fragmentSecond;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
fragmentFirst = new FragmentFirst();
fragmentSecond = new FragmentSecond ();
changeFragment(fragmentFirst); // at first time load the fragmentFirst
btn_nav = findViewById(R.id.bottomNav);
btn_nav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch(menuItem.getItemId()){
case R.id.menu_first_frag:
changeFragment(fragmentFirst); // change fragmentFirst
break;
case R.id.menu_second_frag:
changeFragment(fragmentSecond); // change fragmentSecond
break;
default:
Toast.makeText(SearchActivity.this, "Click on wrong bottom SORRY!", Toast.LENGTH_SHORT).show();
}
return true;
}
});
}
public void changeFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout_changer, fragment).commit();
}
In kotlin you can do:
// instantiate the new fragment
val fragment: Fragment = ExampleFragment()
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.book_description_fragment, fragment)
transaction.addToBackStack("transaction_name")
// Commit the transaction
transaction.commit()
This will work if you're trying to change the fragment from another fragment.
Objects.requireNonNull(getActivity()).getSupportFragmentManager()
.beginTransaction()
.replace(R.id.home_fragment_container,new NewFragment())
NOTE As stated in the above answers, You need to have dynamic fragments.
You can use fragment-ktx
// If you are in fragmet
childFragmentManager.beginTransaction()
// or if you are in activiry
supportFragmentManager.beginTransaction()
// Create and commit a new transaction
supportFragmentManager.commit {
setReorderingAllowed(true)
// Replace whatever is in the fragment_container view with this fragment
replace<ExampleFragment>(R.id.fragment_container)
}
To replace a fragment with another one do this, Note that R.id.fragment comes from the id that you give to the first tag of the fragment in the XML.
barAudioPlaying.setOnClickListener(view -> {
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment,new HomeFragment())
.commit();

Show Fragment like a popup with a Transparent background

I would like to make a Fragment pop-up like an AlertDialog but with a transparent background.
My fragment looks like this:
At the moment I am doing the following:
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Player player = (Player)adapterView.getItemAtPosition(i);
FragmentTransaction fragmentTransaction = getActivity().getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(PlayerProfileFragment.newInstance(null), null);
fragmentTransaction.commit();
}
The fragment doesn't show at all. I guess in order to make it work, I should use the overload add(layoutId, fragment) but that would just place the Fragment in a specific area and not display the Fragment as a "popup".
Any ideas?
The Fragment probably doesn't show because you are not specifying to which layout you want to add it to. The version of add() that you are using, adds the Fragment to a container whose id is 0 as the docs say.
I fixed this issue by creating an interface with the method:
public void addFragment(int viewId, Fragment fragment);
I then implemented that listener in my Activity by having a FragmentTransaction inside it:
public void addFragment(int viewId, Fragment fragment){
FragmentTransaction fragmentTransaction = getSupportFragmentTransaction().beginTran....;
fragmentTransaction.add(viewId, fragment);
fragmentTransaction.commit();
}

Android added Fragment to screen, but taps fall through new Fragment view to the previous one

I'm working with Fragments for the first time and running into a weird behavior. I have an activity with a Fragment covering the entire view. It contains a ListView. When I tap on an item in the ListView, I want to show a details fragment which contains information about that item.
This is how I'm presenting the new fragment view:
FragmentManager fragmentManager = this.getActivity().getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
DetailsFragment fragment = new DetailsFragment();
transaction.add(R.id.viewRoot, fragment).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.addToBackStack("Details").commit();
R.id.viewRoot is the id of the root layout in the first Fragment's layout xml, so the new Fragment fills the entire screen.
My Problem: When the new fragment is visible and covering the entire screen, any clicks or taps which land on the background (i.e. not hitting a button or textfield on the new fragment) appear to be going through the view and landing on the first fragment. So, I tap on a ListView item, which causes the DetailsFragment to get added to the screen. Then when I tap on the background of the DetailsFragment, that tap falls through and lands on the ListView causing another DetailsFragment to be added for whatever item I happened to hit behind the scenes.
Am I adding my new fragment incorrectly? Why are my clicks/taps falling through?
EDIT for caiuspb:
public class BaseFragment extends Fragment {
public void pushNewFragment(Fragment fragment, String description) {
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.remove(this);
transaction.add(R.id.viewRoot, fragment).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.addToBackStack(description).commit();
}
}
All of my fragments extend my BaseFragment class.
I experimented with the suggestions I received, but none of them worked. In the end, my solution was to add an OnTouchListener to the root view of my subfragments which discarded all touches.
View view = inflater.inflate(R.layout.mylayout, container, false);
view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
There is another post here on StackOverflow about that strange Fragment behaviour. Try to remove your Fragment before you add it because the replace Method seems to be buggy
edit:
Move the Fragment logic into your Activity because your activity contains your Fragments. Today I tried to use the FragmentActivity and Fragments from the Android Support Library. Now I can use the replace method withouht any bugs. This is my approach and this works:
public class DashActivity extends FragmentActivity{
...
private void changeRightFragment(Fragment fragment) {
Log.i(TAG, "Loading Fragment into container: " + fragment.getClass().toString());
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.rightfrag, fragment);
// Add a transition effect
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
// Add the Fragment to the BackStack so it can be restored by
// pressing the Back button
ft.addToBackStack(null);
ft.commit();
}
...
public void setUserFragment(User user) {
UserFragment fragment = new UserFragment(user);
changeRightFragment(fragment);
}
So if you want to invoke a changeFragment method from inside your Fragment use a callback mechanism to the Activity

Categories

Resources