android: fragment or contextual layout in Navigation Drawer - android

The question says it all.
I dont know if fragments can be included inside Navigation Drawer or not.
I am more interested to make contextual layout.
The Navigation drawer in Google play and YouTube app is not just a simple drawer.

I dont know if fragments can be included inside Navigation Drawer or not
Yes, they can be integrated just as in any valid part of the layout. Just put in the drawer a ViewGroup (FrameLayout, LinearLayout, etc) and instruct the FragmentManager to put a fragment in that view group by giving the layout id in add or replace method.
I am not sure what you mean by Contextual Layout, but I've checked the Google Play and Youtube apps and in their drawer layout it doesn't look impossible to have fragments inside.
EDIT: Below is some basic example with a drawer having a fragment. I guess you know about this developer article with how to customize the drawer in conjunction with the action bar.
drawer_main.xml:
<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" />
<!-- The navigation drawer -->
<FrameLayout
android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start" />
</android.support.v4.widget.DrawerLayout>
MainActivity.java:
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drawer_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.left_drawer, getDrawerFragment()).commit();
}
}
private Fragment getDrawerFragment() {
return new DrawerFragment();
}
}
DrawerFragment.java:
public class DrawerFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.drawer_fragment_layout, container, false);
}
public void onViewCreated(View view, Bundle savedInstanceState) {
ListView listView = (ListView) view.findViewById(R.id.main_list_view);
listView.setAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, new String[] {
"Adam", "Diana", "John"
}));
}
}
fragment's layout drawer_fragment_layout.xml:
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_list_view"
android:background="#ffffff"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Makes sense?

You can use fragment or just a layout. Navigation drawer has to child layout. First one is main, second is drawer. These two child layout can be just a layout or a fragment like youtube ext. You can find all basic information in here.

Related

Navigation drawer in multiple activities

I know this question has been asked multiple times. But my concern is different.
Using Mr. Tamada Tutorial I've created a NavigaionActivity and multiple fragments to replace in FrameLayout. It's working fine.
Now, after selecting any option in a fragment, another activity gets open.
I want the same Navigation menu in that Activity.
Navigation view -- fragments -- Activity (display navigation view here)
What I tried:
use the xml code of displaying Navigation view in that activity.
(DrawerLayout, CoordinatorLayout, AppBarLayout etc)
Then in Activity.java, on click of menu item diverting to the Navigation Activity.
Code:
XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
....>
<android.support.design.widget.CoordinatorLayout
....>
<android.support.design.widget.AppBarLayout
....>
<android.support.v7.widget.Toolbar
.... />
</android.support.design.widget.AppBarLayout>
<LinearLayout
.... /> <!-- main content of this Acitivity-->
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
.... />
</android.support.v4.widget.DrawerLayout>
Activity.java:
public void dashboard(MenuItem item) {
Bundle bundle = new Bundle();
bundle.putString("fragment", Constant.DASHBOARD_FRAGMENT);
UtilityClass.newActivity(this, NavigationActivity.class, bundle);
}
And handling the call on Navigation Activity. It is doing the task but code isn't re-usable
Create a separate layout file for Navigation and include it in the Activity. But, this is replacing the main content. Here only included Navigation is visible.
Is there any other way to do it?
Downvoters - here the solution is..
Create an xml file which will have DrawerLayout and NavigationView (one can use the xml given in Question, without the main content) - navigation.xml
As suggested in many answers "create a BaseActivity which extends AppCompatActivity. And inflate navigation.xml.
public class BaseActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = View.inflate(this, R.layout.navigation, null);
// view declarations
DrawerLayout drawer = (DrawerLayout) view.findViewById(R.id.drawer_layout);
NavigationView navigationView = (NavigationView) view.findViewById(R.id.nav_view);
...... }}
In whichever Activity you wanna use this NavigationMenu, extend BaseActivity for that class.
GraphActivity extends BaseActivity { .... }
In GraphActivity.xml add the NavigationMenu code. You can't just include the navigation.xml it will disable the current xml widgets.
Done!
Try this:
public class MainActivity extends BaseActivity{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_describtion);
getLayoutInflater().inflate(R.layout.activity_main, frameLayout);
mDrawerList.setItemChecked(position, true);
}
Plz Don't use it this way
Instead use Google recommended MasterDetailFlow Design
You can read how to implement this on
https://inducesmile.com/android/android-fragment-masterdetail-flow-tutorial-in-android-studio/

