How do I make second submenu in this particular case? - android-studio

How do I make second submenu under the SubMenu1?
Like this:
Main Menu (tap and collapse)
____SubMenuItem1 (tap and collapse)
__________SubMenuItem2
Now I have only the Main Menu and one Sub Menu only.
The routes dart file:
import 'file:///S:/AndroidStudioProjects/test_project/lib/menu.dart';
import 'package:font_awesome_flutter/font.dart';
import 'package:test_project/lib/SubMenu1.dart';
final List<dynamic> pages = [
MenuItem(title: "info", icon: Icons.book, items: [
SubMenuItem("SubMenu1", SubMenu1(),
),
]),
];
SubMenuItem getItemForKey(String key) {
SubMenuItem item;
List<dynamic> pag = List<dynamic>.from(pages);
pag.forEach((page) {
if (page is SubMenuItem && page.title == key) {
item = page;
} else if (page is MenuItem) {
page.items.forEach((sub) {
if (sub.title == key) item = sub;
});
}
});
return item;
}
and the menu page dart file:
import 'package:flutter/material.dart';
class MenuItem {
final String title;
final List<SubMenuItem> items;
final IconData icon;
MenuItem(
{Key key,
#required this.title,
this.items,
this.icon = Icons.label_important});
}
class SubMenuItem {
final String title;
final Widget page;
final IconData icon;
final String path;
SubMenuItem(this.title, this.page, {this.icon = Icons.block, this.path});
}
enum OpenMode { CODE, PREVIEW }

Your SubMenuItem class should have a recursive list of SubMenuItems. With this recursive structure, you will add submenuitems into your submenuitems.
class SubMenuItem {
final String title;
final Widget page;
final IconData icon;
final String path;
final List<SubMenuItem> items;
SubMenuItem(this.title, this.page, {this.icon = Icons.block, this.path, this.items});
}
In fact, that is more appropriate for you to define it inside of the MenuItem class. With that, you won't need any SubMenuItem class.
class MenuItem {
final String title;
final List<MenuItem> items; // Here is the recursive structure!
final IconData icon;
MenuItem(
{Key key,
#required this.title,
this.items,
this.icon = Icons.label_important});
}

use expansion title as you want main mneu=> submenu1=>submenu11.
this code will help you.
ExpansionTile(
title: Text("MAin Menu"),
children: [
ExpansionTile(
children: [
Text("Sub Menu 1"),
],
title: Text("Sub Menu 1"),
)
],
),

Related

How to show the name of chosen element in dropdownmenu working with object?

In this code I am trying to show list of Locations in a drop down menu. In here,I am working with a location model that consists of both name and uid. It works. However, I am not able to show the selected option to the user.
the object here for me is the Location( this.name, this.uid).
class DropButt extends StatelessWidget {
DropButt({Key key,this.locations,this.onchange});
// final String _selectedLocation='';
final List<Location> locations;
Function(Location) onchange;
#override
Widget build(BuildContext context) {
return DropdownButton<Location>(
//value:, here I donot know which value Should I put when I come to put //name it didnot accept it as dropdownbutton is of type location
items: locations.map((Location val) {
return new DropdownMenuItem<Location>(
value: val,
child: new Text(val.name),
);
}).toList(),
onChanged:(_){
onchange(_);
//here I will sink to the ream the value of th choosen location
},
);}
}
You would set the value of the currently selected location. It would need to be passed to this new custom stateless object.
Here's a working sample:
class HomePage extends StatefulWidget {
#override
State<StatefulWidget> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Location _selectedLocation;
final _locations = [
new Location("home", "1"),
new Location("office", "2"),
new Location("work", "3"),
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Sample"),),
body: DropButt(
_selectedLocation,
locations: _locations,
onchange: (location) {
setState(() {
_selectedLocation = location;
});
},
),
);
}
}
class DropButt extends StatelessWidget {
DropButt(this.selectedLocation, {Key key, this.locations, this.onchange});
final Location selectedLocation;
final List<Location> locations;
Function(Location) onchange;
#override
Widget build(BuildContext context) {
return DropdownButton<Location>(
value: selectedLocation, // <--- this is the current selected object
items: locations.map((Location val) {
return new DropdownMenuItem<Location>(
value: val,
child: new Text(val.name), // <--- this is what the user sees
);
}).toList(),
onChanged: onchange,
);
}
}
class Location {
final String name;
final String uid;
Location(this.name, this.uid);
}

Override TreeTableCell rendering in JavaFX

