Flutter Dev

Flutter Dev

1631351644

Text Editor for Android, iOS and Web to Help write HTML WYSIWYG

Flutter Html Editor - Enhanced

Flutter HTML Editor Enhanced is a text editor for Android, iOS, and Web to help write WYSIWYG HTML code with the Summernote JavaScript wrapper.

Note that the API shown in this README.md file shows only a part of the documentation and, also, conforms to the GitHub master branch only! So, here you could have methods, options, and events that aren't published/released yet! If you need a specific version, please change the GitHub branch of this repository to your version or use the online API Reference (recommended).

Video ExampleLight Mode andToolbarType.nativeGridDark Mode andToolbarPosition.belowEditor
GIF exampleLightDark
Flutter Web
Flutter Web


 

Table of Contents:

"Enhanced"? In what ways?

Setup

Usage

API Reference

Parameters Table

Methods Table

Callbacks Table

Getters

Toolbar

Plugins

HtmlEditorOptions Parameters

autoAdjustHeight

adjustHeightForKeyboard

filePath

shouldEnsureVisible

webInitialScripts

HtmlToolbarOptions Parameters

customToolbarButtons and customToolbarButtonsInsertionIndices

linkInsertInterceptor, mediaLinkInsertInterceptor, otherFileLinkInsert, mediaUploadInterceptor, and onOtherFileUpload

onButtonPressed and onDropdownChanged

toolbarPosition: ToolbarPosition.custom

HtmlEditorController Parameters

Examples

Notes

FAQ

License

Contribution Guide

In what ways is this package "enhanced"?

It has official support for Flutter Web, with nearly all mobile features supported. Keyboard shortcuts like Ctrl+B for bold work as well!

It has fully native Flutter-based widget controls

It uses a heavily optimized WebView to deliver the best possible experience when using the editor

It doesn't use a local server to load the HTML code containing the editor. Instead, this package simply loads the HTML file, which improves performance and the editor's startup time.

It uses a controller-based API. You don't have to fiddle around with GlobalKeys to access methods, instead you can simply call <controller name>.<method name> anywhere you want.

It has support for many of Summernote's methods

It has support for all of Summernote's callbacks

It exposes the InAppWebViewController so you can customize the WebView however you like - you can even load your own HTML code and inject your own JavaScript for your use cases.

It has support for dark mode

It has support for extremely granular toolbar customization

More is on the way! File a feature request or contribute to the project if you'd like to see other features added.

Setup

Add html_editor_enhanced: ^2.3.0 as dependency to your pubspec.yaml.

Additional setup is required on iOS to allow the user to pick files from storage. See here for more details.

For images, the package uses FileType.image, for video FileType.video, for audio FileType.audio, and for any other file FileType.any. You can just complete setup for the specific buttons you plan to enable in the editor.

v2.0.0 Migration Guide:

Migration Guide

Basic Usage

import 'package:html_editor/html_editor.dart';

HtmlEditorController controller = HtmlEditorController();

@override Widget build(BuildContext context) {
    return HtmlEditor(
        controller: controller, //required
        htmlEditorOptions: HtmlEditorOptions(
          hint: "Your text here...",
          //initalText: "text content initial, if any",
        ),   
        otherOptions: OtherOptions(
          height: 400,
        ),
    );
}

Important note for Web:

At the moment, there is quite a bit of flickering and repainting when having many UI elements draw over IframeElements. See https://github.com/flutter/flutter/issues/71888 for more details.

The current workaround is to build and/or run your Web app with flutter run --web-renderer html and flutter build web --web-renderer html.

Follow https://github.com/flutter/flutter/issues/80524 for updates on a potential fix, in the meantime the above solution should resolve the majority of the flickering issues.

API Reference

For the full API reference, see here.

For a full example, see here.

Below, you will find brief descriptions of the parameters the HtmlEditor widget accepts and some code snippets to help you use this package.

Parameters - HtmlEditor

ParameterTypeDefaultDescription
controllerHtmlEditorControlleremptyRequired param. Create a controller instance and pass it to the widget. This ensures that any methods called work only on their HtmlEditor instance, allowing you to use multiple HTML widgets on one page.
callbacksCallbacksemptyCustomize the callbacks for various events
optionsHtmlEditorOptionsHtmlEditorOptions()Class to set various options. See below for more details.
pluginsList<Plugins>emptyCustomize what plugins are activated. See below for more details.
toolbarList<Toolbar>See the widget's constructorCustomize what buttons are shown on the toolbar, and in which order. See below for more details.

Parameters - HtmlEditorController

ParameterTypeDefaultDescription
processInputHtmlbooltrueDetermines whether processing occurs on any input HTML (e.g. escape quotes, apostrophes, and remove /ns)
processNewLineAsBrboolfalseDetermines whether a new line (\n) becomes a <br/> in any input HTML
processOutputHtmlbooltrueDetermines whether processing occurs on any output HTML (e.g. <p><br/><p> becomes "")

Parameters - HtmlEditorOptions

ParameterTypeDefaultDescription
autoAdjustHeightbooltrueAutomatically adjust the height of the text editor by analyzing the HTML height once the editor is loaded. Recommended value: true. See below for more details.
adjustHeightForKeyboardbooltrueAdjust the height of the editor if the keyboard is active and it overlaps the editor to prevent the overlap. Recommended value: true, only works on mobile. See below for more details.
darkModeboolnullSets the status of dark mode - false: always light, null: follow system, true: always dark
filePathStringnullAllows you to specify your own HTML to be loaded into the webview. You can create a custom page with Summernote, or theoretically load any other editor/HTML.
hintStringemptyPlaceholder hint text
initialTextStringemptyInitial text content for text editor
inputTypeHtmlInputTypeHtmlInputType.textAllows you to set how the virtual keyboard displays for the editor on mobile devices
mobileContextMenuContextMenunullCustomize the context menu when a user selects text in the editor. See docs for ContextMenu here
mobileLongPressDurationDurationDuration(milliseconds: 500)Set the duration until a long-press is recognized
mobileInitialScriptsUnmodifiableListView<UserScript>nullEasily inject scripts to perform actions like changing the background color of the editor. See docs for UserScript here
webInitialScriptsUnmodifiableListView<WebScript>nullEasily inject scripts to perform actions like changing the background color of the editor. See below for more details.
shouldEnsureVisibleboolfalseScroll the parent Scrollable to the top of the editor widget when the webview is focused. Do not use this parameter if HtmlEditor is not inside a Scrollable. See below for more details.

Parameters - HtmlToolbarOptions

Toolbar Options