Android- FragmentTransaction.replace() works only once

I'm using a navigation drawer along with a SwipeRefreshLayout for the main content and when the user selects a menu item in the navigation drawer, I want to replace the fragment inside the SwipeRefreshLayout with another fragment.
This is what my onNavigationItemSelected() looks like:
// Handle navigation view item clicks here.
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
selectedNavItem = item.getItemId();
if(selectedNavItem == R.id.nav_files){
filesFragment = new FilesFragment();
fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(R.id.swipeLayout,filesFragment,"files");
transaction.commit();
} else if(selectedNavItem == R.id.nav_accounts){
accountsFragment = new AccountsFragment();
fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(R.id.swipeLayout,accountsFragment,"accounts");
transaction.commit();
}
return true;
But this never works. When I click an item in the nav drawer, the fragment is replaced by a blank screen. My onCreate method also uses FragmentTransaction.replace() but that seems to work fine.
I also tried FragmentTransaction.remove() and then FragmentTransaction.add() but even that doesn't seem to work.
Edit: Layout files:
Layout of the content view of the navigation drawer:
<android.support.v4.widget.SwipeRefreshLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.harshallele.cloudpool.MainActivity"
tools:showIn="#layout/app_bar_main"
android:id="#+id/swipeLayout">
</android.support.v4.widget.SwipeRefreshLayout>
This is included inside another layout file which contains a CoordinatorLayout containing the toolbar.That file, in turn, is inside the main layout file of the activity inside a android.support.v4.widget.DrawerLayout
(Basically, this is the Navigation Drawer Activity provided by Android Studio when adding an Activity)
Layout for FilesFragment:
<FrameLayout 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"
tools:context=".fragments.FilesFragment">
<android.support.v7.widget.RecyclerView
android:id="#+id/fileListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
/>
<ProgressBar
android:id="#+id/itemsLoadingProgress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
style="?android:attr/progressBarStyleHorizontal"
android:indeterminateOnly="true"
android:visibility="invisible"
/>
</FrameLayout>
Layout for AccountsFragment(this is just the default blank fragment, because i haven't finished this yet):
<FrameLayout 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"
tools:context="com.harshallele.cloudpool.fragments.AccountsFragment">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment" />
</FrameLayout>
Edit 2:
AccountsFragment:
public class AccountsFragment extends Fragment {
public AccountsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_accounts, container, false);
}
}
With just this bit of code we can't help you so much. The problem can be that:
The FilesFragment and AccountsFragment aren't initialized in the right way;
The Layout with id swipeLayout can have visibility = gone;
The Layout of FilesFragment and AccountsFragment can be empty;
This are just some of the infinite reason why your code doesn't work properly so please share more code about the two Fragments and relative XML.

How to show a custom actionbar view from one fragment only

I have a requirement for my app that a custom action bar view be shown from one fragment only (the landing page fragment). The problem is that this action bar is appearing when the user navigates to other fragments. Is there a way to do this without disabling custom view on every fragment?
Thanks
For this issue, only show actionbar for one fragment without show on all other fragments, solution could be very easy:
In your activity that hosts your fragments:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
... ...
// for API >= 11
getActionBar.hide();
// for API < 11
getSupportActionBar().hide();
... ...
}
Then in the fragment that you want to show actionbar:
#Override
public void onAttach(Activity activity){
activity.getActionBar().show(); //getSupportActionBar() for API<11
}
#Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (hidden) {
getActivity().getActionBar().hide(); //getSupportActionBar() for API<11
} else {
getActivity().getActionBar().show(); //getSupportActionBar() for API<11
}
}
Well, I'm just trying to suggest. Why not removing the action bar to all the fragments and just creating a single fragment (the landing page) with a custom action bar thru layout?
To remove ActionBar to all fragments, add this code to tag:
android:theme="#android:style/Theme.Light.NoTitleBar"
Create a Layout with action bar for your landing page through xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/rlMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" >
<RelativeLayout
android:id="#+id/rlHeaderMain"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentTop="true"
android:background="#000000"
android:clipChildren="false"
android:clipToPadding="false"
android:padding="5dp" >
</RelativeLayout>

Android Navigation Drawer (calling activities) with AbstractMainActivity

