I am trying to cycle through an array of texts based on ListWheelScrollView using onSelectedItemChanged, but the text does not update, however the variable change does appear in the console
I am extending StatefulWidget too
Here is my ListWheelScrollView:
ListWheelScrollView(
onSelectedItemChanged: (i) {
setState(() {
prompt = promptList[i];
devtools.log(prompt);
});
},
...
and my Text widget looks like this:
Text("$prompt",
key: const Key("textKey"),
style: const TextStyle(
color: Color.fromARGB(255, 255, 255, 250))),
),
I defined my variable prompt inside my build widget instead of the class itself, I'll leave this in case someone else makes the same mistake
Related
I would really like to make this design but I don't know how to implement it in code, any suggestions?The issue is:I don't know how to show only one item at a time on the FlatList and how to make the centered item look closer.Lastly,How can I make the scroll go from one item to the other,without beeing sort of in the middle?
I tried looking online but I haven't been able to find what I need, if you found something please let me know.
I think you are looking for a carousel. Please refer to this library.
A list that allows both dragging and pressing a button.
For that i would use a horizontal FlatList. Then, make each item in the list take up 100% of the screen width and use the FlatList's ref param to scroll to the next item in the list when pressing a button and have a useState to keep track of which index the user is at to align button and swiping.
Heres how i would do it.
Get 100% screen width
import { Dimensions } from 'react-native';
const { width } = Dimensions.get('window');
Set up horizontal FlatList
The key here is the params: pagingEnabled and horizontal.
onViewableItemsChanged is called whenever focused item changes.
useCallback is for optimization. import it with useState
// Method passed to FlatList. Displays the data's text.
const renderItem = useCallback(
({ item }) => (
<View style={[styles.card, { width }]}>
<Text style={styles.cardItem}>{item.text}</Text>
</View>
),
[]
);
<FlatList
ref={flatListRef} // Reference to list. Used to scroll to specific items.
horizontal
pagingEnabled // cause snapping to items
data={data}
renderItem={renderItem}
onViewableItemsChanged={onScroll} // Calling with anonymous function here causes issues
viewabilityConfig={{
itemVisiblePercentThreshold: 100,
}}
/>
Button
Using the flatListRef and my useState, to scroll to the next index and keep track of where the user is at.
import React, { useState, useRef, useCallbac } from 'react';
const flatListRef = useRef(null);
const [currentSectionIndex, setCurrentSectionIndex] = useState(0);
const onButtonPress = useCallback(() => {
if (currentSectionIndex === data.length - 1) {
// What you want to do at the end of the list.
} else if (flatListRef.current) {
// Go to the next item
flatListRef.current.scrollToIndex({
index: currentSectionIndex + 1,
});
setCurrentSectionIndex(currentSectionIndex + 1);
}
}, [currentSectionIndex, data.length]);
OnScroll function
We wanted to allow dragging and pressing a button to go move on in the list.
So when the user scrolls, we use this function, which we passed to the FlatLists onViewableItemsChanged
// When scrolling set useState to keep track of where the user is at.
const onScroll = useCallback(({ viewableItems }) => {
if (viewableItems.length === 1) {
setCurrentSectionIndex(viewableItems[0].index);
}
}, []);
My question is essentially the same as How to remove Space at the bottom of TextField in flutter?, except instead of a TextFormField widget, I am asking the same for a SpinBox widget. Setting isDense: true or isCollapsed: true seems to move the number out of line with the increment/decrement buttons (see screenshots)
Meanwhile, wrapping in a SizedBox and setting height is some improvement, but I am not able to shrink height as much as I would like, or increment/decrement go below the line.
This is with a height of 25:
Having a height of 45 looks visually fine but it takes up too much space for my needs.
Current code which produces the layout below:
SizedBox(
width: 120,
height: 45,
child: SpinBox(
value: 0,
onChanged: (value) {}
),
)
Looking at the source code of the SpinBox you can see that you have the inputDecoration of the TextField exposed, and you can try removing the contentPadding of it and see if it fixes your issue :
SpinBox(
decoration: InputDecoration(
contentPadding: EdgeInsets.zero,
),
);
I am having problems with my app.. When i set the fontSize on my phone it works OK but on other peoples phones due to there phone fontSize settings it is affecting the size of the text in my app.. I heard text scale factor can help but i do not know how to use it
You can use MediaQuery.of(context).textScaleFactor but I think using auto_size_text is more efficient.
EDIT 2 :
Widget build(BuildContext context){
return Text(
'Hello, How are you?',
textScaleFactor : MediaQuery.of(context).textScaleFactor,
style: TextStyle(fontWeight: FontWeight.bold,fontSize : 18),
);
}
And you can check the usage of this property from here as well as TextStyle class from here.
I am implementing a simple widget but I am a primer with animations :)
How can I avoid the second "screen" to occupy space while transitioning in?
Here my fiddle: https://codesandbox.io/s/7w4yw5yq4q
As you can see when you click a button on the first "screen" both the first "screen" and the second are in the DOM so the widget doubles its height.
I want that the two occupy the same line so the height of the widget stays the same.
I guess that I need to use absolute positioning but I want to be sure that it is the right way to do this and see an example of the implementation.
Maybe is there a way to do it without losing the height of the parent (that when the children are absolute positioned goes to 0)
Likely a bit late to answer this but may be others looking for the same answer may benefit.
Is this what you were asking to do?
One thing in Mithril is that if you don't want to return an element, you can just return a null. I use that technique a lot like showHeading ? m("h1", "Heading!") : null
The following is the mod of your code and its fiddle to demonstrate. There are other ways of doing it like dynamically changing the class depending on the toggle.
var m = require("mithril");
import "./style.css";
let app = function() {
let toggle = false;
return {
view: vnode => {
return m(".steps", [
m("button", { onclick: () => (toggle = !toggle) }, "toggle"),
m(
".step",
toggle
? null
: [m("h1", "Title 1"), m("p", "jfewlkfjewklfjwelkfjklewjfw")]
),
toggle
? m(".step.slide-in", [
m("h1", "Title 2"),
m("p", "jfewlkfjewklfjwelkfjklewjfw")
])
: "",
m(".step", [m("h1", "Title 3 "), m("p", "jfewlkfjewklfjwelkfjklewjfw")])
]);
}
};
};
m.mount(document.getElementById("app"), app);
Problem is probably simple but I can't find the proper answer.
I have a panel with only four buttons. Just vbox with buttons. And now I want to select and press this buttons not only with mouse click but also via keyboard. So I used Ext.KeyMap and I catch every key I want to: ENTER, TAB, DOWN and UP. But I can't find simple way to move focus betveen this buttons.
E.g. I'm focused on first button, press DOWN key and I want to be focused on the second button. No way. I tried
but1.down('button[action=next]').focus(false, 100))
but it can't work. Be so kind as to prompt please.
Well what can I say, just VERY BIG thank you – it is working obviously.
I had no idea to use KeyNav.
But it’s working in such a simple example My case is a little bit more complicated and I asked this question just simplified my situation. So this menu is the second screen in my application and it is constructed in such a way:
PANEL
Panel1
Label1
Button 1
Button 2
Button 3
Panel2
Label2
Button 4
Button 5
Panel3
Label3
Button 6
Button 7
Button 8
and every user can see (panels are hidden on the start) and use parts of this structure (e.g. Panel1, 3 and Button 8). I decide about it one step before (login step) and I show to the user menu only for him in the container defined:
Ext.define('Gromel.view.Menu', {
extend: 'Ext.container.Container',
requires:[
'Ext.tab.Panel',
'Ext.layout.container.Border',
'Ext.form.Label',
'Ext.form.Panel'
],
xtype: 'app-menu',
fullscreen: true,
layout: 'fit',
...
I place your code on the PANEL level and it's working almost properly. And I use the following default definition for above items:
defaults: {
margin: '0 0 10 0',
baseCls: 'x-btn-default-large',
cls: 'cap-btn',
style: 'font-size:18px;text-align: center',
height: 40,
width: '50%',
// yours:
handler: function () {
this.up('panel').activeButton = this.activeIndex;
}
}
so I modified your cls change method to:
button[method]('x-focus x-btn-focus x-btn-default-large-focus')
and your procedure is working.
Problems I can't manage now are:
as you see on the same level as buttons I have labels and I don't know how to bypass them;
more important - I want to run this procedure only on menu panel not in login panel and the rest (deeper in my structure) but this is global, so if I press ENTER on login panel I see the effect on next, menu panel; I replaced ENTER effect in the following way (I want to press ENTER on every button in menu and run different presses events):
case e.ENTER: butt.fireEvent('click', butt); break;
So if it isn’t to much for you be so kind and prompt me more please.
Try to use ExtJS KeyNav.
KeyNav provides a convenient wrapper for normalized keyboard navigation. KeyNav allows you to bind navigation keys to function calls that will get called when the keys are pressed, providing an easy way to implement custom navigation schemes for any UI component.
As you said
I have a panel with only four buttons.
I have work around that, I have created an small sencha fiddle demo. It will show you how is working. I hope this will help you to solve your problem.
You can also refer this Key Navigation Sample
Ext.create('Ext.panel.Panel', {
renderTo: Ext.getBody(),
title: 'Button Example with keyNav',
margin: 10,
bodyStyle: {
'border-width': '2px'
},
layout: {
type: 'vbox',
align: 'center'
},
defaults: {
xtype: 'button',
height: 50,
width: '70%',
margin: '20 0',
handler: function () {
this.up('panel').activeButton = this.activeIndex;
}
},
items: [{
text: 'My button 1',
activeIndex: 0
}, {
text: 'My button 2',
activeIndex: 1
}, {
text: 'My button 3',
activeIndex: 2
}, {
text: 'My button 4',
activeIndex: 3
}],
listeners: {
afterrender: function () {
var panel = this;
panel.keynav = Ext.create('Ext.util.KeyNav', {
target: Ext.getBody(),
scope: panel,
up: panel.doFocusOnButton,
down: panel.doFocusOnButton,
enter: panel.doFocusOnButton,
tab: panel.doFocusOnButton
});
//Remove cls on panel click
panel.el.on('click', function () {
this.doAddRemoveCls('removeCls');
}, panel)
panel.focus();
}
},
/*
* Common event will fire on key : ENTER, TAB, UP, DOWN
* #param {Ext.EventObject} e Just as Ext.Element wraps around a native DOM node
*/
doFocusOnButton: function (e) { //{ http://docs.sencha.com/extjs/4.2.5/#!/api/Ext.EventObject }
var panel = this,
button = '',
totalItem = panel.items.length - 1;
if (Ext.isDefined(panel.activeButton) == false) {
panel.activeButton = 0;
} else {
this.doAddRemoveCls('removeCls');
switch (e.getKey()) {
case e.ENTER:
case e.DOWN:
case e.TAB:
panel.activeButton++;
if (panel.activeButton > totalItem) {
panel.activeButton = 0;
}
break;
case e.UP:
panel.activeButton--;
if (panel.activeButton < 0) {
panel.activeButton = totalItem;
}
break;
}
}
this.doAddRemoveCls('addCls');
},
//This function will add or remove cls..
doAddRemoveCls: function (method) {
var panel = this,
index = panel.activeButton,
button = Ext.isDefined(index) ? panel.down('[activeIndex=' + index + ']') : null;
if (button) {
button[method]('x-focus x-btn-focus x-btn-default-small-focus')
}
}
});