ParameterTypeDefaultDescription
audioExtensionsList<String>nullAllowed extensions when inserting audio files
customToolbarButtonsList<Widget>emptyAdd custom buttons to the toolbar
customToolbarInsertionIndicesList<int>emptyAllows you to set where each custom toolbar button should be inserted into the toolbar widget list
defaultToolbarButtonsList<Toolbar>(all constructors active)Allows you to hide/show certain buttons or certain groups of buttons
otherFileExtensionsList<String>nullAllowed extensions when inserting files other than image/audio/video
imageExtensionsList<String>nullAllowed extensions when inserting images
initiallyExpandedboolfalseSets whether the toolbar is initially expanded or not when using ToolbarType.nativeExpandable
linkInsertInterceptorFutureOr<bool> Function(String, String, bool)nullIntercept any links inserted into the editor. The function passes the display text, the URL, and whether it opens a new tab.
mediaLinkInsertInterceptorFutureOr<bool> Function(String, InsertFileType)nullIntercept any media links inserted into the editor. The function passes the URL and InsertFileType which indicates which file type was inserted
mediaUploadInterceptorFutureOr<bool> Function(PlatformFile, InsertFileType)nullIntercept any media files inserted into the editor. The function passes PlatformFile which holds all relevant file data, and InsertFileType which indicates which file type was inserted.
onButtonPressedFutureOr<bool> Function(ButtonType, bool?, void Function()?)nullIntercept any button presses. The function passes the enum for the pressed button, the current selected status of the button (if applicable) and a function to update the status (if applicable).
onDropdownChangedFutureOr<bool> Function(DropdownType, dynamic, void Function(dynamic)?)nullIntercept any dropdown changes. The function passes the enum for the changed dropdown, the changed value, and a function to update the changed value (if applicable).
onOtherFileLinkInsertFunction(String)nullIntercept file link inserts other than image/audio/video. This handler is required when using the other file button, as the package has no built-in handlers
onOtherFileUploadFunction(PlatformFile)nullIntercept file uploads other than image/audio/video. This handler is required when using the other file button, as the package has no built-in handlers
otherFileExtensionsList<String>nullAllowed extensions when inserting files other than image/audio/video
toolbarTypeToolbarTypeToolbarType.nativeScrollableCustomize how the toolbar is displayed (gridview, scrollable, or expandable)
toolbarPositionToolbarPositionToolbarPosition.aboveEditorSet where the toolbar is displayed (above or below the editor)
videoExtensionsList<String>nullAllowed extensions when inserting videos

Styling Options

ParameterTypeDefaultDescription
renderBorderboolfalseRender a border around dropdowns and buttons
textStyleTextStylenullThe TextStyle to use when displaying dropdowns and buttons
separatorWidgetWidgetVerticalDivider(indent: 2, endIndent: 2, color: Colors.grey)Set the widget that separates each group of buttons/dropdowns
renderSeparatorWidgetbooltrueWhether or not the separator widget should be rendered
toolbarItemHeightdouble36Set the height of dropdowns and buttons. Buttons will maintain a square aspect ratio.
gridViewHorizontalSpacingdouble5The horizontal spacing to use between button groups when displaying the toolbar as ToolbarType.nativeGrid
gridViewVerticalSpacingdouble5The vertical spacing to use between button groups when diplaying the toolbar as ToolbarType.nativeGrid

Styling Options - applies to dropdowns only

ParameterTypeDefault
dropdownElevationint8
dropdownIconWidgetnull
dropdownIconColorColornull
dropdownIconSizedouble24
dropdownItemHeightdoublekMinInteractiveDimension (48)
dropdownFocusColorColornull
dropdownBackgroundColorColornull
dropdownMenuDirectionDropdownMenuDirectionnull
dropdownMenuMaxHeightdoublenull
dropdownBoxDecorationBoxDecorationnull

Styling Options - applies to buttons only

ParameterTypeDefault
buttonColorColornull
buttonSelectedColorColornull
buttonFillColorColornull
buttonFocusColorColornull
buttonHighlightColorColornull
buttonHoverColorColornull
buttonSplashColorColornull
buttonBorderColorColornull
buttonSelectedBorderColorColornull
buttonBorderRadiusBorderRadiusnull
buttonBorderWidthdoublenull

Parameters - Other Options

ParameterTypeDefaultDescription
decorationBoxDecorationnullBoxDecoration that surrounds the widget
heightdoublenullHeight of the widget (includes toolbar and editing area)

Methods

Access these methods like this: <controller name>.<method name>

MethodArgument(s)Returned Value(s)Description
addNotification()String html, NotificationType notificationTypeN/AAdds a notification to the bottom of the editor with the provided HTML content. NotificationType determines how it is styled.
clear()N/AN/AResets the HTML editor to its default state
clearFocus()N/AN/AClears focus for the webview and resets the height to the original height on mobile. Do not use this method in Flutter Web.
disable()N/AN/ADisables the editor (a gray mask is applied and all touches are absorbed)
enable()N/AN/AEnables the editor
execCommand()String command, String argument (optional)N/AAllows you to run any execCommand command easily. See the MDN Docs for usage.
getText()N/AFuture<String>Returns the current HTML in the editor
insertHtml()StringN/AInserts the provided HTML string into the editor at the current cursor position. Do not use this method for plaintext strings.
insertLink()String text, String url, bool isNewWindowN/AInserts a hyperlink using the provided text and url into the editor at the current cursor position. isNewWindow defines whether a new browser window is launched if the link is tapped.
insertNetworkImage()String url, String filename (optional)N/AInserts an image using the provided url and optional filename into the editor at the current cursor position. The image must be accessible via a URL.
insertText()StringN/AInserts the provided text into the editor at the current cursor position. Do not use this method for HTML strings.
recalculateHeight()N/AN/ARecalculates the height of the editor by re-evaluating document.body.scrollHeight
redo()N/AN/ARedoes the last command in the editor
reloadWeb()N/AN/AReloads the webpage in Flutter Web. This is mainly provided to refresh the text editor theme when the theme is changed. Do not use this method in Flutter Mobile.
removeNotification()N/AN/ARemoves the current notification from the bottom of the editor
resetHeight()N/AN/AResets the height of the webview to the original height. Do not use this method in Flutter Web.
setHint()StringN/ASets the current hint text of the editor
setFocus()N/AN/AIf the pointer is in the webview, the focus will be set to the editor box
setFullScreen()N/AN/ASets the editor to take up the entire size of the webview
setText()StringN/ASets the current text in the HTML to the input HTML string
toggleCodeview()N/AN/AToggles between the code view and the rich text view
undo()N/AN/AUndoes the last command in the editor

Callbacks

Every callback is defined as a Function(<parameters in some cases>). See the documentation for more specific details on each callback.

