Chathuranga Wijesingha
Tuesday, April 7, 2015
Monday, April 6, 2015
Tuesday, September 23, 2014
Capture ScreenShot in C# winform Application
All we need to do is pass the screen area to the
The
Each of the methods erases the previous rectangle and to creates a new rectangle every time the mouse is moved (while the left mouse button is held down). This gives the illusion of a rectangle moving.
This is where the code applies all the selected options - include/exclude cursor, save to clipboard/file and type of file the image is saved to.
The addition of the cursor can be particularly useful if you need to point something out in a screenshot such as a button.
To include the cursor in the image, the application's
I have added this event to each button on the application - a more efficient way to do this would be to handle any keys that are pressed while the application is open - the reason I have chosen this method is so that the software is not flagged as key logging by security software.
ScreenShot.CaptureImage
method. The only thing to note here is that we pause for 250
milliseconds to allow the screen to repaint itself. Not doing this can
cause the form, from which the command was invoked, to be included in
the capture even though it has been instructed to minimize.//Allow 250 milliseconds for the screen to repaint itself
//(we don't want to include this form in the capture)
System.Threading.Thread.Sleep(250);
Rectangle bounds = Screen.GetBounds(Screen.GetBounds(Point.Empty));
string fi = "";
if (ScreenPath != "")
{
fi = new FileInfo(ScreenPath).Extension;
}
ScreenShot.CaptureImage(showCursor, curSize, curPos,
Point.Empty, Point.Empty, bounds, ScreenPath, fi);
Capture Area
Holding down the left mouse button, the user draws a rectangle specifying which part of the screen they wish to capture. On releasing the left mouse button, the user can re-size or move the selection area or they can double click to select a file name - what is behind the drawn rectangle is then captured to this selected file.The
mouse_Move
event is used to decide on whether the user is drawing, dragging(moving) or resizing the selection area. Each of the methods erases the previous rectangle and to creates a new rectangle every time the mouse is moved (while the left mouse button is held down). This gives the illusion of a rectangle moving.
private void mouse_Move(object sender, MouseEventArgs e)
{
if (LeftButtonDown && !RectangleDrawn)
{
DrawSelection();
}
if (RectangleDrawn)
{
CursorPosition();
if (CurrentAction == ClickAction.Dragging)
{
DragSelection();
}
if (CurrentAction != ClickAction.Dragging && CurrentAction != ClickAction.Outside)
{
ResizeSelection();
}
}
}
Here is how we call ScreenShot.CaptureImage
for Capture Area.Point StartPoint = new Point(CurrentTopLeft.X, CurrentTopLeft.Y);
Rectangle bounds = new Rectangle(CurrentTopLeft.X, CurrentTopLeft.Y,
CurrentBottomRight.X - CurrentTopLeft.X, CurrentBottomRight.Y - CurrentTopLeft.Y);
...
ScreenShot.CaptureImage(showCursor, curSize, curPos, StartPoint,
Point.Empty, bounds, ScreenPath, fi);
The code that captures the screen is in a class called ScreenShot
which contains a static
method called CaptureImage
.This is where the code applies all the selected options - include/exclude cursor, save to clipboard/file and type of file the image is saved to.
class ScreenShot
{
public static bool saveToClipboard = false;
public static void CaptureImage(bool showCursor, Size curSize, Point curPos,
Point SourcePoint, Point DestinationPoint, Rectangle SelectionRectangle,
string FilePath, string extension)
{
using (Bitmap bitmap = new Bitmap(SelectionRectangle.Width,
SelectionRectangle.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(SourcePoint, DestinationPoint,
SelectionRectangle.Size);
if (showCursor)
{
Rectangle cursorBounds = new Rectangle(curPos, curSize);
Cursors.Default.Draw(g, cursorBounds);
}
}
if (saveToClipboard)
{
Image img = (Image)bitmap;
Clipboard.SetImage(img);
}
else
{
switch (extension)
{
case ".bmp":
bitmap.Save(FilePath, ImageFormat.Bmp);
break;
case ".jpg":
bitmap.Save(FilePath, ImageFormat.Jpeg);
break;
case ".gif":
bitmap.Save(FilePath, ImageFormat.Gif);
break;
case ".tiff":
bitmap.Save(FilePath, ImageFormat.Tiff);
break;
case ".png":
bitmap.Save(FilePath, ImageFormat.Png);
break;
default:
bitmap.Save(FilePath, ImageFormat.Jpeg);
break;
}
}
}
}
Two methods that have been added recently (January 2012) are Clipboard.SetImage
and Cursors.Default.Draw
.
The first method will copy the screen or area captured to the clipboard
and the second method includes the cursor (as an arrow) in the image. The addition of the cursor can be particularly useful if you need to point something out in a screenshot such as a button.
To include the cursor in the image, the application's
KeyUp
events listen for the 'S' key - this then triggers the ScreenCapture
method specifying the inclusion of the cursor. I have added this event to each button on the application - a more efficient way to do this would be to handle any keys that are pressed while the application is open - the reason I have chosen this method is so that the software is not flagged as key logging by security software.
private void keyTest(KeyEventArgs e)
{
if (e.KeyCode.ToString() == "S")
{
screenCapture(true);
}
}
Monday, September 22, 2014
Add a Ribbon panal into a Windows Forms Application (C#)
Reminder: Please note that this ribbon does not work on .Net 3.5 Client Profile and .NET 4.0 Client Profile. You have to switch the target framework to .NET 3.5 or .NET 4.0. When you first create a project, Visual Studio might initially set the target framework to Client Profile.

If the project is using Client Profile, you might receive this error while you are trying to build the solution:
1. Get System.Windows.Forms.Ribbon35.dll from download.
2. Create a blank WinForms project.

3. Add Ribbon into Visual Studio Toolbox.
Right Click on Toolbox > Add Tab.

Give the new tab a name "Ribbon".

Right Click on the New Tab [Ribbon] > Choose Items...

[Browse...] Where are you? System.Windows.Forms.Ribbon35.dl?

There you are... Gotcha... Select it...

Only [Ribbon] can be dragged into Form. Others, as the picture below said, they are not needed to exist in toolbox. However, its not going to harm your computer or project if you select all the items belongs to ribbon (by default). Its up to you.

And finally, what you're going to do is just...

Another Way
Manually code it behind.
You can add the ribbon into WinForm too with code behind.
Add a reference of System.Windows.Forms.Ribbon35.dll into your project. Build the the solution.
Open the designer of Main Form. In this example, Form1.Designer.cs.

Add these three lines of code
Save and Close
Double click and open

Lets continue...

4. Click on the Ribbon and click Add Tab.

5. Click on the newly added

6. Click on the newly added

You might not able to see the extra command links of "Add Button", "Add ButtonList", "Add ItemGroup"... etc at the Properties Explorer.

Right click at the Properties Explorer and Tick/Check the [

7. Try to add some buttons into the
8. Click on the
9. Let's try to change the image and the label text of the button.

10. This is how your ribbon looks like now.
11. Now, create the click event for the buttons. Click on

12. Click on the RibbonButton, go to properties > Click on Events > Double Click on event of

13. Events created.

15. You might want to inherit your Main Form into a
Note: Inherit the Main Form to This problem is solved in released version 10 May 2013.

16. In the code for

The following guide will show how to apply this ribbon with an MDI (Multi Document Interface) enabled WinForm.
Note: In previous version of Ribbon, inheritance of RibbonForm is not supported well with MDI Enabled WinForm. This problem is solved in released version of 10 May 2013.

2. Create another simple another form that will be loaded into the MDI Container of

3. At code behind of
Note: In previous version of Ribbon, inheritance of RibbonForm is not supported well with MDI Enabled WinForm. This problem is solved in released version of 10 May 2013.

If the project is using Client Profile, you might receive this error while you are trying to build the solution:
Error 3 The type or namespace name 'Ribbon' does not exist in the namespace 'System.Windows.Forms' (are you missing an assembly reference?)
1. Get System.Windows.Forms.Ribbon35.dll from download.
2. Create a blank WinForms project.

3. Add Ribbon into Visual Studio Toolbox.
Right Click on Toolbox > Add Tab.

Give the new tab a name "Ribbon".

Right Click on the New Tab [Ribbon] > Choose Items...

[Browse...] Where are you? System.Windows.Forms.Ribbon35.dl?

There you are... Gotcha... Select it...

Only [Ribbon] can be dragged into Form. Others, as the picture below said, they are not needed to exist in toolbox. However, its not going to harm your computer or project if you select all the items belongs to ribbon (by default). Its up to you.

And finally, what you're going to do is just...

Another Way
Manually code it behind.
You can add the ribbon into WinForm too with code behind.
Add a reference of System.Windows.Forms.Ribbon35.dll into your project. Build the the solution.
Open the designer of Main Form. In this example, Form1.Designer.cs.

Add these three lines of code
private System.Windows.Forms.Ribbon ribbon1; ribbon1 = new System.Windows.Forms.Ribbon(); this.Controls.Add(ribbon1);into
Form1.Designer.cs
private void InitializeComponent()
{
ribbon1 = new System.Windows.Forms.Ribbon();
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Text = "Form1";
this.Controls.Add(ribbon1);
}
private System.Windows.Forms.Ribbon ribbon1;
Save and Close
Form1.Designer.cs
. Double click and open
Form1.cs
, and now the Ribbon control is added into the main form.
Lets continue...

4. Click on the Ribbon and click Add Tab.

5. Click on the newly added
RibbonTab
, then click Add Panel
.
6. Click on the newly added
RibbonPanel
, go to Properties. You will see a set of available controls that can be added to the RibbonPanel
.
You might not able to see the extra command links of "Add Button", "Add ButtonList", "Add ItemGroup"... etc at the Properties Explorer.

Right click at the Properties Explorer and Tick/Check the [
Commands
]. 
7. Try to add some buttons into the
RibbonPanel
.8. Click on the
RibbonButton
, go to Properties.9. Let's try to change the image and the label text of the button.

10. This is how your ribbon looks like now.
11. Now, create the click event for the buttons. Click on
RibbonButton
, go to Properties, modify the Name
of the button.
12. Click on the RibbonButton, go to properties > Click on Events > Double Click on event of
Click

13. Events created.
public Form1()
{
InitializeComponent();
}
void cmdNew_Click(object sender, EventArgs e)
{
MessageBox.Show("Button \"New\" Clicked.");
}
void cmdSave_Click(object sender, EventArgs e)
{
MessageBox.Show("Button \"Save\" Clicked.");
}
14. Press F5 to run the application. Done.
15. You might want to inherit your Main Form into a
RibbonForm
to have extra features. Such as:RibbonForm
will have some compatibility problems with some of the System.Windows.Forms
controls. (especially MDI Client Control) 
16. In the code for
Form1.cs
, change inheritance of Form this line:public partial class Form1 : Form
to RibbonForm
public partial class Form1 : RibbonForm
Part 3: Caution While Using With Visual Studio 2010
... deleted ....Part 4: Using this Ribbon with an MDI Enabled WinForm

The following guide will show how to apply this ribbon with an MDI (Multi Document Interface) enabled WinForm.
Note: In previous version of Ribbon, inheritance of RibbonForm is not supported well with MDI Enabled WinForm. This problem is solved in released version of 10 May 2013.
Start
1. Lets design a ribbon winform something like this as example. In the properties window, setIsMdiContainer
to True
.
2. Create another simple another form that will be loaded into the MDI Container of
MainForm
.
3. At code behind of
Form1
, add in the below codes:public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.ControlBox = false;
this.WindowState = FormWindowState.Maximized;
this.BringToFront();
}
}
4. At code behind of MainForm
, create the click events for RibbonButton
at MainForm
:Note: In previous version of Ribbon, inheritance of RibbonForm is not supported well with MDI Enabled WinForm. This problem is solved in released version of 10 May 2013.
public partial class MainForm : RibbonForm
{
public MainForm()
{
InitializeComponent();
}
private void ribbonButton_Form1_Click(object sender, EventArgs e)
{
// Load Form1
}
private void ribbonButton_Close_Click(object sender, EventArgs e)
{
// Close All Forms
}
}
5. Codes for loading Form1 into MDI:private void ribbonButton_Form1_Click(object sender, EventArgs e)
{
foreach (Form f in this.MdiChildren)
{
if (f.GetType() == typeof(Form1))
{
f.Activate();
return;
}
}
Form form1 = new Form1();
form1.MdiParent = this;
form1.Show();
}
6. Codes for closing all opened form in MDI:private void ribbonButton_Close_Click(object sender, EventArgs e)
{
while (this.ActiveMdiChild != null)
{
this.ActiveMdiChild.Close();
}
}
7. That's it. Enjoy.
Android Custom Navigation Drawer
You might have noticed that lot of android applications introduced a sliding panel menu to navigate between major modules of the application. Previously this kind of UI was done using some third party libraries where a list view and some swiping gestures used to achieve this. But now android itself officially introduced sliding panel menu by introducing a newer concept called Navigation Drawer.
Most of the time Sliding Menu (Navigation Drawer) will be hidden and can be shown by swiping the screen from left edge to right or tapping the app icon on the action bar.
In this tutorial we are going to learn how to use navigation drawer to add a sliding menu to your application.
Let’s start by creating a new project..
Starting new Project
1. Create a new project in Eclipse from File ⇒ New ⇒ Android Application Project. I had left my main activity name as MainActivity.java and gave the package name as info.androidhive.slidingmenu.2. I prepared required string variables for List View items and icon names in strings.xml. Open your strings.xml located under res ⇒ values and add the following code.
<? xml version = "1.0" encoding = "utf-8" ?> < resources > < string name = "app_name" >Slider Menu</ string > < string name = "action_settings" >Settings</ string > < string name = "hello_world" >Hello world!</ string > < string name = "drawer_open" >Slider Menu Opened</ string > < string name = "drawer_close" >Slider Menu Closed</ string > <!-- Nav Drawer Menu Items --> < string-array name = "nav_drawer_items" > < item >Home</ item > < item >Find People</ item > < item >Photos</ item > < item >Communities</ item > < item >Pages</ item > < item >What\'s Hot</ item > </ string-array > <!-- Nav Drawer List Item Icons --> <!-- Keep them in order as the titles are in --> < array name = "nav_drawer_icons" > < item >@drawable/ic_home</ item > < item >@drawable/ic_people</ item > < item >@drawable/ic_photos</ item > < item >@drawable/ic_communities</ item > < item >@drawable/ic_pages</ item > < item >@drawable/ic_whats_hot</ item > </ array > <!-- Content Description --> < string name = "desc_list_item_icon" >Item Icon</ string > </ resources > |
Here FrameLayout is used to replace the main content using Fragments and it should be always the first child of the layout for z-index purpose.
< android.support.v4.widget.DrawerLayout android:id = "@+id/drawer_layout" android:layout_width = "match_parent" android:layout_height = "match_parent" > <!-- Framelayout to display Fragments --> < FrameLayout android:id = "@+id/frame_container" android:layout_width = "match_parent" android:layout_height = "match_parent" /> <!-- Listview to display slider menu --> < ListView android:id = "@+id/list_slidermenu" android:layout_width = "240dp" android:layout_height = "match_parent" android:layout_gravity = "start" android:choiceMode = "singleChoice" android:divider = "@color/list_divider" android:dividerHeight = "1dp" android:listSelector = "@drawable/list_selector" android:background = "@color/list_background" /> </ android.support.v4.widget.DrawerLayout > |
Creating Custom List View Adapter
Creating a listview with a icon, title and a counter isn’t straight forward. We have to build a custom listview to achieve this. For this I am going to create a custom adpater class for listview which provides a custom layout for individual list item in the listview.Before start coding the custom adapter, I am going to create required layout files for the list view.
We need the layout drawables to state the list item state when normal and pressed. It needs overall three xml files. One is for normal state, second is for pressed state and third one to combine both the layouts.
4. So create a xml file under res ⇒ drawable folder named list_item_bg_normal.xml and paste the following code. (If you don’t see drawable folder, create a new folder and name it as drawable)
android:shape = "rectangle" > < gradient android:startColor = "@color/list_background" android:endColor = "@color/list_background" android:angle = "90" /> </ shape > |
android:shape = "rectangle" > < gradient android:startColor = "@color/list_background_pressed" android:endColor = "@color/list_background_pressed" android:angle = "90" /> </ shape > |
<? xml version = "1.0" encoding = "utf-8" ?> < item android:drawable = "@drawable/list_item_bg_normal" android:state_activated = "false" /> < item android:drawable = "@drawable/list_item_bg_pressed" android:state_pressed = "true" /> < item android:drawable = "@drawable/list_item_bg_pressed" android:state_activated = "true" /> </ selector > |
If you want to know how to add a rounded corner border layout, you can learn from How to add Rounded Corner borders to Android Layout
<? xml version = "1.0" encoding = "utf-8" ?> android:shape = "rectangle" > <!-- view background color --> < solid android:color = "@color/counter_text_bg" > </ solid > <!-- If you want to add some padding --> < padding android:right = "3dp" android:left = "3dp" > </ padding > <!-- Here is the corner radius --> < corners android:radius = "2dp" > </ corners > </ shape > |
<? xml version = "1.0" encoding = "utf-8" ?> android:layout_width = "match_parent" android:layout_height = "48dp" android:background = "@drawable/list_selector" > < ImageView android:id = "@+id/icon" android:layout_width = "25dp" android:layout_height = "wrap_content" android:layout_alignParentLeft = "true" android:layout_marginLeft = "12dp" android:layout_marginRight = "12dp" android:contentDescription = "@string/desc_list_item_icon" android:src = "@drawable/ic_home" android:layout_centerVertical = "true" /> < TextView android:id = "@+id/title" android:layout_width = "wrap_content" android:layout_height = "match_parent" android:layout_toRightOf = "@id/icon" android:minHeight = "?android:attr/listPreferredItemHeightSmall" android:textAppearance = "?android:attr/textAppearanceListItemSmall" android:textColor = "@color/list_item_title" android:gravity = "center_vertical" android:paddingRight = "40dp" /> < TextView android:id = "@+id/counter" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:background = "@drawable/counter_bg" android:layout_alignParentRight = "true" android:layout_centerVertical = "true" android:layout_marginRight = "8dp" android:textColor = "@color/counter_text_color" /> </ RelativeLayout > |
9. I prefer to create a new package to keep all the model classes. So create a new package named info.androidhive.slidingmenu.model
10. Under model package create a new class named NavDrawerItem.java and paste the following code. Here isCounterVisible defines the visibility of the counter value. If you don’t want to show a counter for a particular list item you can set this to false.
package info.androidhive.slidingmenu.model; public class NavDrawerItem { private String title; private int icon; private String count = "0" ; // boolean to set visiblity of the counter private boolean isCounterVisible = false ; public NavDrawerItem(){} public NavDrawerItem(String title, int icon){ this .title = title; this .icon = icon; } public NavDrawerItem(String title, int icon, boolean isCounterVisible, String count){ this .title = title; this .icon = icon; this .isCounterVisible = isCounterVisible; this .count = count; } public String getTitle(){ return this .title; } public int getIcon(){ return this .icon; } public String getCount(){ return this .count; } public boolean getCounterVisibility(){ return this .isCounterVisible; } public void setTitle(String title){ this .title = title; } public void setIcon( int icon){ this .icon = icon; } public void setCount(String count){ this .count = count; } public void setCounterVisibility( boolean isCounterVisible){ this .isCounterVisible = isCounterVisible; } } |
12. Now we have all the files required for custom list adapter. So create a class named NavDrawerListAdapter.java under adapter package.
package info.androidhive.slidingmenu.adapter; import info.androidhive.slidingmenu.R; import info.androidhive.slidingmenu.model.NavDrawerItem; import java.util.ArrayList; import android.app.Activity; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; public class NavDrawerListAdapter extends BaseAdapter { private Context context; private ArrayList<NavDrawerItem> navDrawerItems; public NavDrawerListAdapter(Context context, ArrayList<NavDrawerItem> navDrawerItems){ this .context = context; this .navDrawerItems = navDrawerItems; } @Override public int getCount() { return navDrawerItems.size(); } @Override public Object getItem( int position) { return navDrawerItems.get(position); } @Override public long getItemId( int position) { return position; } @Override public View getView( int position, View convertView, ViewGroup parent) { if (convertView == null ) { LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); convertView = mInflater.inflate(R.layout.drawer_list_item, null ); } ImageView imgIcon = (ImageView) convertView.findViewById(R.id.icon); TextView txtTitle = (TextView) convertView.findViewById(R.id.title); TextView txtCount = (TextView) convertView.findViewById(R.id.counter); imgIcon.setImageResource(navDrawerItems.get(position).getIcon()); txtTitle.setText(navDrawerItems.get(position).getTitle()); // displaying count // check whether it set visible or not if (navDrawerItems.get(position).getCounterVisibility()){ txtCount.setText(navDrawerItems.get(position).getCount()); } else { // hide the counter view txtCount.setVisibility(View.GONE); } return convertView; } } |
Following are the major steps we need take care of in the main activity.
> Creating a NavDrawerListAdapter instance and adding list items.
> Assigning the adapter to Navigation Drawer ListView
> Creating click event listener for list items
> Creating and displaying fragment activities on selecting list item.
13. So open your MainActivity.java and add the following code. In the following code, we declared required variables, loaded the list items titles and icons from strings.xml, created an adapter and added each list item. Finally we added a navigation drawer listener.
invalidateOptionsMenu() is called in onDrawerOpened() and onDrawerClosed() to hide and show the action bar icons on navigation drawer opened and closed.
public class MainActivity extends Activity { private DrawerLayout mDrawerLayout; private ListView mDrawerList; private ActionBarDrawerToggle mDrawerToggle; // nav drawer title private CharSequence mDrawerTitle; // used to store app title private CharSequence mTitle; // slide menu items private String[] navMenuTitles; private TypedArray navMenuIcons; private ArrayList<NavDrawerItem> navDrawerItems; private NavDrawerListAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTitle = mDrawerTitle = getTitle(); // load slide menu items navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items); // nav drawer icons from resources navMenuIcons = getResources() .obtainTypedArray(R.array.nav_drawer_icons); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerList = (ListView) findViewById(R.id.list_slidermenu); navDrawerItems = new ArrayList<NavDrawerItem>(); // adding nav drawer items to array // Home navDrawerItems.add( new NavDrawerItem(navMenuTitles[ 0 ], navMenuIcons.getResourceId( 0 , - 1 ))); // Find People navDrawerItems.add( new NavDrawerItem(navMenuTitles[ 1 ], navMenuIcons.getResourceId( 1 , - 1 ))); // Photos navDrawerItems.add( new NavDrawerItem(navMenuTitles[ 2 ], navMenuIcons.getResourceId( 2 , - 1 ))); // Communities, Will add a counter here navDrawerItems.add( new NavDrawerItem(navMenuTitles[ 3 ], navMenuIcons.getResourceId( 3 , - 1 ), true , "22" )); // Pages navDrawerItems.add( new NavDrawerItem(navMenuTitles[ 4 ], navMenuIcons.getResourceId( 4 , - 1 ))); // What's hot, We will add a counter here navDrawerItems.add( new NavDrawerItem(navMenuTitles[ 5 ], navMenuIcons.getResourceId( 5 , - 1 ), true , "50+" )); // Recycle the typed array navMenuIcons.recycle(); // setting the nav drawer list adapter adapter = new NavDrawerListAdapter(getApplicationContext(), navDrawerItems); mDrawerList.setAdapter(adapter); // enabling action bar app icon and behaving it as toggle button getActionBar().setDisplayHomeAsUpEnabled( true ); getActionBar().setHomeButtonEnabled( true ); mDrawerToggle = new ActionBarDrawerToggle( this , mDrawerLayout, R.drawable.ic_drawer, //nav menu toggle icon R.string.app_name, // nav drawer open - description for accessibility R.string.app_name // nav drawer close - description for accessibility ){ public void onDrawerClosed(View view) { getActionBar().setTitle(mTitle); // calling onPrepareOptionsMenu() to show action bar icons invalidateOptionsMenu(); } public void onDrawerOpened(View drawerView) { getActionBar().setTitle(mDrawerTitle); // calling onPrepareOptionsMenu() to hide action bar icons invalidateOptionsMenu(); } }; mDrawerLayout.setDrawerListener(mDrawerToggle); if (savedInstanceState == null ) { // on first time display view for first nav item displayView( 0 ); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true ; } @Override public boolean onOptionsItemSelected(MenuItem item) { // toggle nav drawer on selecting action bar app icon/title if (mDrawerToggle.onOptionsItemSelected(item)) { return true ; } // Handle action bar actions click switch (item.getItemId()) { case R.id.action_settings: return true ; default : return super .onOptionsItemSelected(item); } } /*** * Called when invalidateOptionsMenu() is triggered */ @Override public boolean onPrepareOptionsMenu(Menu menu) { // if nav drawer is opened, hide the action items boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList); menu.findItem(R.id.action_settings).setVisible(!drawerOpen); return super .onPrepareOptionsMenu(menu); } @Override public void setTitle(CharSequence title) { mTitle = title; getActionBar().setTitle(mTitle); } /** * When using the ActionBarDrawerToggle, you must call it during * onPostCreate() and onConfigurationChanged()... */ @Override protected void onPostCreate(Bundle savedInstanceState) { super .onPostCreate(savedInstanceState); // Sync the toggle state after onRestoreInstanceState has occurred. mDrawerToggle.syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super .onConfigurationChanged(newConfig); // Pass any configuration change to the drawer toggls mDrawerToggle.onConfigurationChanged(newConfig); } |
Creating Fragment Views for individual List Item
You can see we have Home, Find People, Photos, Communities, Pages and What’s Hot in the list view. Here each list item represents a view where each view needs a Fragment class and a xml layout file.14. So create a class file named HomeFragment.java and a layout file named fragment_home.xml with following content. For demo purpose I have created very simple layout for this view. You can customize this view depending on your app design.
package info.androidhive.slidingmenu; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class HomeFragment extends Fragment { public HomeFragment(){} @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_home, container, false ); return rootView; } } |
<? xml version = "1.0" encoding = "utf-8" ?> android:layout_width = "match_parent" android:layout_height = "match_parent" > < TextView android:id = "@+id/txtLabel" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_centerInParent = "true" android:textSize = "16dp" android:text = "Home View" /> < ImageView android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_below = "@id/txtLabel" android:src = "@drawable/ic_home" android:layout_centerHorizontal = "true" android:layout_marginTop = "10dp" /> </ RelativeLayout > |
Handling Navigation Drawer List Item Click Event
When user selects a list item from navigation drawer, we need to display respected view in the main view. This can be done by adding a list item click listener and loading respected fragment view in the call back event.15. Open the MainActivity.java and add the following code. Here we added a click listener and loaded the related fragment view.
public class MainActivity extends Activity { .. .. @Override protected void onCreate(Bundle savedInstanceState) { .. mDrawerList.setOnItemClickListener( new SlideMenuClickListener()); } /** * Slide menu item click listener * */ private class SlideMenuClickListener implements ListView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // display view for selected nav drawer item displayView(position); } } /** * Diplaying fragment view for selected nav drawer list item * */ private void displayView( int position) { // update the main content by replacing fragments Fragment fragment = null ; switch (position) { case 0 : fragment = new HomeFragment(); break ; case 1 : fragment = new FindPeopleFragment(); break ; case 2 : fragment = new PhotosFragment(); break ; case 3 : fragment = new CommunityFragment(); break ; case 4 : fragment = new PagesFragment(); break ; case 5 : fragment = new WhatsHotFragment(); break ; default : break ; } if (fragment != null ) { FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction() .replace(R.id.frame_container, fragment).commit(); // update selected item and title, then close the drawer mDrawerList.setItemChecked(position, true ); mDrawerList.setSelection(position); setTitle(navMenuTitles[position]); mDrawerLayout.closeDrawer(mDrawerList); } else { // error in creating fragment Log.e( "MainActivity" , "Error in creating fragment" ); } } } |
Final Code
MainActivity.javapackage info.androidhive.slidingmenu; import info.androidhive.slidingmenu.adapter.NavDrawerListAdapter; import info.androidhive.slidingmenu.model.NavDrawerItem; import java.util.ArrayList; import android.app.Activity; import android.app.Fragment; import android.app.FragmentManager; import android.content.res.Configuration; import android.content.res.TypedArray; import android.os.Bundle; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.widget.DrawerLayout; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; public class MainActivity extends Activity { private DrawerLayout mDrawerLayout; private ListView mDrawerList; private ActionBarDrawerToggle mDrawerToggle; // nav drawer title private CharSequence mDrawerTitle; // used to store app title private CharSequence mTitle; // slide menu items private String[] navMenuTitles; private TypedArray navMenuIcons; private ArrayList<NavDrawerItem> navDrawerItems; private NavDrawerListAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTitle = mDrawerTitle = getTitle(); // load slide menu items navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items); // nav drawer icons from resources navMenuIcons = getResources() .obtainTypedArray(R.array.nav_drawer_icons); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerList = (ListView) findViewById(R.id.list_slidermenu); navDrawerItems = new ArrayList<NavDrawerItem>(); // adding nav drawer items to array // Home navDrawerItems.add( new NavDrawerItem(navMenuTitles[ 0 ], navMenuIcons.getResourceId( 0 , - 1 ))); // Find People navDrawerItems.add( new NavDrawerItem(navMenuTitles[ 1 ], navMenuIcons.getResourceId( 1 , - 1 ))); // Photos navDrawerItems.add( new NavDrawerItem(navMenuTitles[ 2 ], navMenuIcons.getResourceId( 2 , - 1 ))); // Communities, Will add a counter here navDrawerItems.add( new NavDrawerItem(navMenuTitles[ 3 ], navMenuIcons.getResourceId( 3 , - 1 ), true , "22" )); // Pages navDrawerItems.add( new NavDrawerItem(navMenuTitles[ 4 ], navMenuIcons.getResourceId( 4 , - 1 ))); // What's hot, We will add a counter here navDrawerItems.add( new NavDrawerItem(navMenuTitles[ 5 ], navMenuIcons.getResourceId( 5 , - 1 ), true , "50+" )); // Recycle the typed array navMenuIcons.recycle(); mDrawerList.setOnItemClickListener( new SlideMenuClickListener()); // setting the nav drawer list adapter adapter = new NavDrawerListAdapter(getApplicationContext(), navDrawerItems); mDrawerList.setAdapter(adapter); // enabling action bar app icon and behaving it as toggle button getActionBar().setDisplayHomeAsUpEnabled( true ); getActionBar().setHomeButtonEnabled( true ); mDrawerToggle = new ActionBarDrawerToggle( this , mDrawerLayout, R.drawable.ic_drawer, //nav menu toggle icon R.string.app_name, // nav drawer open - description for accessibility R.string.app_name // nav drawer close - description for accessibility ) { public void onDrawerClosed(View view) { getActionBar().setTitle(mTitle); // calling onPrepareOptionsMenu() to show action bar icons invalidateOptionsMenu(); } public void onDrawerOpened(View drawerView) { getActionBar().setTitle(mDrawerTitle); // calling onPrepareOptionsMenu() to hide action bar icons invalidateOptionsMenu(); } }; mDrawerLayout.setDrawerListener(mDrawerToggle); if (savedInstanceState == null ) { // on first time display view for first nav item displayView( 0 ); } } /** * Slide menu item click listener * */ private class SlideMenuClickListener implements ListView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // display view for selected nav drawer item displayView(position); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true ; } @Override public boolean onOptionsItemSelected(MenuItem item) { // toggle nav drawer on selecting action bar app icon/title if (mDrawerToggle.onOptionsItemSelected(item)) { return true ; } // Handle action bar actions click switch (item.getItemId()) { case R.id.action_settings: return true ; default : return super .onOptionsItemSelected(item); } } /*** * Called when invalidateOptionsMenu() is triggered */ @Override public boolean onPrepareOptionsMenu(Menu menu) { // if nav drawer is opened, hide the action items boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList); menu.findItem(R.id.action_settings).setVisible(!drawerOpen); return super .onPrepareOptionsMenu(menu); } /** * Diplaying fragment view for selected nav drawer list item * */ private void displayView( int position) { // update the main content by replacing fragments Fragment fragment = null ; switch (position) { case 0 : fragment = new HomeFragment(); break ; case 1 : fragment = new FindPeopleFragment(); break ; case 2 : fragment = new PhotosFragment(); break ; case 3 : fragment = new CommunityFragment(); break ; case 4 : fragment = new PagesFragment(); break ; case 5 : fragment = new WhatsHotFragment(); break ; default : break ; } if (fragment != null ) { FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction() .replace(R.id.frame_container, fragment).commit(); // update selected item and title, then close the drawer mDrawerList.setItemChecked(position, true ); mDrawerList.setSelection(position); setTitle(navMenuTitles[position]); mDrawerLayout.closeDrawer(mDrawerList); } else { // error in creating fragment Log.e( "MainActivity" , "Error in creating fragment" ); } } @Override public void setTitle(CharSequence title) { mTitle = title; getActionBar().setTitle(mTitle); } /** * When using the ActionBarDrawerToggle, you must call it during * onPostCreate() and onConfigurationChanged()... */ @Override protected void onPostCreate(Bundle savedInstanceState) { super .onPostCreate(savedInstanceState); // Sync the toggle state after onRestoreInstanceState has occurred. mDrawerToggle.syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super .onConfigurationChanged(newConfig); // Pass any configuration change to the drawer toggls mDrawerToggle.onConfigurationChanged(newConfig); } } |
Subscribe to:
Posts (Atom)