I need my button to changed gradient when pressed.
I've tried the following code (suggested by official documentation):
Button {
background: Rectangle {
gradient: Gradient {
GradientStop { position: 0 ; color: control.pressed ? "#ccc" : "#eee" }
GradientStop { position: 1 ; color: control.pressed ? "#aaa" : "#ccc" }
}
}
}
However, my button turns out black.
By substituing the word 'control' with the word 'this' or 'parent', I get the same result: the button is correctly coloured in case it is not pressed, but when I press it, nothing changes.
You forgot to give your button an id:control.
this.pressed and parent.pressed will be undefined, which means they will resolve to false.
Related
I have added a rive ❤️ heart animation to a iconButton in flutter. when I tap on it, it animates from Unlike > Like and when I tapped again it animates backwards. Which is perfectly working. But the thing is, when I close the page and reopen the same page, Rive animation animates again from the very beginning (the default state of the animation is outline bordered heart icon, which I have to tap on it to make ❤️ filled heart icon). So the problem is if I like an item, close the page and then reopened the page I have to tap on it again, in order to make the item favorite or not. I also created a isFavorite bool to tack the icon button state, the thing is I don't know how to sync the bool with rive animation.
So this is what I want: I need the riveAnimation to stay liked or unliked according to the state of isFavourite bool + Unlike, Dislike transition animation. This may be hard to understand. Please leave a comment what part is that you do not understand.
Rive Animation I Used (go to rive)
class Place with ChangeNotifier {
bool isFavourite;
Place(
{this.isFavourite = false});
void toggleFavouriteStatus() {
isFavourite = !isFavourite;
notifyListeners();
}
}
.
.
.
.
.
.
.
SMIInput<bool>? _heartButtonInput;
Artboard? _heartButtonArtboard;
#override
void initState() {
super.initState();
rootBundle.load('assets/rive/heart.riv').then(
(data) {
final file = RiveFile.import(data);
final artboard = file.mainArtboard;
var controller = StateMachineController.fromArtboard(
artboard,
'state',
);
if (controller != null) {
artboard.addController(controller);
_heartButtonInput = controller.findInput('Like');
}
setState(() => _heartButtonArtboard = artboard);
},
);
}
#override
Widget build(BuildContext context) {
final Fav = Provider.of<Place>(context); // I used provider package to retrieve bool data
void _heartButtonAnimation() {
if (_heartButtonInput?.value == false &&
_heartButtonInput?.controller.isActive == false) {
_heartButtonInput?.value = true;
} else if (_heartButtonInput?.value == true &&
_heartButtonInput?.controller.isActive == false) {
_heartButtonInput?.value = false;
}
}
return Stack(
alignment: Alignment.bottomCenter,
children: [
Positioned(
right: 8,
top: 8,
child: Container(
child: Center(
child: Material(
color: Colors.transparent,
child: _heartButtonArtboard == null
? const SizedBox()
: IconButton(
onPressed: () {
Fav.toggleFavouriteStatus();
_heartButtonAnimation();
},
icon: Rive(
artboard: _heartButtonArtboard!,
fit: BoxFit.cover,
),
),
),
),
),
)
],
);
}
}
I'm not sure if I understood correctly. When your record is already given a heart, then after revisiting it, you want the heart to be displayed in "liked" state without running animating it. Is that it?
If so, IMO the problem is within your state machine not allowing the animation to be started in the desired state of "liked". For the heart to get to the liked state, it needs to pass through the liking animation. This is how your state machine looks now:
You should define two paths from Entry state depending on the value of your Like input. Take a look at a state machine from a checkbox I've imported to Flutter lately. Each of the "idle" timelines have only one keyframe for being checked or unchecked. On entry, there's an intersection where a decision is made based on the initial value of checked input.
This way you can display your heart in the desired state without any animation happening when the widget is built.
I need to find the red buttons on Activity and set orange background color to these buttons.
When I click on the button I set it to red:
view.setBackgroundTintList(ColorStateList.valueOf(Color.RED));
When I click on another button, the red buttons should turn orange.
public void Active(View view){
for (View but : buttons) {
but.setClickable(true);
but.setBackgroundTintList();
}
}
I do not know how to get the id of the colors
For me is unclear your question but I'll try to answer it.
Supposing buttons is a List<Button>, so what you can do is.
for(View but : buttons){
int color = ((ColorDrawable)but.getBackground()).getColor();
if(color == Color.Red){
//This button is red change it to orange
but.setBackgroundColor(R.colors.orange);
}
}
And when you are clicking the button use
button.setBackgroundResource(Color.Red);
but.setBackgroundColor(Color.RED);
use that
I can't find any solution for this.I have an dialog which has an TextArea and Ok and close buttons.When I opened the dialog , Then close it. Back button is not working on Android. Why ? My code is :
Dialog {
id: messagereject
Connections
{
target:process
ignoreUnknownSignals: true
onSuccessrejectwo: {
var task=stackView.get(0).currenttask;
task.color="red";
task.enabled=false;
rejectreasontxt.text="";
}
}
contentItem:ColumnLayout {
id:rejectlay
Layout.preferredHeight: rejectheadertxt.height+rejectreasontxt.height+dp(30)
Layout.preferredWidth: rejectheadertxt.width+dp(100)
spacing: dp(10)
.......
......
I just ran into the very same problem myself today. In my app, I want to use a dialog with a TextField to let the user edit the title of some items.
The issue using Dialog in QML seems to be that even after the dialog is closed, it retains keyboard focus and hence captures the back button as well.
For me, the solution was to ensure that after the dialog has been closed (i.e. its visible property is set to false), active keyboard focus is handed back to the "main window":
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.2
ApplicationWindow {
id: mainWindow
width: 200
height: 150
visible: true
FocusScope {
id: rootItem
anchors.fill: parent
Label {
id: label
text: qsTr("Hello World")
anchors.centerIn: parent
}
Button {
text: qsTr("Edit")
anchors {
right: parent.right
bottom: parent.bottom
margins: 10
}
onClicked: {
edit.text = label.text;
dialog.open();
// Let the TextField gain keyboard focus. This also
// means the main window no longer gets keyboard input
// so from here on input (including the back button)
// is handled by the dialog:
edit.forceActiveFocus();
}
}
}
Dialog {
id: dialog
standardButtons: StandardButton.Ok | StandardButton.Cancel
onAccepted: label.text = edit.text
onVisibleChanged: {
if (!visible) {
// Force some item in the main window (in our case the "root item")
// to gain active focus:
rootItem.forceActiveFocus();
}
}
TextField {
id: edit
}
}
}
I have a tableview with searchbar
var tv = Titanium.UI.createTableView ({
data: official_list,
filterAttribute: 'title',
backgroundColor : '#fff',
search: search,
searchHidden:false,
top: '50dp'
});
I want the searchbar to be hidden initially and only shown when searchbutton is pressed. I am using the following code for that
searchButton.addEventListener('click', function(_e) {
search.visible = !search.visible;
if(search.visible) {
search.focus();
self.softKeyboardOnFocus = 0;
}
else {
Ti.UI.Android.hideSoftKeyboard();
}
});
The problem i am having is, even though the search gets hidden, a blank space remains in the place of searchbar.
I tried animating the coordinates of the tableview but that overrides the navigation bar and the blank space still remains. Is there anyway i can toggle the searchbar (by removing the white space also ? ).
Please help!
I solved the problem by creating 2 searchBar and making the searchBar in tableview coordinates out of scope. The searchbar attached to the tableview is made 1dp.
var search = Titanium.UI.createSearchBar({
barColor:'#000',
showCancel:false,
top: -50,
height:'45dp',
hidden: true,
visible: false,
softKeyboardOnFocus : Titanium.UI.Android.SOFT_KEYBOARD_DEFAULT_ON_FOCUS
});
var search_table = Titanium.UI.createSearchBar({
barColor:'#000',
showCancel:false,
height:'1dp',
hidden: true,
visible: false,
});
Now i can animate searchBar (search).
search.visible = !search.visible;
if(search.visible) {
search.focus();
self.softKeyboardOnFocus = 0;
search.animate({
top: '50dp',
duration : 500,
delay : 0,
curve: Titanium.UI.ANIMATION_CURVE_EASE_IN
});
tv.animate({
top: '90dp',
duration : 500,
delay : 0,
curve: Titanium.UI.ANIMATION_CURVE_EASE_IN
});
}
else {
Ti.UI.Android.hideSoftKeyboard();
tv.animate({
top: '50dp',
duration : 500,
delay : 0,
curve: Titanium.UI.ANIMATION_CURVE_EASE_OUT
});
}
});
and pass the values from searchBar to search_table ( better way was to write query for each search but i have more than 7 and instead choose passing the value to tableview.search )
search.addEventListener('change', function(e) {
search_table.value = e.value;
});
I think your solution do not work because the tableview is the immediate children of the window.
It should work if you enclose the tableview with another view, and then animate the tableview within the enclosing view to hide the search bar.
Is it possible to make a textfield with buttons inside? I found the properties rightButton and leftButton, but using Android (emulator) does not work. Is there another alternative?
That is the used code:
var rightButton1 = Titanium.UI.createButton({
color:'#fff',
width:25,
height:25,
right:10,
backgroundImage:'plus.png',
backgroundSelectedImage:'plus.png',
backgroundDisabledImage: 'plus.png'
});
rightButton1.addEventListener('click',function()
{
Titanium.UI.createAlertDialog({
title:'Button clicked',
message:'Button clicked'
}).show();
});
var textField3 = Titanium.UI.createTextField({
color:'#336699',
width:"auto",
height:"auto",
borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED,
rightButton:rightButton1
});
Thanks in advance.
According to the KitchenSink it's an iPhone only function currently.
if(Titanium.Platform.name == 'iPhone OS') {
data.push({title:'Buttons on Textfields', hasChild:true, test:'../examples/textfield_buttons.js'});
}
However I don't see why you couldn't fake this by creating a view and placing the button on top of the textField because Titanium.UI.Android supports zIndex just fine and the focus event to toggle the visibility of the button.
var view = Ti.UI.createView();
var textField = Ti.UI.createTextField({
// cordinates using top, right, left, bottom
zIndex: 1
});
var button = Ti.UI.createButton({
// cordinates using top, right, left, bottom
visible: false,
zIndex: (textField.zIndex + 1)
});
view.add(textField);
Ti.UI.currentWindow.add(button);
Ti.UI.currentWindow.add(view);
// you only need the listeners if you want to hide and show the button
textField.addEventListener('focus', function(e) {
button.show();
});
textField.addEventListener('blur', function(e) {
button.hide();
});