CallbackParameter(s)Description
onBeforeCommandStringCalled before certain commands are called (like undo and redo), passes the HTML in the editor before the command is called
onChangeContentStringCalled when the content of the editor changes, passes the current HTML in the editor
onChangeCodeviewStringCalled when the content of the codeview changes, passes the current code in the codeview
onChangeSelectionEditorSettingsCalled when the current selection of the editor changes, passes all editor settings (e.g. bold/italic/underline, color, text direction, etc).
onDialogShownN/ACalled when either the image, link, video, or help dialogs are shown
onEnterN/ACalled when enter/return is pressed
onFocusN/ACalled when the rich text field gains focus
onBlurN/ACalled when the rich text field or the codeview loses focus
onBlurCodeviewN/ACalled when the codeview either gains or loses focus
onImageLinkInsertStringCalled when an image is inserted via URL, passes the URL of the image
onImageUploadFileUploadCalled when an image is inserted via upload, passes FileUpload which holds filename, date modified, size, and MIME type
onImageUploadErrorFileUpload, String, UploadErrorCalled when an image fails to inserted via upload, passes FileUpload which may hold filename, date modified, size, and MIME type (or be null), String which is the base64 (or null), and UploadError which describes the type of error
onInitN/ACalled when the rich text field is initialized and JavaScript methods can be called
onKeyDownintCalled when a key is downed, passes the keycode of the downed key
onKeyUpintCalled when a key is released, passes the keycode of the released key
onMouseDownN/ACalled when the mouse/finger is downed
onMouseUpN/ACalled when the mouse/finger is released
onNavigationRequestMobileStringCalled when the URL of the webview is about to change on mobile only
onPasteN/ACalled when content is pasted into the editor
onScrollN/ACalled when editor box is scrolled

Getters

  1. <controller name>.editorController. This returns the InAppWebViewController, which manages the webview that displays the editor.

This is extremely powerful, as it allows you to create your own custom methods and implementations directly in your app. See flutter_inappwebview for documentation on the controller.

This getter should not be used in Flutter Web. If you are making a cross platform implementation, please use kIsWeb to check the current platform in your code.

  1. <controller name>.characterCount. This returns the number of text characters in the editor.

Toolbar

This API allows you to customize the toolbar in a nice, readable format.

By default, the toolbar will have all buttons enabled except the "other file" button, because the plugin cannot handle those files out of the box.

Here's what that a custom implementation could look like:

HtmlEditorController controller = HtmlEditorController();
Widget htmlEditor = HtmlEditor(
  controller: controller, //required
  //other options
  toolbarOptions: HtmlToolbarOptions(
    defaultToolbarButtons: [
        StyleButtons(),
        ParagraphButtons(lineHeight: false, caseConverter: false)
    ]
  )
);

If you leave the Toolbar constructor blank (like Style() above), then the package interprets that you want all the buttons for the Style group to be visible.

If you want to remove certain buttons from the group, you can set their button name to false, as shown in the example above.

Order matters! Whatever group you set first will be the first group of buttons to display.

If you don't want to show an entire group of buttons, simply don't include their constructor in the Toolbar list! This means that if you want to disable just one button, you still have to provide all other constructors.

You can also create your own toolbar buttons! See below for more details.

Plugins

This API allows you to add certain Summernote plugins from the Summernote Awesome library.

Currently the following plugins are supported:

Summernote Case Converter - Convert the selected text to all lowercase, all uppercase, sentence case, or title case. Supported via a dropdown in the toolbar in ParagraphButtons.

Summernote List Styles - Customize the ul and ol list style. Supported via a dropdown in the toolbar in ListButtons.

Summernote RTL - Switch the currently selected text between LTR and RTL format. Supported via two buttons in the toolbar in ParagraphButtons.

Summernote At Mention - Shows a dropdown of available mentions when the '@' character is typed into the editor. The implementation requires that you pass a list of available mentions, and you can also provide a function to call when a mention is inserted into the editor.

Summernote File - Support picture files (jpg, png, gif, wvg, webp), audio files (mp3, ogg, oga), and video files (mp4, ogv, webm) in base64. Supported via the image/audio/video/other file buttons in the toolbar in InsertButtons.

This list is not final, more can be added. If there's a specific plugin you'd like to see support for, please file a feature request!

No plugins are activated activated by default. They can be activated by modifying the toolbar items, see above for details.

To activate Summernote At Mention:

HtmlEditorController controller = HtmlEditorController();
Widget htmlEditor = HtmlEditor(
  controller: controller, //required
  //other options
  plugins: [
    SummernoteAtMention(
      //returns the dropdown items on mobile
      getSuggestionsMobile: (String value) {
        List<String> mentions = ['test1', 'test2', 'test3'];
        return mentions
            .where((element) => element.contains(value))
            .toList();
      },
      //returns the dropdown items on web
      mentionsWeb: ['test1', 'test2', 'test3'],
      onSelect: (String value) {
        print(value);
      }
    ),
  ]
);

HtmlEditorOptions parameters

This section contains longer descriptions for select parameters in HtmlEditorOptions. For parameters not mentioned here, see the parameters table above for a short description. If you have further questions, please file an issue.

autoAdjustHeight

Default value: true

This option parameter sets the height of the editor automatically by getting the value returned by the JS document.body.scrollHeight and the toolbar GlobalKey (toolbarKey.currentContext?.size?.height).

This is useful because the toolbar could have either 1 - 5 rows depending on the widget's configuration, screen size, orientation, etc. There is no reliable way to tell how large the toolbar is going to be until after build() is executed, and thus simply hardcoding the height of the webview can induce either empty space at the bottom or a scrollable webview. By using the JS and a GlobalKey on the toolbar widget, the editor can get the exact height and update the widget to reflect that.

There is a drawback: The webview will visibly shift size after the page is loaded. Depending on how large the change is, it could be jarring. Sometimes, it takes a second for the webview to adjust to the new size and you might see the editor page jump down/up a second or two after the webview container adjusts itself.

If this does not help your use case feel free to disable it, but the recommended value is true.

adjustHeightForKeyboard

Default value: true, only considered on mobile

This option parameter changes the height of the editor if the keyboard is active and it overlaps with the editor.

This is useful because webviews do not shift their view when the keyboard is active on Flutter at the moment. This means that if your editor spans the height of the page, if the user types a long text they might not be able to see what they are typing because it is obscured by the keyboard.

When this parameter is enabled, the webview will shift to the perfect height to ensure all the typed content is visible, and as soon as the keyboard is hidden, the editor shifts back to its original height.

The webview does take a moment to shift itself back and forth after the keyboard pops up/keyboard disappears, but the delay isn't too bad. It is highly recommended to have the webview in a Scrollable and shouldEnsureVisible enabled if there are other widgets on the page - if the editor is on the bottom half of the page it will be scrolled to the top and then the height will be set accordingly, rather than the plugin trying to set the height for a webview obscured completely by the keyboard.

See below for an example use case.

If this does not help your use case feel free to disable it, but the recommended value is true.

filePath

This option parameter allows you to fully customize what HTML is loaded into the webview, by providing a file path to a custom HTML file from assets.

