I am trying to add a custom layout page within cards.
Here: https://developer.android.com/training/wearables/ui/2d-picker.html
explains that CardFragment can easily add a card by:
CardFragment fragment = CardFragment.create(title, text, page.iconRes);
now if I decided I want to have a custom layout, how do I add it instead of creating a CardFragment?
Check this image:
The third page is a full screen custom layout. How can I achieve this?
FragmentGridPagerAdapter can actually support any subclass of Fragment that you need to use. CardFragment is just a convenience for a standard wearable layout.
So, you can just create a custom Fragment with a simple layout (such as a full-size ImageView) and return it for the appropriate page index.
On getFragment(int row, int col) method from your FragmentGridPagerAdapter class, you can create as many fragments as you want.
you just need to test your row/col values in order to instantiate your fragment class in the correct position.
In your case, something like this:
public Fragment getFragment(int row, int col) {
Fragment fragment;
if (row == 0 && col == 2) {
fragment = new YourFullScreenFragment();
} else {
fragment = CardFragment.create(title, text, page.iconRes);
}
return fragment;
}
Cheers
CardFrame is probably that one that you are looking for - it very similar to CardFragment but you can implement your own layout to it. Also as matiash pointed you can use any fragment that you like in such structure.
Related
I am using Vaadin Testbench (4.1.0-alpha) for designing some integration test for my application (designed in Vaadin 7.6.1).
In a window, I use a rich test area. The idea is to design a test where the value of this rich text element is changed simulating some user behaviour. But now I realize I cannot find any method for change the value of this element, neither get the current value of the element.
I have tested some methods.getHTML() gets the HTML for the component, no the HTML of the designer. getText() gets the list of elements (font colour, background and other options of the element, but not the content).
Then I expect to have specific class methods for retrieving the value. If I explore the class RichTextAreaElement, seems that no method is implemented. All code in this class is:
#ServerClass("com.vaadin.ui.RichTextArea")
public class RichTextAreaElement extends AbstractFieldElement {
}
As you can see, no method is declared.
How can I do a test where a user change the value of this rich text area? It is not implemented?
Hmm yeah, that looks like some work in progress, probably because it's a complex component with all the features it provides. Nonetheless we can workaround the limitations a bit, again making use of chrome developer tools (or similar) and some custom classes to select the components by (actually it's just the gwt-RichTextArea).
Of course this serves just as a starting point and can be further enhanced. Also I'd be very interested to see a more elegant solution if someone finds one...
Structure inspection
Test class
public class RichTextAreaTest extends TestBenchTestCase {
#Before
public void setUp() throws Exception {
System.setProperty("webdriver.chrome.driver", "D:\\Kit\\chromedriver_win32\\chromedriver.exe");
setDriver(new ChromeDriver());
}
#After
public void tearDown() throws Exception {
// TODO uncomment below once everything works as expected
//getDriver().quit();
}
#Test
public void shouldModifyRichTextArea() throws InterruptedException {
// class to identify the editor area by
String editorClass = "gwt-RichTextArea";
// open the browser
getDriver().get("http://localhost:8080/");
// select the first rich text
RichTextAreaElement richTextArea = $(RichTextAreaElement.class).first();
// get the editor section which is where we're writing
WebElement richTextEditorArea = richTextArea.findElement(By.className(editorClass));
// click inside to make it "editable"
richTextEditorArea.click();
// send some keystrokes
richTextEditorArea.sendKeys(" + something else added by selenium");
}
}
Result:
Update for getting the value
If you simply want to get the text, the code below will do the trick:
// switch to the editor iframe
getDriver().switchTo().frame(richTextEditorArea);
// get the <body> section where the text is inserted, and print its text
System.out.println("Text =[" + findElement(By.xpath("/html/body")).getText() + "]");
Output
Text =[Some predefined text + something else added by selenium]
At the end, I was able to obtain the content of the element selecting the first iframe of the page, and searching for the body content. The final code looks like:
String currentWindow = getDriver().getWindowHandle();
getDriver().switchTo().frame(getDriver().findElement(By.tagName("iframe")));
WebElement webelement = this.findElement(By.xpath("/html/body"));
String text = webelement.getText();
getDriver().switchTo().window(currentWindow);
return text;
As I need to switch between the iframe and the window, I am only able to obtain the content of the element, not the element itself. If I return directly the element for future use, an org.openqa.selenium.StaleElementReferenceException: Element belongs to a different frame than the current one - switch to its containing frame to use it exception is obtained.
For changing the text, the solutions is very similar, only use the sendKey functions to first remove existing characters and later add the new text:
String currentWindow = getDriver().getWindowHandle();
getDriver().switchTo().frame(getDriver().findElement(By.tagName("iframe")));
WebElement webelement = this.findElement(By.xpath("/html/body"));
// Remove any previous text.
String previousText = webelement.getText();
for (int i = 0; i < previousText.length(); i++) {
webelement.sendKeys(Keys.DELETE);
}
// Set text.
webelement.sendKeys(text);
getDriver().switchTo().window(currentWindow);
If I overwrite showContextMenu on a grid it only add additional menu to the pop up menu when I click on a grid but do not click on any column. One way is to overwrite showContextMenu on all columns in grid but this solution does not looks right. Is there some better way how to insertItem to showContextMenu on all columns of a grid?
I am using AX 2012.
Standard code works only if grid is clicked but not a single column of a grid.
int ret,ii;
int myMenu = 2;
PopupMenu popupMenu = PopupMenu::create(_menuHandle);
FormListItem item;
;
deleteAttachment = popupMenu.insertItem('My menu');
ret = super(_menuHandle);
if(ret == myMenu)
{
//My code
}
return ret;
You need to use method registerOverrideMethod.
You can test how it works as follows. E.g. you have a form with a grid (property Name = 'Grid', AutoDeclaration = 'Yes'), and there are a few StringEdit controls in that grid.
1) Create following method in your form:
public void formControlContext(FormStringControl _formStringControl)
{
_formStringControl.context();
info(strFmt(#"Overridden context of control '%1'", _formStringControl.name()));
}
2) Override method init in your form:
public void init()
{
FormStringControl fsc;
int controlNum;
super();
for (controlNum = 1; controlNum <= Grid.controlCount(); controlNum++)
{
fsc = Grid.controlNum(controlNum);
fsc.registerOverrideMethod(methodStr(FormStringControl, context), identifierStr(formControlContext));
}
}
You only need to modify method 'formControlContext' according to your needs.
P.S. I just noticed you need to override method showContextMenu anot not context. The idea is the same - use registerOverrideMethod. You can override any method this way.
I've never played with overwriting the ShowContextMenu, but I did just make a blog post about how to recursively loop over every form control that sounds like it might help you.
http://alexondax.blogspot.com/2014/05/how-to-use-recursion-to-loop-over-form.html
I'd imagine you could create some sort of handler and key/value thing if you're creative.
I'm trying to scroll down to the bottom of a grid, after the model was setted.
1) I set the model:
myGrid.setModel(new ListModelList<Object>(myList));
2) I override the row renderer
myGrid.setRowRenderer(new RowRenderer<Object>() {
#Override
public synchronized void render(Row row,final Object data, int index) throws Exception {
row.setStyle("commonCellPadding");
.
.
.
row.appendChild(htmlMessage);
}
});
3) Finally if the list used to set the model is too big (the grid in the .zul has fixed height) i want to show the last results (the more recents in this case).
I need to scroll down automatically after the render. How can i do this?
Things i had try
a) Calling a javascript function after the render, this doesn't work due to the fact that the gridEle.scrollHeight attribute returns the fixed height of the grid setted in the zul (or 0 if not) and not the grid's height after the model was setted.
myGrid.addEventListener(ZulEvents.ON_AFTER_RENDER, new EventListener<Event>() {
public void onEvent(Event event) throws Exception
{
Clients.evalJavaScript("var gridEle = document.getElementById('"+myGrid.getUuid()+"-body"+"'); gridEle.scrollTop = gridEle.scrollHeight;alert(gridEle.scrollHeight);");
}
});
Why don't you sort the myList descending at first to make the last row become the first one instead to control the scroll bar?
In my opinion, it would be more easy and matching the users experience.
Just call Clients.scrollIntoView(rows.getLastChild()); after you have set the model and row renderer (provided rows is Rows component id and is already auto wired into your controller). See the live demo on zkfiddle here and source
UPDATE: Clients.scrollIntoView(Component) wouldn't work if you are using Render-On-Demand feature because naturally if the row that you want to scroll to wouldn't have been loaded on initial page load.
I have a QListView with the ViewMode set to IconMode. I would like to achieve the following DnD behavior:
If a list view item is dragged inside the view, only the items position in the view is changed. This is the same as setting DragDropMode equal to InternalMove.
If a list item is moved out of the view, it can be copied to another external view. In this case, DragDropMode is equal to DragOnly.
How do I mix the two modes in such a way that both behaviors are supported by the view?
You might be able to do this by overriding the dropEvent of your view like this:
void MyListView::dropEvent( QDropEvent* e )
{
if( e->source() != this )
{
// something comes from the outside
// what to do? return?
return;
}
else
{
// event comes from the view itself, let's do some stuff
// for example call the base class default event
QAbstractItemView::dropEvent(e);
}
}
I guess the correct flag would be QAbstractItemView::DragDrop to do this.
I'm extending the GWT celltable, and I'd like to override the default row striping with my own styles. The documentation seems to indicate that the celltable should implement RowStyles interface, which I have:
#Override
public String getStyleNames(Object row, int rowIndex) {
if(rowIndex == 0 || rowIndex % 2 == 0)
return "even_row";
return "odd_row";
}
However, it's not applying the style - It's not even hitting the method. If I'm extending the GWT CellTable, then it should be calling this method to apply the row style, right?
Anyone have this working and can tell me what I'm missing...?
Have a look at this page, specifically the last post on the page. It gives a good example of how to do this.
Implement the RowStyles interface and call this:
this.setRowStyles(this);