I want to have a AbstractMainActivity which creates the Navigation Drawer. In there I should also handle the clicks on the menu items and then call new activities. In those activities, I want to again use the same Navigation Drawer.
I would extend in the Subclasses with the AbstractMainActivity and call the getLayoutResourceID differently from each subclass (as suggested here: android how to create my own Activity and extend it?).
The problem is, that now in the AbstractMainActivity where I want to build the Navigation Drawer, I do not have any access to the navigation drawer layout (xml) element, as I of course want to have a different base layout for the subclasses.
Would I need to "include layout" in all the subclasses layout files? But this does not work, what do I do wrong if I want to use Activities instead of Fragments with the Navigation Drawer?
public abstract class MainActivity extends Activity {
private String[] menuItems;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
setContentView(getLayoutResourceId());
menuItems = getResources().getStringArray(R.array.menu_items);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
// Set the adapter for the list view
mDrawerList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, menuItems));
// Set the list's click listener
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
}
protected abstract int getLayoutResourceId();
#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;
}
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
selectItem(position);
}
/** Swaps fragments in the main content view */
private void selectItem(int position) {
//Fragment fragment = new PlanetFragment();
Bundle args = new Bundle();
// args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
Intent intent = new Intent(MainActivity.this, ProductListActivity.class);
startActivity(intent);
}
}
public class ProductListActivity extends MainActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.options_menu, menu);
return true;
}
#Override
protected int getLayoutResourceId() {
// TODO Auto-generated method stub
return R.layout.activity_product_list;
}
This is the layout of the product list sub-class (activity_product_list.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=".ProductList" >
<include layout="#layout/activity_main"/>
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" >
</ListView>
This is the layout of the navigation drawer (activity_main.xml):
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android1="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="300dp"
android:layout_height="500dp" >
<!-- The main content view -->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- 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="#c3c3c3"/>
But the does not work, but if I do not have it, I get null-pointer exceptions when my subclass calls the onCreate of the abstract class, where I want to build the Navigation Drawer, it does not find the layout-elements to set the lists and layout (R.id.left_drawer or R.id.drawer_layout)!
I'm also trying to figure out how to do this.
I've seen a very good tutorial that does exactly what you want here.
The idea is to create an abstract activity class AbstractNavDrawerActivity that all activities with drawers will inherit from. This class uses a NavDrawerActivityConfiguration bean class that holds all the information about the nav drawer including the layout that needs to be inflated
Another approach would be creating a NavDrawerUtil class where you would put static methods that interact with the nav drawer. You would then call these methods from each activity as you need.
The second approach gives you more flexibility and you don't have to worry about order of layout inflations and such but I think it's a less clean solution than the first one with the AbstractNavDrawerActivity that all activities with nav drawer inherit from like you suggested.
What I've done in previous apps is have a sliding menu built as a function call in the abstract activity. When you set up a new Activity extending the abstract activity, you perform the function call in the onCreate(). I'm currently working on a similar implementation using the Navigation Drawer instead, so I'm not quite sure if it works yet, but it might be a good place for you to start. All your Activities that will call the Navigation Drawer will need to have a DrawerLayout as the top-level layout element.

ActionbarSherlock Fragment in Fragment

I don't know it's a problem of my application structure or a problem with my code.
I have a tabActivity which extends SherlockFragmentActivity.
This has a ViewPager and a TabsAdapter.
There are two Tabs and one OptionsMenu item ("search").
The two tabs are for entering search parameters. One simple, one detaild. If search is clicked, a search is performed and the results shall be shown.
The content of the tabs are already objects of the type SherlockFragment. So far, this works fine.
At the moment, the search results are a seperate activity. I would like to have them in the viewpager as well. So I converted it to a SherlockActivity. But if I make ("this" is the tabActivity) in the onCreate() Method:
FragmentManager fm = this.getSupportFragmentManager();
Fragment ft = Fragment.instantiate(this, searchFragment.class.getName(), null);
if(fm.findFragmentById(R.id.searchresults_content) == null)
{
fm.beginTransaction().add(R.id.searchresults_content, ft).commit();
}
and then:
this.mViewPager.addView(ft.getView());
but ft.getView(); returns null. OnCreateView from searchFragment will do this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
WebView mWebView = (WebView)findViewById(R.id.search_results);
View mView = inflater.inflate(R.layout.search_results, container, false);
mWebView.setWebViewClient(new SearchResultsWebViewClient());
//... (load data for webview etc...)
return mView;
}
search_results.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id ="#+id/search_results"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</WebView>
</LinearLayout>

Categories

Resources