I am trying to change the rendering of a TextFieldTreeTableCell to show a string as a Hyperlink as opposed to plaintext, to no avail. It seems as though it should be doable using setSkin, but something like
setSkin((new HyperLink()).getSkin());
or
setSkin((new HyperLink(getItem())).getSkin());
does not help. Any insight on how this could be done?
What you are doing wrong
You are not using the right function to customize your cell: setSkin is is used for creating custom control skins and is generic to all kinds of controls not just cells, you should a use a cell factory instead.
You are not using the right superclass: TextFieldTreeTableCell is for creating a cell which contains a label that can be made into an editable TextField when you click on it. Such functionality is not useful when you want to "display a non-editable, clickable URL".
Approach you should use
Cells have a specific method for controlling their rendering which is preferred to the skin mechanism when working with cells. This cell specific mechanism is called a cell factory and is documented with an example in the Cell documentation.
TreeTableColumns allow you to set a cell factory on the column to control the rendering of the column cells. The relevant code for rendering a Hyperlink in a cell is below:
emailColumn.setCellFactory(param -> new TreeTableCell<Employee, String>() {
private Hyperlink link = new Hyperlink();
{
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setGraphic(null);
return;
}
link.setText(item);
link.setVisited(getTreeTableRow().getItem().isVisited());
link.setOnAction(event -> {
getTreeTableRow().getItem().setVisited(true);
sendLabel.setText("Send mail to: " + item);
});
setGraphic(link);
}
});
Sample Application
In the screen shot below, the user has just linked on the hyperlink for anna.black#example.com.
The sample code is a modified version of the code from the Oracle TreeTableView tutorial. The addition of a visited property to the Employee class is necessary to keep track of which items in the TreeTableView have been clicked on, so that the Hyperlink visited property can be appropriately set when the cell is updated.
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import java.util.*;
public class TreeTableViewSample extends Application {
private List<Employee> employees = Arrays.asList(
new Employee("Ethan Williams", "ethan.williams#example.com"),
new Employee("Emma Jones", "emma.jones#example.com"),
new Employee("Michael Brown", "michael.brown#example.com"),
new Employee("Anna Black", "anna.black#example.com"),
new Employee("Rodger York", "roger.york#example.com"),
new Employee("Susan Collins", "susan.collins#example.com"));
private final ImageView depIcon = new ImageView (
new Image("http://icons.iconarchive.com/icons/custom-icon-design/flatastic-10/16/Bear-icon.png")
);
final TreeItem<Employee> root =
new TreeItem<>(new Employee("Sales Department", ""), depIcon);
public static void main(String[] args) {
Application.launch(TreeTableViewSample.class, args);
}
final Label sendLabel = new Label();
#Override
public void start(Stage stage) {
root.setExpanded(true);
employees.forEach((employee) -> root.getChildren().add(new TreeItem<>(employee)));
stage.setTitle("Tree Table View Sample");
final Scene scene = new Scene(new VBox(), 400, 400);
scene.setFill(Color.LIGHTGRAY);
VBox sceneRoot = (VBox) scene.getRoot();
TreeTableColumn<Employee, String> empColumn =
new TreeTableColumn<>("Employee");
empColumn.setPrefWidth(150);
empColumn.setCellValueFactory(
(TreeTableColumn.CellDataFeatures<Employee, String> param) ->
new ReadOnlyStringWrapper(param.getValue().getValue().getName())
);
TreeTableColumn<Employee, String> emailColumn =
new TreeTableColumn<>("Email");
emailColumn.setPrefWidth(190);
emailColumn.setCellValueFactory(
(TreeTableColumn.CellDataFeatures<Employee, String> param) ->
new ReadOnlyStringWrapper(param.getValue().getValue().getEmail())
);
emailColumn.setCellFactory(param -> new TreeTableCell<Employee, String>() {
private Hyperlink link = new Hyperlink();
{
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setGraphic(null);
return;
}
link.setText(item);
link.setVisited(getTreeTableRow().getItem().isVisited());
link.setOnAction(event -> {
getTreeTableRow().getItem().setVisited(true);
sendLabel.setText("Send mail to: " + item);
});
setGraphic(link);
}
});
TreeTableView<Employee> treeTableView = new TreeTableView<>(root);
treeTableView.getColumns().setAll(empColumn, emailColumn);
sceneRoot.getChildren().addAll(treeTableView, sendLabel);
stage.setScene(scene);
stage.show();
}
public class Employee {
private SimpleStringProperty name;
private SimpleStringProperty email;
private SimpleBooleanProperty visited;
public SimpleStringProperty nameProperty() {
if (name == null) {
name = new SimpleStringProperty(this, "name");
}
return name;
}
public SimpleStringProperty emailProperty() {
if (email == null) {
email = new SimpleStringProperty(this, "email");
}
return email;
}
private Employee(String name, String email) {
this.name = new SimpleStringProperty(name);
this.email = new SimpleStringProperty(email);
this.visited = new SimpleBooleanProperty(false);
}
public String getName() {
return name.get();
}
public void setName(String fName) {
name.set(fName);
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
public void setVisited(boolean visited) {
this.visited.set(visited);
}
public boolean isVisited() {
return visited.get();
}
}
}

Place a Pin MKMapView

