I am displaying various fragments in an Activity FrameLayout. The first fragment I display is a Google Map. To display a fragment, I swap the FrameLayout with a fragment. Next I display a fragment then push to the backstack. Upon popping the backstack the Google Map becomes very slow and laggy. If I override onBackPressed, remove the pushed fragment from the backstack then recreate the Google Map fragment, the Google Map responds as expected. Overridding onBackPressed seems like a work around.
How come the map is slow and laggy?
Here is my code (without the onBackPressed function I mentioned):
MainActivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
displayFragment(new MapFragment());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
try {
int id = item.getItemId();
if(id == R.id.displayBlankFragment) {
displayDialogFragment(new BlankFragment());
return true;
}
} catch(Exception e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
}
return super.onOptionsItemSelected(item);
}
private void displayFragment(Fragment fragment) {
FragmentTransaction t = getSupportFragmentManager().beginTransaction();
t.replace(R.id.frame, fragment);
t.commit();
}
private void displayDialogFragment(Fragment fragment) {
FragmentTransaction t = getSupportFragmentManager().beginTransaction();
t.replace(R.id.frame, fragment);
t.addToBackStack(null);
t.commit();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin">
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</RelativeLayout>
MapFragment
public class MapFragment extends Fragment {
private View view;
public MapFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(view == null) {
view = inflater.inflate(R.layout.fragment_map, container, false);
}
return view;
}
}
fragment_map.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" >
</fragment>
</FrameLayout>
BlankFragment
public class BlankFragment extends Fragment {
public BlankFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_blank, container, false);
}
}
fragment_blank.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment"/>
</FrameLayout>
Related
im developing an android app which has a bottomnavigation that opens 3 different fragments without a viewpager. One fragment has a viewpager inside it which opens 2 fragments. these 2 fragments are the same fragment and each has a recyclerview inside it. my problem is that when I run the app everything except the viewpager runs as intended. I tried putting the fragment inside the viewpager instead of it and the fragment works. I even tried putting the viewpager in a empty activity which worked as well.
This is my MainActivity which holds the BottomNavigation and its functionality:
public class MainActivity extends AppCompatActivity implements BottomNavigationView.OnNavigationItemSelectedListener {
private androidx.appcompat.widget.Toolbar toolbar;
private BottomNavigationView navView;
private Fragment fragment1 = new HomeFragment();
private Fragment fragment2 = new SearchFragment();
private Fragment fragment3 = new SettingsFragment();
private FragmentManager fm = getSupportFragmentManager();
private Fragment active = fragment1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = findViewById(R.id.action_bar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Home");
fm.beginTransaction().add(R.id.main_container, fragment3, "settings").hide(fragment3).commit();
fm.beginTransaction().add(R.id.main_container, fragment2, "search").hide(fragment2).commit();
fm.beginTransaction().add(R.id.main_container, fragment1, "home").commit();
navView = findViewById(R.id.nav_view);
navView.setOnNavigationItemSelectedListener(this);
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.navigation_home:
fm.beginTransaction().hide(active).show(fragment1).addToBackStack("home").commit();
active = fragment1;
toolbar.setTitle("Home");
return true;
case R.id.navigation_search:
fm.beginTransaction().hide(active).show(fragment2).addToBackStack("search").commit();
active = fragment2;
toolbar.setTitle("Search");
return true;
case R.id.navigation_settings:
fm.beginTransaction().hide(active)
.show(fragment3).addToBackStack("settings").commit();
active = fragment3;
toolbar.setTitle("Settings");
return true;
}
return false;
}
public void setCurrentPage(Fragment fragment, int position) {
if(fm.findFragmentByTag("playlist"+position) != null){
fm.beginTransaction().remove(fragment).hide(active).add(R.id.main_container, fragment, "playlist"+position).addToBackStack(null).commit();
active = fragment;
} else {
fm.beginTransaction().hide(active).add(R.id.main_container, fragment, "playlist"+position).addToBackStack(null).commit();
active = fragment;
}
}
}
This is the MainActivityLayout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<include
layout="#layout/action_bar"
android:id="#+id/action_bar"/>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="56dp"
android:layout_marginBottom="70dp"
android:id="#+id/main_container_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:id="#+id/main_container"/>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
android:layout_alignParentBottom="true"
app:menu="#menu/bottom_nav_menu"
app:itemTextColor="#color/bottom_nav_color"
app:itemIconTint="#color/bottom_nav_color"
android:elevation="20dp"/>
</RelativeLayout>
This is my Fragment that implements the ViewPager:
public class HomeFragment extends Fragment {
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_home, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
PlaylistsPagerAdapter playlistsPagerAdapter = new PlaylistsPagerAdapter(getChildFragmentManager());
playlistsPagerAdapter.addFragment(new PlaylistsFragment(),"private");
playlistsPagerAdapter.addFragment(new PlaylistsFragment(),"public");
ViewPager viewPager = view.findViewById(R.id.pager_home);
viewPager.setAdapter(playlistsPagerAdapter);
TabLayout tabLayout = view.findViewById(R.id.tab_layout_home);
tabLayout.setupWithViewPager(viewPager);
setHasOptionsMenu(false);
}
public class PlaylistsPagerAdapter extends FragmentStatePagerAdapter {
ArrayList<Fragment> mFragmentList = new ArrayList<>();
ArrayList<String> mFragmentListTitle = new ArrayList<>();
public void addFragment(Fragment playlistsFragment, String title) {
mFragmentListTitle.add(title);
mFragmentList.add(playlistsFragment);
}
public PlaylistsPagerAdapter(FragmentManager fm) {
super(fm);
}
#NonNull
#Override
public Fragment getItem(int i) {
return mFragmentList.get(i);
}
#Override
public int getCount() {
return mFragmentList.size();
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentListTitle.get(position);
}
}
}
This is the HomeFragmentLayout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.viewpager.widget.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager_home"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_layout_home"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</androidx.viewpager.widget.ViewPager>
This is the PlaylistsFragment:
public class PlaylistsFragment extends Fragment {
private static final String TAG = "PlaylistsFragment";
private ArrayList<String> mPlaylistName = new ArrayList<>();
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_playlists, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initNameBitmap(view);
}
private void initNameBitmap(View view){
mPlaylistName.add("Playlist1");
mPlaylistName.add("Playlist2");
mPlaylistName.add("Playlist3");
mPlaylistName.add("Playlist4");
initRecyclerView(view);
}
private void initRecyclerView(View view){
RecyclerView recyclerView = view.findViewById(R.id.recycler_view_playlists);
RecyclerViewAdapterPlaylists recyclerViewAdapterPlaylists = new RecyclerViewAdapterPlaylists(mPlaylistName, view.getContext(),this);
recyclerView.setAdapter(recyclerViewAdapterPlaylists);
recyclerView.setLayoutManager(new LinearLayoutManager(getView().getContext()));
}
}
This is the PlaylistsFragments Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recycler_view_playlists"
android:layout_margin="10dp" />
</LinearLayout>
The weird thing is that it worked already. I tried around with onBackPressed and when i implemented this and pressed another View on the BottomNavigation than the back button on the phone and than the Home button it showed as intened:
fm.beginTransaction().hide(active).show(fragmentsHistory.get(fragmentsHistory.size()-1));
active = fragmentsHistory.get(fragmentsHistory.size()-1)
fragmentsHistory.remove(fragmentsHistory.size()-1);
What am I doing wrong?
Appreciate the help!
i think the problem is in your layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
tools:context=".ui.plans.PlansFragment">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimaryDark"
app:tabSelectedTextColor="#color/white"
app:tabTextColor="#DBD8D8" />
<androidx.viewpager.widget.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
your HomeFragmentLayout should be similar to this
The Android fragment lifecycle shows that when a fragment is added to the backstack and then removed/replaced, onDestroyView() is called, and later on, when the fragment returns to the layout from the backstack, onCreateView() is called.
From my understanding it means that the fragment's view is being destroyed and recreated. If the user has input text in an EditText in fragment A and goes to fragment B and then back to A, when the fragment comes back the EditText's contents will have been erased.
However, this is not happening in the following code; can anybody explain why? I have already verified that FragmentA's onDestroyView() is being called.
MainActivity.java
public class MainActivity extends FragmentActivity {
private Fragment currentFragment = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
addFragment(new FragmentA());
}
}
public void setCurrentFragment(Fragment fragment) {
this.currentFragment = fragment;
}
#Override
public void onBackPressed() {
if (currentFragment instanceof FragmentB) {
getSupportFragmentManager().popBackStackImmediate();
} else {
super.onBackPressed();
}
}
public void addFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment).addToBackStack(null).commit();
setCurrentFragment(fragment);
}
}
FragmentA.java
public class FragmentA extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_a, container, false);
final EditText editText = (EditText)view.findViewById(R.id.editText);
Button button = (Button)view.findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentB fragmentB = new FragmentB();
Bundle arguments = new Bundle();
arguments.putString("text", editText.getText().toString());
fragmentB.setArguments(arguments);
((MainActivity)getActivity()).addFragment(fragmentB);
}
});
return view;
}
#Override
public void onDestroyView() {
super.onDestroyView();
Log.d("Tag", "FragmentA.onDestroyView() has been called.");
}
}
FragmentB.java
public class FragmentB extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_b, container, false);
TextView textView = (TextView)view.findViewById(R.id.textView);
textView.setText(getArguments().getString("text"));
return view;
}
}
activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.fragmenttest.MainActivity"
tools:ignore="MergeRootFrame" />
fragment_a.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="#+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
fragment_b.xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Fragments in back stack retain their state in a Bundle. This includes the view hierarchy state with the current contents of EditTexts and such.
To destroy The Fragment .. Use This onDestroyView
or in onDetach
if (fragment != null) {
fragment = new YourFragment();
FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
}
The following is layout
test.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Click"
android:id="#+id/button"
/>
<!-- Framelayout to display Fragments -->
<FrameLayout
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
test_detail.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Hello"
android:id="#+id/textView" android:layout_gravity="center_horizontal"/>
</LinearLayout>
common_view_pager_layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="#+id/MainViewerPage"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<android.support.v4.view.PagerTabStrip
android:id="#+id/TitlePageTabStrip"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.v4.view.ViewPager>
</LinearLayout>
The following is my Activity code
public class TestFragmentActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.test);
Button button = (Button) this.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, new HomeFragment()).commit();
}
});
}
public class HomeFragment extends Fragment {
private PagerAdapter _adapter;
public HomeFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.common_view_pager_layout, container, false);
this._adapter = new PagerAdapter(TestFragmentActivity.this);
this._adapter.add(new DetailFragment());
ViewPager pager = (ViewPager) view.findViewById(R.id.MainViewerPage);
pager.setAdapter(this._adapter);
return view;
}
}
public class DetailFragment extends Fragment {
public DetailFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.test_detail, container, false);
return rootView;
}
}
public class PagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> _fragments;
public PagerAdapter(FragmentActivity activity) {
super(activity.getSupportFragmentManager());
this._fragments = new ArrayList<Fragment>();
}
public void add(Fragment fragment) {
this._fragments.add(fragment);
}
#Override
public Fragment getItem(int position) {
return this._fragments.get(position);
}
#Override
public CharSequence getPageTitle(int position) {
return "Test";
}
#Override
public int getCount() {
return 1;
}
}
}
When I click a button the fragment in ViewPager was display
But when I click the button again the fragment disappear
Please help me.
try using this:
in the constructor of your adapter change this :
public class MyPagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> _fragments;
public MyPagerAdapter(FragmentManager activity) {
super(activity);
this._fragments = new ArrayList<Fragment>();
}
public void add(Fragment fragment) {
this._fragments.add(fragment);
}
#Override
public Fragment getItem(int position) {
return this._fragments.get(position);
}
#Override
public CharSequence getPageTitle(int position) {
return "Test";
}
#Override
public int getCount() {
return 1;
}
}
and when you want to create the adapter send getChildFragmentManager() to its constructor
public class HomeFragment extends Fragment {
private MyPagerAdapter _adapter;
public HomeFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.common_view_pager_layout, container, false);
ViewPager pager = (ViewPager) view.findViewById(R.id.MainViewerPage);
this._adapter = new MyPagerAdapter(getChildFragmentManager());
this._adapter.add(new DetailFragment());
pager.setAdapter(this._adapter);
return view;
}
}
I test it and it works, any problem comment it.
Good Luck!
In your Fragment class, in the onCreate() method, you have to call setRetainInstance(true) like this:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
This tells the FragmentManager to keep your fragments on reloads.
In addition, check your manifest file doesn't have any
android:screenOrientation
config changes where you are basically saying you will handle reloads due to config changes yourself.
In PagerFragment 's onResume() add this:
#Override
public void onResume() {
super.onResume();
for (Fragment fragment : getFragmentManager().getFragments()) {
if (fragment instanceof Tab1Fragment || fragment instanceof Tab2Fragment) {
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.detach(fragment);
ft.attach(fragment);
ft.commit();
}
}
}
Try to add this lines in your code:
public int getItemPosition(Object object) {
return POSITION_NONE;
}
and Add the below lines
pager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
... anything you may need to do to handle pager state ...
adapter.notifyDataSetChanged(); //this line will force all pages to be loaded fresh when changing between fragments
}
Under
pager.setAdapter(adapter);
Hope this may help you!
Ensure you pass the adapter instance the child fragment manager, not the fragment manager.
Like this:
this._adapter = new PagerAdapter(getChildFragmentManager());
I have a MainActivity and a Fragment called Frags that itself has a fragment called CardFrontFragment.
I register an OnClickListener on this fragment (the child fragment) and in this OnClickListener's OnClick method I replace this fragment(CardFrontFragment) by CardbackFragment fragment. Also I register an OnClickListener on this fragment(CardbackFragment) too, in order to switch again between this to child fragment.
OnClickListener in first fragment (CardfrontFragment) works and the second fragment is shown but now by clicking on the second fragment nothing happens, OnClickListener does not work with the second fragment, this is killing me, please help me!
Code:
MainActivity.java
public class MainActivity extends ActionBarActivity {
public static Frags frag=new Frags();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, frag)
.commit();
}
}
}
Frags.java
public class Frags extends Fragment{
CardBackFragment back=new CardBackFragment();
CardFrontFragment front=new CardFrontFragment();
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view;
view=inflater.inflate(R.layout.frag_layout, container, false);
getChildFragmentManager().beginTransaction()
.add(R.id.frag_container, back)
.commit();
return view;
}
public void Onflip(boolean iSback)
{
if(iSback)
{
getChildFragmentManager().beginTransaction()
.setCustomAnimations(
R.animator.card_flip_right_in, R.animator.card_flip_right_out,
R.animator.card_flip_right_in, R.animator.card_flip_right_out)
.replace(R.id.frag_container, front)
.commit();
}
else
{
getChildFragmentManager().beginTransaction()
.setCustomAnimations(
R.animator.card_flip_right_in, R.animator.card_flip_right_out,
R.animator.card_flip_right_in, R.animator.card_flip_right_out)
.replace(R.id.frag_container, back)
.commit();
}
}
}
CardFrontFragment
public class CardFrontFragment extends Fragment {
public CardFrontFragment() {
}
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view=inflater.inflate(R.layout.fragment_card_front, container, false);
view.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
MainActivity.frag.Onflip(false);
Log.i("front","onclick");
}
});
return view;
}
}
CardBackFragment
public class CardBackFragment extends Fragment {
public CardBackFragment() {
}
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view=inflater.inflate(R.layout.fragment_card_back, container, false);
view.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
MainActivity.frag.Onflip(false);
Log.i("back","onclick");
}
});
return view;
}
}
xml:
fragment_card_front.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#0000ff" >
<Button
android:id="#+id/front_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
fragment_card_back.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000000" >
<Button
android:id="#+id/back_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
frag_layout.xml
<?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"
android:id="#+id/frag_container">
</LinearLayout>
activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.demokhar.MainActivity"
tools:ignore="MergeRootFrame" />
I am following a fragment example https://gist.github.com/daichan4649/2947119.
I am adding the fragment dynamically after button click event.But the fragment is overlapping with the button. And when I am pressing back key on this screen, activity is closed.
Need help to display only the fragment after button is clicked and if the back is pressed after adding fragment, then only the top fragment should be closed.
Here are my test code.
MainActivity.java
public class MainActivity extends FragmentActivity {
private static Button mBtn;
private static final String TAG_LIST = "list";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
return;
}
mBtn = (Button) findViewById(R.id.clickme);
mBtn.setOnClickListener(new View.OnClickListener() {
#SuppressLint("NewApi")
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Fragment fragment = getFragmentManager().findFragmentByTag(TAG_LIST);
if (fragment == null) {
fragment = TestListFragment.newInstance();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(android.R.id.content, fragment, TAG_LIST);
ft.commit();
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
TestListFragment.java
public class TestListFragment extends ListFragment {
public static TestListFragment newInstance() {
return new TestListFragment();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
ViewGroup rootView = (ViewGroup) inflater.inflate(android.R.id.content, container, false);
return rootView;
}
#SuppressLint("NewApi")
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), R.layout.list_column, R.id.text);
setListAdapter(adapter);
adapter.addAll(createDataList(10));
}
private static List<String> createDataList(int counts) {
List<String> list = new ArrayList<String>();
for (int i = 0; i < counts; i++) {
list.add("i=" + i);
}
return list;
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
//Toast.makeText(getActivity(), "List Item Clicked", Toast.LENGTH_SHORT).show();
//On item click, launch the DialogFragment
TestDialogFragment moveFragment = new TestDialogFragment( );
moveFragment.show(getFragmentManager(), "Test List Fragment");
}
TestDilogFragment.java
public class TestDialogFragment extends DialogFragment {
private View testDialogFragment = null;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Fill the layout as per Your requirement
testDialogFragment = inflater.inflate(R.layout.activity_list_fragment, container);
return testDialogFragment;
}
}
activity-main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/clickme"
android:text="ClickMe" />
</RelativeLayout>
activity_list_fragment.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
</RelativeLayout>
Change your activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parentt" >
<Button
android:id="#+id/clickme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="Button" />
<FrameLayout
android:id="#+id/container"
android:layout_above="#id/clickme"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
>
</FrameLayout>
</RelativeLayout>
You have a Button at the bottom and a ViewGroup which is a FrameLayout at the top. You add the Fragment to the container.
And in ManiActivtiy change to
ft.add(R.id.container, fragment, TAG_LIST);