There is a particular format that is required/recommended when providing a file path for web, because the web implementation will load the HTML as a String and make changes to it directly using replaceAll()., rather than using a method like evaluateJavascript() - because that does not exist on Web.

On Web, you should include the following:

<!--darkCSS--> inside <head> - this enables dark mode support

<!--headString--> inside <body> and below your summernote <div> - this allows the JS and CSS files for any enabled plugins to be loaded

<!--summernoteScripts--> inside <body> and below your summernote <div> - REQUIRED - this allows Dart and JS to communicate with each other. If you don't include this, then methods/callbacks will do nothing.

Notes:

Do not initialize the Summernote editor in your custom HTML file! The package will take care of that.

Make sure to set the id for Summernote to summernote-2! - <div id="summernote-2"></div>.

Make sure to include jquery and the Summernote JS/CSS in your file! The package does not do this for you.

You can use these files from the package to avoid adding more asset files:

<script src="assets/packages/html_editor_enhanced/assets/jquery.min.js"></script>
<link href="assets/packages/html_editor_enhanced/assets/summernote-lite.min.css" rel="stylesheet">
<script src="assets/packages/html_editor_enhanced/assets/summernote-lite.min.js"></script>

See the example HTML file below for an actual example.

shouldEnsureVisible

Default value: false

This option parameter will scroll the editor container into view whenever the webview is focused or text is typed into the editor.

You can only use this parameter if your HtmlEditor is inside a Scrollview, otherwise it does nothing.

This is useful in cases where the page is a SingleChildScrollView or something similar with multiple widgets (eg a form). When the user is going through the different fields, it will pop the webview into view, just like a TextField would scroll into in view if text is being typed inside it.

See below for an example with a good way to use this.

webInitialScripts

This parameter allows you to specify custom JavaScript for the editor on Web. These can be called at any point in time using controller.evaluateJavascriptWeb.

You must add these scripts using the WebScript class, which takes a name and a script argument. name must be a unique identifier, otherwise your desired script may not be executed. Pass your JavaScript code in the script argument.

The package supports returning values from JavaScript as well. You should run var result = await controller.evaluateJavascriptWeb(<name>, hasReturnValue: true);.

To get the return value, you must add the following at the end of your JavaScript:

window.parent.postMessage(JSON.stringify({"type": "toDart: <WebScript name goes here>", <add any other params you wish to return here>}), "*");

You can view a complete example below

HtmlToolbarOptions parameters

This section contains longer descriptions for select parameters in HtmlToolbarOptions. For parameters not mentioned here, see the parameters table above for a short description. If you have further questions, please file an issue.

customToolbarButtons and customToolbarButtonsInsertionIndices

These two parameters allow you to insert custom buttons and set where they are inserted into the toolbar widget list.

This would look something like this:

HtmlEditorController controller = HtmlEditorController();
Widget htmlEditor = HtmlEditor(
  controller: controller, //required
  //other options
  toolbarOptions: HtmlToolbarOptions(
    defaultToolbarButtons: [
      StyleButtons(),
      FontSettingButtons(),
      FontButtons(),
      ColorButtons(),
      ListButtons(),
      ParagraphButtons(),
      InsertButtons(),
      OtherButtons(),
    ],
    customToolbarButtons: [
      //your widgets here
      Button1(),
      Button2(),
    ],
    customToolbarInsertionIndices: [2, 5]
  )
);

In the above example, we have defined two buttons to be inserted at indices 2 and 5. These buttons will not be inserted before FontSettingButtons and before ListButtons, respectively! Each default button group may have a few different sub-groups:

Button GroupNumber of Subgroups
StyleButtons1
FontSettingButtons3
FontButtons2
ColorButtons1
ListButtons2
ParagraphButtons5
InsertButtons1
OtherButtons2

If some of your buttons are deactivated, the number of subgroups could be reduced. The insertion index depends on these subgroups rather than the overall button group. An easy way to count the insertion index is to build the app and count the number of separator spaces between each button group/dropdown before the location you want to insert your button.

So with this in mind, Button1 will be inserted between the first two subgroups in FontSettingButtons, and Button2 will be inserted between the two subgroups in FontButtons.

When creating an onPressed/onTap/onChanged method for your widget, you can use controller.execCommand or any of the other methods on the controller to perform actions in the editor.

Notes:

using controller.editorController.<method> will do nothing on Web!

If you don't provide customToolbarButtonsInsertionIndices, the plugin will insert your buttons at the end of the default toolbar list

If you provide customToolbarButtonsInsertionIndices, it must be the same length as your customToolbarButtons widget list.

linkInsertInterceptor, mediaLinkInsertInterceptor, otherFileLinkInsert, mediaUploadInterceptor, and onOtherFileUpload

These callbacks help you intercept any links or files being inserted into the editor.

ParameterTypeDescription
linkInsertInterceptorFutureOr<bool> Function(String, String, bool)Intercept any links inserted into the editor. The function passes the display text (String), the URL (String), and whether it opens a new tab (bool).
mediaLinkInsertInterceptorFutureOr<bool> Function(String, InsertFileType)Intercept any media links inserted into the editor. The function passes the URL (String).
mediaUploadInterceptorFutureOr<bool> Function(PlatformFile, InsertFileType)Intercept any media files inserted into the editor. The function passes PlatformFile which holds all relevant file data. You can use this to upload into your server, to extract base64 data, perform file validation, etc. It also passes the file type (image/audio/video).
onOtherFileLinkInsertFunction(String)Intercept file link inserts other than image/audio/video. This handler is required when using the other file button, as the package has no built-in handlers. The function passes the URL (String). It also passes the file type (image/audio/video)
onOtherFileUploadFunction(PlatformFile)Intercept file uploads other than image/audio/video. This handler is required when using the other file button, as the package has no built-in handlers. The function passes PlatformFile which holds all relevant file data. You can use this to upload into your server, to extract base64 data, perform file validation, etc.

For linkInsertInterceptor, mediaLinkInsertInterceptor, and mediaUploadInterceptor, you must return a bool to tell the plugin what it should do. When you return false, it assumes that you have handled the user request and taken action. When you return true, the plugin will use the default handlers to handle the user request.

onOtherFileLinkInsert and onOtherFileUpload are required when using the "other file" button. This button isn't active by default, so if you make it active, you must provide these functions, otherwise nothing will happen when the user inserts a file other than image/audio/video.

See below for an example.

onButtonPressed and onDropdownChanged

These callbacks help you intercept any button presses or dropdown changes.

ParameterTypeDescription
onButtonPressedFutureOr<bool> Function(ButtonType, bool?, void Function()?)Intercept any button presses. The function passes the enum for the pressed button, the current selected status of the button (if applicable) and a function to update the status (if applicable).
onDropdownChangedFutureOr<bool> Function(DropdownType, dynamic, void Function(dynamic)?)Intercept any dropdown changes. The function passes the enum for the changed dropdown, the changed value, and a function to update the changed value (if applicable).

