I've been looking for similar questions here on Stack Overflow, but with no luck. I have my first activity, MapsActivity. I want my second activity, AboutActivity, to appear in the FrameLayout of the MapsActivity layout, so I used LayoutInflater. When I run the app, I see my AboutActivity for about half a second, then it quickly changes back to the MapActivity. I don't have any errors on logcat and both activities are listed in the Manifest file.
Here is my MapsActivity (with just the relevant parts). My Google Map is inside the fragment (where I hope my second activity will appear). I have a menu button, and one of the buttons leads to the second activity.:
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private String[] menuOptions;
private DrawerLayout myDrawerLayout;
private ListView myList;
// private Fragment menuFragment;
private MapFragment mMapFragment;
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
if (findViewById(R.id.content_frame)!=null){
if (savedInstanceState!=null){
return;
}
// to add fragment dynamically, create new instance- add to frame layout
mMapFragment= MapFragment.newInstance();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.content_frame, mMapFragment);
fragmentTransaction.commit();
//make menu from array indices
menuOptions = getResources().getStringArray(R.array.menu_array);
myDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
myList= (ListView)findViewById(R.id.left_drawer);
//adapter for list view
myList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, menuOptions));
//list's click listener
myList.setOnItemClickListener(new DrawerItemClickListener());
Button menuButton = (Button) findViewById(R.id.menuButton);
menuButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
myDrawerLayout.openDrawer(Gravity.LEFT);
}
});
...
private void selectItem(int position){
switch(position) {
case 0:
//Highlight selected item
myList.setItemChecked(position, true);
myDrawerLayout.closeDrawer(myList);
break;
case 1:
//about
Intent switchIntent = new Intent(getApplicationContext(), AboutActivity.class);
startActivity(switchIntent);
break;
Here is my AboutActivity, the second activity. The activity_about only appears for one second. I want it to appear where the map was.
public class AboutActivity extends MapsActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_about);
FrameLayout frame = (FrameLayout) findViewById(R.id.content_frame);
getLayoutInflater().inflate(R.layout.activity_about, frame);
}
Here is my activity_maps.xml, it features a map and a FrameLayout where I want my other activities to appear (this way I can also have the ListView menu in each activity):
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="#+id/menuButton"
android:layout_width="100dp"
android:layout_height="50dp"
android:text="Menu" />
</FrameLayout>
<!-- The navigation drawer -->
<ListView android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#111">
</ListView>
</android.support.v4.widget.DrawerLayout>
If you want your Button and ListView in both activities, why not use AboutFragment instead of AboutActivity. And when you click the aboutButton in ListView, just replace the fragment shows in the FrameLayout.You have to let you menuButton outside the FrameLayout.
activity_xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->
<LinearLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp" />
<Button
android:id="#+id/menuButton"
android:layout_width="100dp"
android:layout_height="50dp"
android:text="Menu" />
</LinearLayout>
<!-- The navigation drawer -->
<ListView android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#111">
</ListView>
</android.support.v4.widget.DrawerLayout>
public class AboutActivity extends FragmentActivity, and try to use fragments.
In "main" layout create one:
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="#+id/menuButton"
android:layout_width="100dp"
android:layout_height="50dp"
android:text="Menu" />
</FrameLayout>
in mainActivity inflate your fragment created into frameLayout.
Related
I need my app to have bottom bar navigation and swipable tabs. so I need viewpager to swap between fragments nested inside each fragment that is used by the bottom navigation. how do I do this?
First, you create a Fragment that contains ViewPager and TabLayout like this
<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"
tools:context=".FragmentThatHasViewPagerAndTabLayout">
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
Then create a Activity which includes FrameLayout (that will be used as fragment container) and BottomNavigation
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#color/colorPrimary"
app:itemIconTint="#FFF"
app:itemTextColor="#FFF"
app:menu="#menu/menu_bottom_navigation"/>
</LinearLayout>
Snippet code for Activity
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation_view);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
//Change fragment when select another item in BottomNavigation
}
}
getFragmentManager().beginTransaction().replace(R.id.fragment_container, new FragmentThatHasViewPagerAndTabLayout(), "TAG_TO_REUSE_FRAGMENT_AFTER_CONFIG_CHANGES").commit();
}
And code in Fragment that contains ViewPager and TabLayout, you just write it like normally do (like having a FragmentPagerAdapter, etc.)
I have a DrawerLayout component in my activity, but I'm not using ActionBar.
This is my main_activity.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white">
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="#+id/mainContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
<ListView
android:id="#+id/drawer"
android:layout_width="650dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#android:color/white"
android:divider="#null"
android:choiceMode="singleChoice"
android:visibility="gone"/>
</android.support.v4.widget.DrawerLayout>
<ImageButton
android:id="#+id/categories_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_margin="20dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:background="#drawable/button_category"/>
In my MainActivity I try to open/close the DrawerLayout by clicking on my Button.
Here is my Activity:
public class MainActivity extends Activity {
private ImageButton categoriesButton;
private DrawerLayout drawerLayout;
private ListView drawerMenu;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
categoriesButton = (ImageButton)findViewById(R.id.categories_button);
categoriesButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(drawerLayout.isDrawerOpen(drawerMenu)) {
drawerLayout.closeDrawer(drawerMenu);
}else {
drawerLayout.openDrawer(drawerMenu);
}
}
});
drawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
drawerMenu = (ListView) findViewById(R.id.drawer);
MyAdapter myAdapter = new MyAdapter(context, getCategories());
drawerMenu.setAdapter(myAdapter);
}
}
When I click the Button the first time it does not respond, but after I open the DrawerLayout manually it works perfect.
Does anybody know what is wrong here?
Thanks!
I found the solution! In the xml, the Listview visibility needs to be set to visible. It was set to gone (I took this code from the oficial documentation).
<ListView
android:id="#+id/drawer"
android:layout_width="650dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#android:color/white"
android:divider="#null"
android:choiceMode="singleChoice"
android:visibility="visible"/>
Anyway now it works. Thanks for your help!
I followed http://android-developers.blogspot.de/2014/10/appcompat-v21-material-design-for-pre.html to use the toolbar, without fragment, it works perfectly, but when I use fragment, the fragment always overlays the content, and I cannot see toolbar when displaying fragment.
screen:
and when I starts another activity from the current one, the icon of the toolbar in the new activity doesn't show up. screen:
I use Android Support Library 21.0.3.
and the code in the MainActivity class:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
mLeftDrawerList = (ListView) findViewById(R.id.left_drawer);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
mNavigationDrawerAdapter=new ArrayAdapter<String>( MyActivity.this, android.R.layout.simple_list_item_1, data);
mLeftDrawerList.setAdapter(mNavigationDrawerAdapter);
if (mToolbar != null) {
mToolbar.setTitle("Home");
setSupportActionBar(mToolbar);
}
initDrawer();
final FragmentManager fragementMgr = getSupportFragmentManager();
FragmentTransaction transaction = fragementMgr.beginTransaction();
transaction.add(R.id.fragment_container, new MyFragment());
transaction.commit();
}
the layout xml:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity"
android:layout_width="match_parent"
android:id="#+id/drawerLayout"
android:layout_height="match_parent">
<!-- activity view -->
<LinearLayout
android:layout_width="match_parent"
android:background="#fff"
android:layout_height="match_parent">
<include layout="#layout/toolbar" />
<FrameLayout android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<!-- navigation drawer -->
<RelativeLayout
android:layout_gravity="left|start"
android:layout_width="match_parent"
android:background="#fff"
android:layout_height="match_parent">
<ListView
android:id="#+id/left_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#eee"
android:background="#fff"
android:dividerHeight="1dp" />
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
code in MyFragment:
public class MyFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, container, false);
final Button button = (Button) view.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
Intent intent = new Intent(getActivity(), DetailActivity.class);
startActivity(intent);
}
});
// Inflate the layout for this fragment
return view;
}
}
layout xml for Fragment:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello_fragment"
android:textStyle="bold"
android:gravity="center"
android:layout_gravity="top"
android:textSize="18sp"
android:id="#+id/text"/>
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_below="#+id/text"
android:text="#string/open"
android:id="#+id/button"/>
</RelativeLayout>
The code in DetailActivity class:
public class DetailActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.detail_activity);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("Detail");
setSupportActionBar(toolbar);
}
}
layout for the detail activity:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context=".DetailActivity">
<include layout="#layout/toolbar" />
<TextView
android:layout_width="wrap_content"
android:textColor="#000"
android:text="Detail Activity Content"
android:layout_height="wrap_content" />
</LinearLayout>
can anyone help me out? thanks a lot!
Update: I updated the code and layout of the main activity according to reply from m iav.
new screen is blank now with the changes:
toolbar is a view in your layout , you can see it like textview ,now it is a textview overlay your fragment ,you use attrbibu to below it
so finally after checking the sample: MaterialEverywhere, I came with the solution with updating the layout:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity"
android:layout_width="match_parent"
android:id="#+id/drawerLayout"
android:layout_height="match_parent">
<!-- activity view -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar" />
<FrameLayout android:id="#+id/fragment_container"
android:layout_below="#id/toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
<!-- navigation drawer -->
<RelativeLayout
android:layout_gravity="left|start"
android:layout_width="match_parent"
android:background="#fff"
android:layout_height="match_parent">
<ListView
android:id="#+id/left_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#eee"
android:background="#fff"
android:dividerHeight="1dp" />
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
the trick is the parent layout of the toolbar and the content frame. Instead of LinearLayout, I use RelativeLayout. and it works now as expected.
anyway, I found such change from the SDK is over complex, with so many changes, and each can cause issues. It will be much better for the developers to have clean APIs with less all these tweaks.
This should be your main layout.
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity"
android:layout_width="match_parent"
android:id="#+id/drawerLayout"
android:layout_height="match_parent">
<!-- activity view -->
<LinearLayout
android:layout_width="match_parent"
android:background="#fff"
android:layout_height="match_parent">
<include layout="#layout/toolbar" />
<FrameLayout android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<!-- navigation drawer -->
<RelativeLayout
android:layout_gravity="left|start"
android:layout_width="match_parent"
android:background="#fff"
android:layout_height="match_parent">
<ListView
android:id="#+id/left_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#eee"
android:background="#fff"
android:dividerHeight="1dp" />
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
And this should be your call to the new fragment:
transaction.add(R.id.fragment_container, new MyFragment())
transaction.commit();
Regarding your second question, a navigation drawer can't be shared among different activities. You have to use a new Fragment and keep the same Activity you're working in now.
I use an ActionBarActivity with NavigationDrawer and a ListView in the content frame of Drawer.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/lyt_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:orientation="horizontal" >
<ListView
android:id="#+id/list_notes"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight="1" >
</ListView>
</LinearLayout>
</FrameLayout>
<FrameLayout
android:id="#+id/drawer_frame"
android:layout_width="240dp"
android:layout_height="fill_parent"
android:layout_gravity="start"
android:layout_weight="1" >
<ListView
android:id="#+id/left_drawer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#color/darkGray"
android:choiceMode="singleChoice"/>
</FrameLayout>
I open PreferenceFragment from one of Drawer items like this:
FragmentTransaction transaction = getFragmentManager().beginTransaction();
PrefsFragment prefs = new PrefsFragment();
transaction.add(R.id.content_frame, prefs);
transaction.addToBackStack(null);
transaction.commit();
and this is my PrefsFragment:
public class PrefsFragment extends Fragment {
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getActivity().getFragmentManager().beginTransaction()
.replace(R.id.content_frame, new PrefsFr())
.commit();
}
public class PrefsFr extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
... }
}
}
but I can not remove this fragment.
When I toggle to another Drawer item; PreferenceFragment remains on top of ListView in content_frame with tranceparent background.
Is it possible in ActionBarActivity to remove a fragment without replacing it by another fragment ?
If not so how to use PreferenceFragment for api > 11 ? Is it true that the only way is to replace fragments with each other?
Is it possible in ActionBarActivity to remove a fragment without replacing it by another fragment ?
Yes, you can use FragmentTransaction#remove(Fragment)
The underlying problem however is that you are showing the PreferenceFragment with transaction.add(R.id.content_frame, prefs);. If you want only the PreferenceFragment to display wihthout the ListView behind it, you should use replace() instead.
In android I am trying to move more activities into one (refactor code and I try to replace set of activities with fragments), but I need only one fragment to be visible at time.
How on click button in activity which has this xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="#+id/fragment_container"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:orientation="vertical" >
<fragment
android:id="#+id/lm_fragment"
android:name="com.example.loyalty.MerchantsActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2"
/>
<fragment
android:id="#+id/pm_fragment"
android:name="com.example.loyalty.RewardsActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2" />
<com.touchmenotapps.widget.radialmenu.semicircularmenu.SemiCircularRadialMenu
android:id="#+id/radial_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:padding="0dp" />
</RelativeLayout>
to make that on click change which fragment is visible (only one is visible and use whole screen)
If you are trying to show one fragment at a time and also want many fragment to change, you have to create fragment dynamically in activity on a view click. use a xml like this one.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- This will hold your fragment's view-->
<FrameLayout
android:id="#+id/fragment_layout"
android:layout_width="match_parent"
android:background="#android:color/white"
android:layout_height="0dp"
android:layout_weight="1" />
<!-- This part will be your activity specific -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal" >
<Button
android:id="#+id/open_fragmen1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:id="#+id/open_fragmen2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>
Here FrameLayout will be replaced with your Fragment that you want to show on Activity at that time, on Button click you can make this transition.
In activity to change the Fragment you have to write the following code.
public class MenuActivity extends Activity {
private Button btn1, btn2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
btn1 = (ImageButton) findViewById(R.id.open_fragment1);
btn2 = (ImageButton) findViewById(R.id.open_fragment2);
btn1.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
// I am assuming your fragment class is MerchantsActivity
changeFragmentTo(new com.example.loyalty.MerchantsActivity());
}
});
btn2.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
changeFragmentTo(new com.example.loyalty.RewardsActivity());
}
});
}
public void changeFragmentTo(Fragment fragment) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.menu_fragment, fragment).commit();
}
}
If you need to change another fragment to activity call the function changeFragmnetTo(new NewFragment())