I want to place a pin whenever the screen is touched using MKMapView inside the method ViewDidLoad()
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Perform any additional setup after loading the view, typically from a nib.
mapView.ShowsUserLocation = true;
MKUserLocation currentLocation = mapView.UserLocation;
}
How would I go about doing this? The Xamarindocs are specific about placing an image, but how do I place a pin? Isn't it built into MKMapView?
You add an MKAnnotation to the Map
class BasicMapAnnotation : MKAnnotation{
public override CLLocationCoordinate2D Coordinate {get;set;}
string title, subtitle;
public override string Title { get{ return title; }}
public override string Subtitle { get{ return subtitle; }}
public BasicMapAnnotation (CLLocationCoordinate2D coordinate, string title, string subtitle) {
this.Coordinate = coordinate;
this.title = title;
this.subtitle = subtitle;
}
}
var annotation = new BasicMapAnnotation (new CLLocationCoordinate2D(48.857,2.351), "Paris", "City of Light");
mapView.AddAnnotation(annotation);

Listview with multiple lists

One list:
ListView list = (ListView) pane.lookup("#list");
ObservableList<String> countries = FXCollections.observableArrayList(
"England", "Germany", "France", "Israel");
list.setItems(countries);
Please tell me how to do like this?
ListView list = (ListView) root.lookup("#list");
ObservableList<String> countries = FXCollections.observableArrayList(
"England", "Germany", "France", "Israel");
ObservableList<String> capitals = FXCollections.observableArrayList(
"London", "Berlin", "Paris", "Ierusalim");
There is an example for you. Just make a bean with country and capital field. And you will have a ListView of YourBean. Like that :
The bean
public class MyBean {
private String country;
private String capital;
public MyBean(String country, String capital) {
this.country = country;
this.capital = capital;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCapital() {
return capital;
}
public void setCapital(String capital) {
this.capital = capital;
}
}
and the ListView
public class Example extends ListView<MyBean> {
public Example() {
this.getItems().add(new MyBean("France", "Paris"));
this.getItems().add(new MyBean("England", "London"));
this.setCellFactory(new Callback<ListView<MyBean>, ListCell<MyBean>>() {
#Override
public ListCell<MyBean> call(ListView<MyBean> myBeanListView) {
return new ListCell<MyBean>() {
#Override
protected void updateItem(MyBean myBean, boolean b) {
super.updateItem(myBean, b);
if (!b) {
HBox box = new HBox();
box.setSpacing(50);
box.getChildren().add(new Label(myBean.getCountry()));
box.getChildren().add(new Label(myBean.getCapital()));
setGraphic(box);
} else {
setGraphic(null);
}
}
};
}
});
}
}
You just have to adapt it to your program but it for show you the good setCellFactory method

MonoTouch.Dialog how to get data from dialog

I'm a beginner in MonoTouch and MonoTouch.Dialog.
I am trying to use MT Dialog but I cannot understand how to get data in and out.
Let's say I have Event class:
class Event {
bool type {get;set;}
string name {get;set;}
}
And I want to edit it using this dialog definition:
return new RootElement ("Event Form") {
// string element
new Section ("Information"){
new EntryElement ("Name", "Name of event", ""),
new RootElement ("Type", new RadioGroup (0)){
new Section (){
new RadioElement ("Concert"),
new RadioElement ("Movie"),
new RadioElement ("Exhibition"),
new RadioElement ("Sport")
}
}
},
How can I pass data to and from this form? (using low-level API not Reflection which supports binding)
Very easy, assign the intermediate values to variables:
Section s;
SomeElement e;
return new RootElement ("Foo") {
(s = new Section ("...") {
(e = new StringElement (...))
})
};
You can do something like this:
//custom class to get the Tapped event to work in a RadioElement
class OptionsRadioElement: RadioElement
{
public OptionsRadioElement(string caption, NSAction tapped): base(caption)
{
Tapped += tapped;
}
}
//Custom Controller
public class MyController: DialogViewController
{
private readonly RadioGroup optionsGroup;
private readonly EntryElement nameField;
public MyController(): base(null)
{
//Note the inline assignements to the fields
Root = new RootElement ("Event Form") {
new Section ("Information"){
nameField = new EntryElement ("Name", "Name of event", ""),
new RootElement ("Type", optionsGroup = new RadioGroup (0)){
new Section (){
new OptionsRadioElement("Concert", OptionSelected),
new OptionsRadioElement("Movie", OptionSelected),
new OptionsRadioElement("Exhibition", OptionSelected),
new OptionsRadioElement("Sport", OptionSelected)
}
}
};
}
private void OptionSelected()
{
Console.WriteLine("Selected {0}", optionsGroup.Selected);
}
public void SetData(MyData data)
{
switch(data.Option)
{
case "Concert:
optionsGroup.Selected = 0;
break;
case "Movie":
optionsGroup.Selected = 1;
break;
//And so on....
default:
optionsGroup.Selected = 0;
break;
}
nameField.Value = data.Name;
ReloadData();
}
}

Resources