You must return a bool to tell the plugin what it should do. When you return false, it assumes that you have handled the user request and taken action. When you return true, the plugin will use the default handlers to handle the user request.

Some buttons and dropdowns, such as copy/paste and the case converter, don't need to update their changed value, so functions to update the value after handling the user request will not be provided for those buttons.

See below for an example.

Custom toolbar position using ToolbarPosition.custom

You can use toolbarPosition: ToolbarPosition.custom and the ToolbarWidget() widget to fully customize exactly where you want to place the toolbar. THe possibilities are endless - you could place the toolbar in a sticky header using Slivers, you could decide to show/hide the toolbar whenever you please, or you could make the toolbar into a floating, draggable widget!

ToolbarWidget() requires the HtmlEditorController you created for the editor itself, along with the HtmlToolbarOptions you supplied to the Html constructor. These can be simply copy-pasted, no changed necessary.

A basic example where the toolbar is placed in a different location than normal:

HtmlEditorController controller = HtmlEditorController();
Widget column = Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    HtmlEditor(
      controller: controller,
      htmlEditorOptions: HtmlEditorOptions(
        hint: 'Your text here...',
        shouldEnsureVisible: true,
        //initialText: "<p>text content initial, if any</p>",
      ),
      htmlToolbarOptions: HtmlToolbarOptions(
        toolbarPosition: ToolbarPosition.custom, //required to place toolbar anywhere!
        //other options
      ),
      otherOptions: OtherOptions(height: 550),
    ),
    //other widgets here
    Widget1(),
    Widget2(),
    ToolbarWidget(
      controller: controller,
      htmlToolbarOptions: HtmlToolbarOptions(
        toolbarPosition: ToolbarPosition.custom, //required to place toolbar anywhere!
        //other options
      ),
    )
  ]
);

HtmlEditorController Parameters

processInputHtml, processOutputHtml, and processNewLineAsBr

Default values: true, true, false, respectively

processInputHtml replaces any occurrences of " with \\", ' with \\', and \r, \r\n, \n, and \n\n with empty strings. This is necessary to prevent syntax exceptions when inserting HTML into the editor as quotes and other special characters will not be escaped. If you have already sanitized and escaped all relevant characters from your HTML input, it is recommended to set this parameter false. You may also want to set this parameter false on Web, as in testing it seems these characters are handled correctly by default, but that may not be the case for your HTML.

processOutputHtml replaces the output HTML with "" if:

It is empty

It is <p></p>

It is <p><br></p>

It is <p><br/></p>

These may seem a little random, but they are the three possible default/initial HTML codes the Summernote editor will have. If you'd like to still receive these outputs, set the parameter false.

processNewLineAsBr will replace \n and \n\n with <br/>. This is only recommended when inserting plaintext as the initial value. In typical HTML any new-lines are ignored, and therefore this parameter defaults to false.

Examples

See the example app to see how the majority of methods & callbacks can be used. You can also play around with the parameters to see how they function.

This section will be updated later with more specialized and specific examples as this library grows and more features are implemented.

Example for linkInsertInterceptor, mediaLinkInsertInterceptor, otherFileLinkInsert, mediaUploadInterceptor, and onOtherFileUpload:

Example code

Note: This example uses the http package.

import 'package:file_picker/file_picker.dart';
import 'package:http/http.dart' as http;

  Widget editor = HtmlEditor(
    controller: controller,
    toolbarOptions: ToolbarOptions(
      mediaLinkInsertInterceptor: (String url, InsertFileType type) {
        if (url.contains(website_url)) {
          controller.insertNetworkImage(url);
        } else {
          controller.insertText("This file is invalid!");
        }
        return false;
      },
      mediaUploadInterceptor: (PlatformFile file, InsertFileType type) async {
        print(file.name); //filename
        print(file.size); //size in bytes
        print(file.extension); //MIME type (e.g. image/jpg)
        //either upload to server:
        if (file.bytes != null && file.name != null) {
          final request = http.MultipartRequest('POST', Uri.parse("your_server_url"));
          request.files.add(http.MultipartFile.fromBytes("file", file.bytes, filename: file.name)); //your server may require a different key than "file"
          final response = await request.send();
          //try to insert as network image, but if it fails, then try to insert as base64:
          if (response.statusCode == 200) {
            controller.insertNetworkImage(response.body["url"], filename: file.name!); //where "url" is the url of the uploaded image returned in the body JSON
          } else {
            if (type == InsertFileType.image) {
              String base64Data = base64.encode(file.bytes!);
              String base64Image =
              """<img src="data:image/${file.extension};base64,$base64Data" data-filename="${file.name}"/>""";
              controller.insertHtml(base64Image);
            } else if (type == InsertFileType.video) {
              String base64Data = base64.encode(file.bytes!);
              String base64Image =
              """<video src="data:video/${file.extension};base64,$base64Data" data-filename="${file.name}"/>""";
              controller.insertHtml(base64Image);
            } else if (type == InsertFileType.audio) {
              String base64Data = base64.encode(file.bytes!);
              String base64Image =
              """<audio src="data:audio/${file.extension};base64,$base64Data" data-filename="${file.name}"/>""";
              controller.insertHtml(base64Image);
            }
          }
        }
        //or insert as base64:
        if (file.bytes != null) {
          if (type == InsertFileType.image) {
            String base64Data = base64.encode(file.bytes!);
            String base64Image =
            """<img src="data:image/${file.extension};base64,$base64Data" data-filename="${file.name}"/>""";
            controller.insertHtml(base64Image);
          } else if (type == InsertFileType.video) {
            String base64Data = base64.encode(file.bytes!);
            String base64Image =
            """<video src="data:video/${file.extension};base64,$base64Data" data-filename="${file.name}"/>""";
            controller.insertHtml(base64Image);
          } else if (type == InsertFileType.audio) {
            String base64Data = base64.encode(file.bytes!);
            String base64Image =
            """<audio src="data:audio/${file.extension};base64,$base64Data" data-filename="${file.name}"/>""";
            controller.insertHtml(base64Image);
          }
        }
        return false;
      },
    ),
  );

linkInsertInterceptor, onOtherFileLinkInsert, and onOtherFileUpload can be implemented in a very similar way, except those do not use the InsertFileType enum in their function.

onOtherFileLinkInsert and onOtherFileUpload also do not require a bool to be returned.

Example for onButtonPressed and onDropdownChanged

Example code

  Widget editor = HtmlEditor(
    controller: controller,
    toolbarOptions: ToolbarOptions(
      onButtonPressed: (ButtonType type, bool? status, Function()? updateStatus) {
        print("button '${describeEnum(type)}' pressed, the current selected status is $status");
        //run a callback and return false and update the status, otherwise
        return true;
      },
      onDropdownChanged: (DropdownType type, dynamic changed, Function(dynamic)? updateSelectedItem) {
        print("dropdown '${describeEnum(type)}' changed to $changed");
        //run a callback and return false and update the changed value, otherwise
        return true;
      },
    ),
  );

