I'm trying to make an animation inside a FlatList in react-native.
Flat List
--------
item1
--------
item2
--------
item3
--------
As soon as I press the item2 the FlatList will look like this:
--------
item1
--------
empty
--------
item3
And on top of the FlatList (starting from the empty space) it will be the item2 expanding to full screen height, not allowing item1 and item3 to move in the list.
Does anyone have an idea if this can be done using react-native?
I already tried this using absolute positioning with zIndex but nothing seems to work.
Here is my FlatList item
<Animated.View style={[ { height: this.state.height }, this.state.pressed ? { position: 'absolute', top:0, bottom:0, left:0, right:0, zIndex: 1000 } :
{} ]}>
<Text>Absolute expandable FlatList item</Text>
</Animated.View>
The FlatList item has style absolute because in react every element has relative positioning by default.
I did a trick without absolute positioning, using scrollToIndex to move the element at the top of the list and then position it as absolute. But this will make the item3 disapear from the screen while the item2 height is expanding.
Any idea?
One way to achieve this can be having an extra component that has an absolute positioning and opacity 0. When you press on an item you can turn pressed item's opacity to 0 and then render the extra component with the info from the pressed item and then you can give the desired animation. This way pressed item's row will be still filled but seen as empty. If this extra component be inside the FlatList item it can't go out of row's boundaries (as far as I know). You might need to calculate position of the pressed item to start animation of the extra component from.
Related
How could I scroll one page to the right in Cypress?
E.g. I have a horizontally scrollable area. The area contains elements a, b and if I scroll to the right a and b get destroyed, while c and d get added.
My attempt is to find out the width of the scrollable view and then scroll that amount to the right. But the width does not get retrieved before the scrollTo gets called.
Here is what I am trying to do:
const width = cy.getCy("scroll-viewport").invoke("width");
cy.getCy("scroll-viewport").scrollTo(width, 0);
Your code sample has some mystery about it, for example what is cy.getCy().
I can show you how to do it with standard code, and you can adapt from there.
Assuming scroll-viewport is a selector for the scroll container (the owner of the scroll bar)
cy.get("scroll-viewport").then($scrollContainer => {
const width = $scrollContainer[0].offsetWidth;
$scrollContainer[0].scrollTo(width, 0);
})
Note $scrollContainer[0].scrollWidth gives you the total width after scrolling, in case you need that.
I've got a Xamarin Forms cross-platform application (iOS and Android), and on one of the screens I want a list with details:
Heading 1
Detail 1
Detail 2
Detail 3
Heading 2
Detail 1
Heading 3
Detail 1
Detail 2
As you can see, the amount of detail under each heading is variable.
I want the page to display at first with just the headings:
Heading 1
Heading 2
Heading 3
And then when the user presses on a heading, the details for that particular heading appear. Pretty standard stuff.
I've tried several different ways to get this to work, the only path that seems open to me is to have a StackLayout where I define a bunch of labels:
new StackLayout
{
Orientation = StackOrientation.Vertical,
Children =
{
new Label { Text = "Heading 1" },
new Label { Text = " Detail 1\n Detail 2\n Detail 3", IsVisible = false },
new Label { Text = "Heading 2" },
new Label { Text = " Detail 1", IsVisible = false },
new Label { Text = "Heading 3" },
new Label { Text = " Detail 1\n Detail 2", IsVisible = false }
}
}
I then add a TapGestureRecognizer to the heading labels, and when tapped I toggle the value of IsVisible for the detail labels. It works!
The only thing I don't like, is that there is no transition. I click on the heading label and BAM the detail label appears (correctly pushing down all the following labels to make space for itself). I would like an animation so that when I click on the header, the space beneath the header "slowly" opens up to reveal the detail.
As I read about animations online, one possibility is to set the HeightRequest of the detail labels to zero (instead of hiding them with IsVisible=false) and then creating an animation that "slowly" changes the HeightRequest from zero to the actual height of the label. And that's where I run into a problem.
I can't figure out how to get Xamarin to tell me the height of my "details" label.
If I inspect the Height and HeightRequest properties of my details label right after creating it, they are both -1 (no big surprise there). If I inspect those same two properties when I click on the heading, they are still -1. The only way I've found to get the height of my detail label, is to set the detail label visible, call ForceLayout() on my stack layout, store the detail label height, and then set the detail label invisible again. The problem with that is that I sometimes see the detail label flash visible for an instant while I do this.
What's the best/recommended way to accomplish my desired UI?
You can use the Animation API.
Read the blog about it - Creating Animations with Xamarin.Forms.
In particular for your scenario you can use the FadeTo method to animate the Opacity property of a Visual Element.
Eg :
await image.FadeTo (1, 4000);
For more information, see Animation.
In your case my suggested approach would be for showing a label, to set opacity of label to 0, then make it visible, and then use FadeTo to make the opacity to 1.
Use the opposite to hide the label, set opacity 0 via FadeTo, then set IsVisible to false.
If I understand right your problem the only thing you need is to avoid the flash on the label, if this is the case then you can set the Opacity to 0, in this way the label will not be visible until you set again the opacity to 1.
I can suggest you to make a custom XF control (to use as item DataTemplate) as follow:
2 vertical parts:
The header part (A) (when you click on it it will show the second part)
The second part is a 'Listview' control (B) that is empty at the beginning
When you click on (A):
it will show (B)
It will start to populate (B) with your details elements
The trick in my mind is to implement a method that populate the listview (B) item by item (getting them from your viewmodel) with some delay (a few milliseconds) between each insertion and maybe a 'fadeTo' effect too in the same time.
You can see here what I mean (see the "Fade" section):
Insert / fade list item effect sample in HTML
You can improve your template as you want, by embedding the two parts into a 'border' for instance, to make a graphical separation...
Tell me if it's unclear, all you need is time :)
And maybe if you are ready, you can try to make native controls / animations...
I'm new to jvectormap, but have found it to be awesome.
I have created a map with the following characteristics. When the map loads, about 30 countries have colors applied, either Red, Yellow or Green, based on some score associated with that country (like the percentage of the population that are Duran Duran fans). The rest of the countries are just grey. (There is some interactivity on the colored regions, like tooltips and clicks.) When the map is first created, there is a line at the end:
map.series.regions[0].setValues(getColors(currentColor);
and currentColor had previously been defined:
var currentColor = "[ALL]";
so that all of the colors (red, yellow and green) are shown on the map, and that works.
Beneath the map I want to provide buttons to show just the countries of a given color, like just the red ones. When the Red button is clicked, just the red countries will be shown in red and the others shown in grey. Each color would get its own button.
This seems like it would be easy to do. I have seen the technique used here: http://jvectormap.com/examples/random-colors/, where you could click to randomly change the colors and everything else about the map (panning, zooming, etc.) remains intact. The key part is:
map.series.regions[0].setValues(generateColors());
when you have a map constructor like:
map = new jvm.Map({
(If your map constructor is like this:
$('#map').vectorMap({
then you would need to do something like this:
var mapObject = $('#map').vectorMap('get', 'mapObject');
mapObject.series.regions[0].setValues(generateColors());
)
I have tried to do exactly that, but with my own getColors(color) method:
map.series.regions[0].setValues(getColors(currentColor));
where I regenerate the array of map colors that is passed to setValues(), but there is no change to the map. I know that the array of map colors is correct, because my workaround has been to do the following when the button is pressed:
(1) change the currentColor variable
(2) empty out the map div container: $("#map").empty()
(3) redraw the map from scratch using the constructor and the call to map.series.regions[0].setValues(getColors(currentColor));
The downside of this approach is that any panning or zooming is lost when the map is redrawn from scratch. Is there any step I am missing to get the map to update when I call: map.series.regions[0].setValues()
Here is a jsfiddle showing how it does not work, unless you redraw the map from scratch: http://jsfiddle.net/msalamon/euqyfs7v/10/
In the jsfiddle, if you call "High Redraw" it shows just the Red countries, but only by redrawing.
I figured it out. See: http://jsfiddle.net/msalamon/euqyfs7v/11/.
I assumed that setValues() fully replaced the prior values, so any missing values were set to a default value. But instead setValues() only replaces the values that were included there. So when a particular color/level is selected with the button, I have changed it so that the returned array includes a default value for any region that is not included:
else
{
colors[code] = "#999999";
}
this code work for me, you just have to change values, :)
<button id="update-colors-button2">change </button>
<button id="update-colors-button">change </button>
<div id="world-map" style="width: 600px; height: 400px"></div>
<script type="text/javascript">
map = new jvm.WorldMap({
map: 'chile',
container: $('#world-map'),
series: {
regions: [{
attribute: 'fill'
}]
}
});
$(function(){
$('#update-colors-button').click(function(e){
e.preventDefault();
map.series.regions[0].clear();
map.series.regions[0].setValues({'ari' : '#328942'});
});
$('#update-colors-button2').click(function(e){
e.preventDefault();
map.series.regions[0].clear();
map.series.regions[0].setValues({'ata' : '#328942'});
});
})
</script>
When the datatype is Date, the kendo grid uses a kendo datepicker with dropdown calendar for the column.
The datepicker's dropdown calendar usually aligns itself flush with the left edge of the input box. If there isn't room for that, it is moved to the left, but not quite enough. This presents a problem when the rightmost column in the grid is a Date, and the grid is occupying 100% of the width available on the screen: the Saturday column in the dropdown calendar gets "cut off". See pic attached.
Is it possible to tell the calendar dropdown (for a particular column) to align itself flush with the right edge of the text input?
I know that bug. Your datepicker animation container is hidden under right scrollbar. If you set body overflow to hidden, you will not have a scrollbars and calendar will fit and touch right border of screen, like in this example: http://dojo.telerik.com/UCOhA
However if you can't turn off the body scrollbars you need to set calendar position manually dirty way like this:
$("#piker").kendoDatePicker({
open: function(e) {
//setTimeout to let kendo make k-animation-container element at first open
setTimeout(function(){
var animationContainer = $("#" + e.sender.element.attr("id") + "_dateview").parent();
var left = e.sender.element.offset().left + e.sender.element.closest('.k-datepicker').width() - animationContainer.width();
animationContainer.css('left', left);
});
},
//turnoff the animation to avoid strange visual effects
animation: {
open: {
duration: 0
}
}
});
Running example: http://dojo.telerik.com/Imiqa/2
I am using FabricJS to create an application. I am finding that scrolling a parent div/container offsets the selectable area of an object to the right in direct relation to amount scrolled.
So, if I have a canvas that is 1200x600 and a container div that is 600x600 and I add a rect to that canvas at 400, 120; when I scroll 200px, I can't click on the rect to select it. Rather, I have to move my mouse to 600, 120 (empty space) to get the cross bar and select the rect.
Not sure if this is known, or has a work around - but I would appreciate any help possible.
You'll have to modify FabricJs code to make it work.
The problem is in the getPointer function, if you search for it in all.js you'll notice the comment "this method needs fixing" from kangax.
A workaround can be substituting this function with
function getPointer(event) {
// TODO (kangax): this method needs fixing
return { x: pointerX(event) + document.getElementById("container").scrollLeft, y: pointerY(event) + document.getElementById("container").scrollTop };
}
where "container" is the wrapper div of you canvas. It's not nice, since you have to put the exact id, but it works.
Hope this helps.