Example for adjustHeightForKeyboard:

Example code

class _HtmlEditorExampleState extends State<HtmlEditorExample> {
  final HtmlEditorController controller = HtmlEditorController();

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        if (!kIsWeb) {
          // this is extremely important to the example, as it allows the user to tap any blank space outside the webview,
          // and the webview will lose focus and reset to the original height as expected. 
          controller.clearFocus();
        }
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
          elevation: 0,
        ),
        body: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              //other widgets
              HtmlEditor(
                controller: controller,
                htmlEditorOptions: HtmlEditorOptions(
                  shouldEnsureVisible: true,
                  //adjustHeightForKeyboard is true by default
                  hint: "Your text here...",
                  //initialText: "<p>text content initial, if any</p>",
                ),
                otherOptions: OtherOptions(
                  height: 550,c
                ),
              ),
              //other widgets
            ],
          ),
        ),
      ),
    );
  }
}

Example for shouldEnsureVisible:

Example code

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:html_editor_enhanced/html_editor.dart';

class _ExampleState extends State<Example> {
  final HtmlEditorController controller = HtmlEditorController();

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        if (!kIsWeb) {
          //these lines of code hide the keyboard and clear focus from the webview when any empty
          //space is clicked. These are very important for the shouldEnsureVisible to work as intended.
          SystemChannels.textInput.invokeMethod('TextInput.hide');
          controller.editorController!.clearFocus();
        }
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
          elevation: 0,
          actions: [
            IconButton(
               icon: Icon(Icons.check),
               tooltip: "Save",
               onPressed: () {
                  //save profile details
               }
            ),
          ]   
        ),
        body: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Padding(
                padding: EdgeInsets.only(left: 18, right: 18),
                child: TextField(
                  controller: titleController,
                  textInputAction: TextInputAction.next,
                  focusNode: titleFocusNode,
                  decoration: InputDecoration(
                      hintText: "Name",
                      border: InputBorder.none
                  ),
                ),
              ),
              SizedBox(height: 16),
              HtmlEditor(
                controller: controller,
                htmlEditorOptions: HtmlEditorOptions(
                  shouldEnsureVisible: true,
                  hint: "Description",
                ),
                otherOptions: OtherOptions(
                  height: 450,
                ),
              ),
              SizedBox(height: 16),
              Padding(
                padding: EdgeInsets.only(left: 18, right: 18),
                child: TextField(
                  controller: bioController,
                  textInputAction: TextInputAction.next,
                  focusNode: bioFocusNode,
                  decoration: InputDecoration(
                    hintText: "Bio",
                    border: InputBorder.none
                  ),
                ),
              ),
              Image.network("path_to_profile_picture"),
              IconButton(
                 icon: Icon(Icons.edit, size: 35),
                 tooltip: "Edit profile picture",
                 onPressed: () async {
                    //open gallery and make api call to update profile picture   
                 }
              ),
              //etc... just a basic form.
            ],
          ),
        ),
      ),
    );
  }
}

Example HTML for filePath:

Example HTML

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <meta name="description" content="Flutter Summernote HTML Editor">
    <meta name="author" content="tneotia">
    <title>Summernote Text Editor HTML</title>
    <script src="assets/packages/html_editor_enhanced/assets/jquery.min.js"></script>
    <link href="assets/packages/html_editor_enhanced/assets/summernote-lite.min.css" rel="stylesheet">
    <script src="assets/packages/html_editor_enhanced/assets/summernote-lite.min.js"></script>
    <!--darkCSS-->
</head>
<body>
<div id="summernote-2"></div>
<!--headString-->
<!--summernoteScripts-->
<style>
  body {
      display: block;
      margin: 0px;
  }
  .note-editor.note-airframe, .note-editor.note-frame {
      border: 0px solid #a9a9a9;
  }
  .note-frame {
      border-radius: 0px;
  }
</style>
</body>
</html>

Example for webInitialScripts:

View code

  String result = '';
  final HtmlEditorController controller = HtmlEditorController();
  final FocusNode node = FocusNode();

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        if (!kIsWeb) {
          controller.clearFocus();
        }
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
          elevation: 0,
        ),
        body: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              HtmlEditor(
                controller: controller,
                htmlEditorOptions: HtmlEditorOptions(
                  darkMode: false,
                  webInitialScripts: UnmodifiableListView([
                    WebScript(name: "editorBG", script: "document.getElementsByClassName('note-editable')[0].style.backgroundColor='blue';"),
                    WebScript(name: "height", script: """
                      var height = document.body.scrollHeight;
                      window.parent.postMessage(JSON.stringify({"type": "toDart: height", "height": height}), "*");
                    """),
                  ])
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    TextButton(
                      style: TextButton.styleFrom(
                          backgroundColor: Colors.blueGrey),
                      onPressed: () {
                        controller.evaluateJavascriptWeb("editorBG");
                      },
                      child:
                          Text('Change Background', style: TextStyle(color: Colors.white)),
                    ),
                    SizedBox(
                      width: 16,
                    ),
                    TextButton(
                      style: TextButton.styleFrom(
                          backgroundColor: Colors.blueGrey),
                      onPressed: () async {
                        var result = await controller.evaluateJavascriptWeb("height", hasReturnValue: true);
                        print(result); // prints "{type: toDart: height, height: 561}"
                      },
                      child:
                          Text('Get Height', style: TextStyle(color: Colors.white)),
                    ),
                  ]
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

Notes

Due to this package depending on a webview for rendering the HTML editor, there will be some general weirdness in how the editor behaves. Unfortunately, these are not things I can fix, they are inherent problems with how webviews function on Flutter.

If you do find any issues, please report them in the Issues tab and I will see if a fix is possible, but if I close the issue it is likely due to the above fact.

When switching between dark and light mode, a reload is required for the HTML editor to switch to the correct color scheme. You can implement this programmatically in Flutter Mobile: <controller name>.editorController.reload(), or in Flutter Web: <controller name>.reloadWeb(). This will reset the editor! You can save the current text, reload, and then set the text if you'd like to maintain the state.

If you are making a cross platform implementation and are using either the editorController getter or the reloadWeb() method, use kIsWeb in your app to ensure you are calling these in the correct platform.

FAQ

View answered questions

How can I display the final output of the editor? - Examples given for both raw HTML output and rendered HTML output - https://github.com/tneotia/html-editor-enhanced/issues/2

How can I set the editor to "fullscreen" by default? - https://github.com/tneotia/html-editor-enhanced/issues/4

The editor does not accept any key inputs when using the iOS Simulator. How can I fix this? - https://github.com/tneotia/html-editor-enhanced/issues/7

Clicking on the editor makes the cursor appear on the second line relative with the hint. Is there a workaround? - https://github.com/tneotia/html-editor-enhanced/issues/24

How can I give the editor box a custom background color on mobile? - https://github.com/tneotia/html-editor-enhanced/issues/27

I see a file upload button in the top left of my application on Web. How can I remove it? - https://github.com/tneotia/html-editor-enhanced/issues/28

I can't tap drawer items above the text editor on Web. How can I fix this? - https://github.com/tneotia/html-editor-enhanced/issues/30

How can I remove the "dragbar" at the bottom of the editor? - https://github.com/tneotia/html-editor-enhanced/issues/42

How can I detect if an image has been deleted from the editor? - https://github.com/tneotia/html-editor-enhanced/issues/43

How can I handle editor focus? - https://github.com/tneotia/html-editor-enhanced/issues/47

How can I set the default text direction for the editor content? - https://github.com/tneotia/html-editor-enhanced/issues/49

How can I handle relative URLs for images in my initial text? - https://github.com/tneotia/html-editor-enhanced/issues/50

How can I give the editor box a custom background color on web? - https://github.com/tneotia/html-editor-enhanced/issues/57

How can I create a toolbar dropdown for custom fonts? - https://github.com/tneotia/html-editor-enhanced/issues/59

How can I translate things like dialog text? - https://github.com/tneotia/html-editor-enhanced/issues/69

How can I disable copy/paste buttons from the toolbar? - https://github.com/tneotia/html-editor-enhanced/issues/71

How can I extract image tag from the editor HTML? - https://github.com/tneotia/html-editor-enhanced/issues/72

How can I use LaTeX or math formulas in the editor? - https://github.com/tneotia/html-editor-enhanced/issues/74

How can I make a custom button outside of the toolbar to make text bold? - https://github.com/tneotia/html-editor-enhanced/issues/81

How can I style the <blockquote> element differently? - https://github.com/tneotia/html-editor-enhanced/issues/83

How can I set image width to 100% by default? - https://github.com/tneotia/html-editor-enhanced/issues/86

How can I override link opening on mobile? - https://github.com/tneotia/html-editor-enhanced/issues/88

How can I set the initial font family in the editor? - https://github.com/tneotia/html-editor-enhanced/issues/125

How can I change background color of toolbar only? - https://github.com/tneotia/html-editor-enhanced/issues/94

How can I pick images from gallery directly without showing the dialog? - https://github.com/tneotia/html-editor-enhanced/issues/97

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contribution Guide

Coming soon!

Meanwhile, PRs are always welcome

Original html_editor by xrb21 - repo link. Credits for the original idea and original base code to him. This library is a fork of his repo.

Download Details:
 

Author: tneotia
Download Link: Download The Source Code
Official Website: https://github.com/tneotia/html-editor-enhanced 
License: MIT License 

#flutter 

What is GEEK

Buddha Community

Text Editor for Android, iOS and Web to Help write HTML WYSIWYG
Ava Watson

Ava Watson

1595318322

Know Everything About HTML With HTML Experts

HTML stands for a hypertext markup language. For the designs to be displayed in web browser HTML is the markup language. Technologies like Cascading style sheets (CSS) and scripting languages such as JavaScript assist HTML. With the help of HTML websites and the web, designs are created. Html has a wide range of academic applications. HTML has a series of elements. HTML helps to display web content. Its elements tell the web how to display the contents.

The document component of HTML is known as an HTML element. HTML element helps in displaying the web pages. An HTML document is a mixture of text nodes and HTML elements.

Basics of HTML are-

The simple fundamental components oh HTML is

  1. Head- the setup information for the program and web pages is carried in the head
  2. Body- the actual substance that is to be shown on the web page is carried in the body
  3. HTML- information starts and ends with and labels.
  4. Comments- come up in between

Html versions timeline

  1. HTML was created in 1990. Html is a program that is updated regularly. the timeline for the HTML versions is
  2. HTML 2- November, 1995
  3. HTML 3- January, 1997
  4. HTML 4- December, 1997; April, 1998; December, 1999; May, 2000
  5. HTML 5- October, 2014; November, 2016; December, 2017

HTML draft version timelines are

  1. October 1991
  2. June 1992
  3. November 1992
  4. June 1993
  5. November 1993
  6. November 1994
  7. April 1995
  8. January 2008
  9. HTML 5-
    2011, last call
    2012 candidate recommendation
    2014 proposed recommendation and recommendation

HTML helps in creating web pages. In web pages, there are texts, pictures, colouring schemes, tables, and a variety of other things. HTML allows all these on a web page.
There are a lot of attributes in HTML. It may get difficult to memorize these attributes. HTML is a tricky concept. Sometimes it gets difficult to find a single mistake that doesn’t let the web page function properly.

Many minor things are to be kept in mind in HTML. To complete an HTML assignment, it is always advisable to seek help from online experts. These experts are well trained and acknowledged with the subject. They provide quality content within the prescribed deadline. With several positive reviews, the online expert help for HTML assignment is highly recommended.

#html assignment help #html assignment writing help #online html assignment writing help #html assignment help service online #what is html #about html

Android App to iOS App Porting Services in Virginia, USA | SISGAIN

Want to port your android app to IOS ? The Android to iOS portion can be easy with SISGAIN. Our android to ios porting services make it easier to port android apps to iOS in Virginia, USA. With our remote team you can port your app today. Our dedicated android to iOS Porting developers will help you to run your business smoothly without any hassle. For more information call us at +18444455767 or email us at hello@sisgain.com

#android to ios porting #port android app to ios #porting android to ios #android to ios porting #android app to ios app porting in usa #dedicated android to ios porting developers

Autumn  Blick

Autumn Blick

1593867420

Top Android Projects with Source Code

Android Projects with Source Code – Your entry pass into the world of Android

Hello Everyone, welcome to this article, which is going to be really important to all those who’re in dilemma for their projects and the project submissions. This article is also going to help you if you’re an enthusiast looking forward to explore and enhance your Android skills. The reason is that we’re here to provide you the best ideas of Android Project with source code that you can choose as per your choice.

These project ideas are simple suggestions to help you deal with the difficulty of choosing the correct projects. In this article, we’ll see the project ideas from beginners level and later we’ll move on to intermediate to advance.

top android projects with source code

Android Projects with Source Code

Before working on real-time projects, it is recommended to create a sample hello world project in android studio and get a flavor of project creation as well as execution: Create your first android project

Android Projects for beginners

1. Calculator

build a simple calculator app in android studio source code

Android Project: A calculator will be an easy application if you have just learned Android and coding for Java. This Application will simply take the input values and the operation to be performed from the users. After taking the input it’ll return the results to them on the screen. This is a really easy application and doesn’t need use of any particular package.

To make a calculator you’d need Android IDE, Kotlin/Java for coding, and for layout of your application, you’d need XML or JSON. For this, coding would be the same as that in any language, but in the form of an application. Not to forget creating a calculator initially will increase your logical thinking.

Once the user installs the calculator, they’re ready to use it even without the internet. They’ll enter the values, and the application will show them the value after performing the given operations on the entered operands.

Source Code: Simple Calculator Project

2. A Reminder App

Android Project: This is a good project for beginners. A Reminder App can help you set reminders for different events that you have throughout the day. It’ll help you stay updated with all your tasks for the day. It can be useful for all those who are not so good at organizing their plans and forget easily. This would be a simple application just whose task would be just to remind you of something at a particular time.

To make a Reminder App you need to code in Kotlin/Java and design the layout using XML or JSON. For the functionality of the app, you’d need to make use of AlarmManager Class and Notifications in Android.

In this, the user would be able to set reminders and time in the application. Users can schedule reminders that would remind them to drink water again and again throughout the day. Or to remind them of their medications.

3. Quiz Application

Android Project: Another beginner’s level project Idea can be a Quiz Application in android. Here you can provide the users with Quiz on various general knowledge topics. These practices will ensure that you’re able to set the layouts properly and slowly increase your pace of learning the Android application development. In this you’ll learn to use various Layout components at the same time understanding them better.

To make a quiz application you’ll need to code in Java and set layouts using xml or java whichever you prefer. You can also use JSON for the layouts whichever preferable.

In the app, questions would be asked and answers would be shown as multiple choices. The user selects the answer and gets shown on the screen if the answers are correct. In the end the final marks would be shown to the users.

4. Simple Tic-Tac-Toe

android project tic tac toe game app

Android Project: Tic-Tac-Toe is a nice game, I guess most of you all are well aware of it. This will be a game for two players. In this android game, users would be putting X and O in the given 9 parts of a box one by one. The first player to arrange X or O in an adjacent line of three wins.

To build this game, you’d need Java and XML for Android Studio. And simply apply the logic on that. This game will have a set of three matches. So, it’ll also have a scoreboard. This scoreboard will show the final result at the end of one complete set.

Upon entering the game they’ll enter their names. And that’s when the game begins. They’ll touch one of the empty boxes present there and get their turn one by one. At the end of the game, there would be a winner declared.

Source Code: Tic Tac Toe Game Project

5. Stopwatch

Android Project: A stopwatch is another simple android project idea that will work the same as a normal handheld timepiece that measures the time elapsed between its activation and deactivation. This application will have three buttons that are: start, stop, and hold.

This application would need to use Java and XML. For this application, we need to set the timer properly as it is initially set to milliseconds, and that should be converted to minutes and then hours properly. The users can use this application and all they’d need to do is, start the stopwatch and then stop it when they are done. They can also pause the timer and continue it again when they like.

6. To Do App

Android Project: This is another very simple project idea for you as a beginner. This application as the name suggests will be a To-Do list holding app. It’ll store the users schedules and their upcoming meetings or events. In this application, users will be enabled to write their important notes as well. To make it safe, provide a login page before the user can access it.

So, this app will have a login page, sign-up page, logout system, and the area to write their tasks, events, or important notes. You can build it in android studio using Java and XML at ease. Using XML you can build the user interface as user-friendly as you can. And to store the users’ data, you can use SQLite enabling the users to even delete the data permanently.

Now for users, they will sign up and get access to the write section. Here the users can note down the things and store them permanently. Users can also alter the data or delete them. Finally, they can logout and also, login again and again whenever they like.

7. Roman to decimal converter

Android Project: This app is aimed at the conversion of Roman numbers to their significant decimal number. It’ll help to check the meaning of the roman numbers. Moreover, it will be easy to develop and will help you get your hands on coding and Android.

You need to use Android Studio, Java for coding and XML for interface. The application will take input from the users and convert them to decimal. Once it converts the Roman no. into decimal, it will show the results on the screen.

The users are supposed to just enter the Roman Number and they’ll get the decimal values on the screen. This can be a good android project for final year students.

8. Virtual Dice Roller

Android Project: Well, coming to this part that is Virtual Dice or a random no. generator. It is another simple but interesting app for computer science students. The only task that it would need to do would be to generate a number randomly. This can help people who’re often confused between two or more things.

Using a simple random number generator you can actually create something as good as this. All you’d need to do is get you hands-on OnClick listeners. And a good layout would be cherry on the cake.

The user’s task would be to set the range of the numbers and then click on the roll button. And the app will show them a randomly generated number. Isn’t it interesting ? Try soon!

9. A Scientific Calculator App

Android Project: This application is very important for you as a beginner as it will let you use your logical thinking and improve your programming skills. This is a scientific calculator that will help the users to do various calculations at ease.

To make this application you’d need to use Android Studio. Here you’d need to use arithmetic logics for the calculations. The user would need to give input to the application that will be in terms of numbers. After that, the user will give the operator as an input. Then the Application will calculate and generate the result on the user screen.

10. SMS App

Android Project: An SMS app is another easy but effective idea. It will let you send the SMS to various no. just in the same way as you use the default messaging application in your phone. This project will help you with better understanding of SMSManager in Android.

For this application, you would need to implement Java class SMSManager in Android. For the Layout you can use XML or JSON. Implementing SMSManager into the app is an easy task, so you would love this.

The user would be provided with the facility to text to whichever number they wish also, they’d be able to choose the numbers from the contact list. Another thing would be the Textbox, where they’ll enter their message. Once the message is entered they can happily click on the send button.

#android tutorials #android application final year project #android mini projects #android project for beginners #android project ideas #android project ideas for beginners #android projects #android projects for students #android projects with source code #android topics list #intermediate android projects #real-time android projects

Android Vs iOS - Which is Better for App Development?

Welcome to our Android tutorial, in this tutorial, we are here with something that is a very hot topic of all time. In this article, we are going to discuss a very interesting topic that is Android VS iOS. We know that these days iOS is on fire, and so is Android. The growth rate of both the operating systems has been increasing rapidly for the last few years. Regardless of this, the growth of Android is found to be on the totally next level. So, we are very well prepared here to jot down the difference between Android and iOS

#android tutorials #android vs ios #difference between android and ios #ios vs android which is better #which is better ios or android #why android is better than ios

Best iOS & Android App Development Services in USA

Are you looking for the best iOS & Android app development services provider in USA? AppClues Infotech is a highly trusted & most reliable mobile app development company that provide a complete solution of iOS & Android as per your custom business requirements.

For more info:
Website: https://www.appcluesinfotech.com/
Email: info@appcluesinfotech.com
Call: +1-978-309-9910

#ios & android app development #top ios & android app development company #ios & android app development company in usa #best ios & android app development agency #hire ios & android app developers #custom ios & android app development