How to make this kind of animation in Flutter? - flutter

Video reference
please check the link above to see the animation.
The one in the video is made in Java, An imageView changing images using UniversalImageLoader in 2500 milliseconds interval with a Handler.
JavaCode:
int imgs[] = {R.drawable.efone, R.drawable.eftwo, R.drawable.efthree, R.drawable.effour, R.drawable.effive};
backgroundSlide = (ImageView) findViewById(R.id.bgSlide);
backgroundSlide.setImageResource(R.drawable.efone);
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
int i = 0;
#Override
public void run() {
if (i > imgs.length - 1)
i = 0;
backgroundSlide.startAnimation(animAlpha);
ImageLoader.getInstance().displayImage("drawable://" + imgs[i], backgroundSlide);
i++;
handler.postDelayed(runnable, 2500);
}
};
Xml:
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:id="#+id/bgSlide"
android:src="#drawable/efone" />

Giving you hint:
First add
import 'dart:async';
Suppose you have List of Images.
List<String> imgURLs = ['img1', img2, img3.....N];
Below code for change images:
int index = 0;
const duration = const Duration(seconds:2); // change time as per your requirement
new Timer.periodic(duration, (timer){
setState(){
imageObj = imgURLs[index];
}
if(index >= imgURLs.lenght-1) {
timer.cancel();
}
index++;
});
Put this code at your place might be in initState method and use imageObj to set your image on the screen.
imageObj might be Image type or whatever type based on your image list

Related

Is it possible to customize Gif generation frame-rate with image package?

I've managed to generate an animated GIF image from a set of images on a temporary directory on my storage, with the image package. But I don't if it is possible to customize the frame-rate of the generated GIF image.
This my current generation code :
void _mergeScreenshotsIntoGif({
required int gameStepsCount,
required String tempStorageDirPath,
required String baseFilename,
}) async {
final animation = image.Animation();
final imageDecoder = image.PngDecoder();
for (var stepIndex = 1; stepIndex <= gameStepsCount; stepIndex++) {
final currentFile = File(
'$tempStorageDirPath${Platform.pathSeparator}${baseFilename}_$stepIndex.png');
final currentImageBytes = await currentFile.readAsBytes();
final currentImage = imageDecoder.decodeImage(currentImageBytes)!;
animation.addFrame(currentImage);
}
final gifData = image.encodeGifAnimation(animation);
if (gifData == null) {
//TODO handle gif generation error
return;
}
final destinationFile =
File('$tempStorageDirPath${Platform.pathSeparator}$baseFilename.gif');
await destinationFile.writeAsBytes(gifData);
}
I've looked at the documentation of the package, but did not manage to reach my needs.
So is it possible ?
Maybe a naive implementation, but I managed to "slow" the animation. By adding the different images several times.
Replacing
animation.addFrame(currentImage);
with
for (var frameRepetitionIndex = 0;
frameRepetitionIndex < 10;
frameRepetitionIndex++) {
animation.addFrame(currentImage);
}

javafx8 candle stick chart can't getrid of the stale data

I used the sample candle stick chart code to draw chart. When I worked in the java7 ,the chart worked fine. But when I tried in the Java8. there is a problem.
I tracked the problem like this:this code is from the sample code of Ensemble :CandlStickChart.java
#Override protected void layoutPlotChildren() {
// we have nothing to layout if no data is present
if(getData() == null) return;
// update candle positions
for (int seriesIndex=0; seriesIndex < getData().size(); seriesIndex++) {
Series<Number,Number> series = getData().get(seriesIndex);
Iterator<Data<Number,Number>> iter = getDisplayedDataIterator(series);
Path seriesPath = null;
if (series.getNode() instanceof Path) {
seriesPath = (Path)series.getNode();
seriesPath.getElements().clear();
}
while(iter.hasNext()) {
System.out.println(i++); // the different place
Data<Number,Number> item = iter.next();
double x = getXAxis().getDisplayPosition(getCurrentDisplayedXValue(item));
double y = getYAxis().getDisplayPosition(getCurrentDisplayedYValue(item));
Node itemNode = item.getNode();
CandleStickExtraValues extra = (CandleStickExtraValues)item.getExtraValue();
if (itemNode instanceof Candle && extra != null) {
Candle candle = (Candle) itemNode;
this is part of the code.the problem is with the "the different palce"
for the iter.hasNext() will preserve the stale value.so, every time I set in new data。the list is further long .
the setdata code like :
ObservableList<XYChart.Data<Number, Number>> newData
= FXCollections.<XYChart.Data<Number, Number>>observableArrayList();
for (int j = 1; j <= leno; j++) {
newData.add(。。。。。。。);//
series.getData().clear();
series.setData(newData);
When I remove the stale data by Iter.remove the exception is:we don't support removeing items from the diplayed data list.
You have to add two calls to removeDataItemFromDisplay to the dataItemRemoved method.
Note: I made series and item final in the example code.
#Override
protected void dataItemRemoved(final Data<Number, Number> item,
final Series<Number, Number> series) {
final Node candle = item.getNode();
if (shouldAnimate()) {
// fade out old candle
FadeTransition ft = new FadeTransition(Duration.millis(500), candle);
ft.setToValue(0);
ft.setOnFinished(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent actionEvent) {
getPlotChildren().remove(candle);
removeDataItemFromDisplay(series, item);
}
});
ft.play();
} else {
getPlotChildren().remove(candle);
removeDataItemFromDisplay(series, item);
}
}

CheckBox clickhandler code doesn't work...there is no compile time error...look at the snap shot

CheckBox clickhandler code doesn't work...there is no compile time error...look at the snap shotlook at the snap shot in which there is no image in popup...i have highlighted it
cb1.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event) {
System.out.println("hello2");
boolean checked = ((CheckBox) event.getSource()).getValue();
if (checked) {
System.out.println("hello3");
int left = toothWidget.getToothImage().getAbsoluteLeft();
int top = toothWidget.getVPanel().getAbsoluteTop();//toothWidget.getToothImage().getAbsoluteTop();
Image im = new Image();
im.setUrl(GWT.getHostPageBaseURL()+"/images/"+menuItem.getImg());
System.out.println(GWT.getHostPageBaseURL()+"/images/"+menuItem.getImg());
int offx = left;
int offy = top;
final PopupPanel popup1 = new PopupPanel(true);
popup1.setStylePrimaryName("transparent");
popup1.setPopupPosition(Math.max(offx, 0),Math.max(offy, 0));
//popup.add(im);
ToothWidget wgt = new ToothWidget(toothWidget.getToothNumber(),menuItem.getImg(), toothWidget.getTeeth());
toothWidget.getTeeth().getMap().get(toothWidget.getToothNumber()).put(menuItem.getName(), wgt);
wgt.setMenu(toothWidget.getMenu());
wgt.setPanel(popup1);
popup1.add(wgt);
popup1.show();
}
else{
ToothWidget wgt = toothWidget.getTeeth().getMap().get(toothWidget.getToothNumber()).remove(menuItem.getName());
wgt.getPanel().hide();
}
}
});
WEB Dev 101 - Always use FireFox/FireBug's Network/Image console to check for URL mismatch . You will be seeing 404 errors for the Image path.
Where is YOUR Image located?
1) public folder parallel to your gwt.xml
If you have images folder in your gwt module's public folder you need to use im.setUrl(GWT.getModuleBaseURL()+"/images/"+menuItem.getImg());
or
2) webapps folder
If you have images in deployed into your war/images you need to use
im.setUrl(GWT.getHostPageBaseURL()+"/images/"+menuItem.getImg());
If the above does not solve the issue then you may not have the image at all under "images"
try this. It is better to use the ValueChangeHandler that works for sure and is used for changing values.
CheckBox cb1 = new CheckBox();
cb1.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
#Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
Boolean isChecked = event.getValue();
if (isChecked) {
System.out.println("hello3");
int left = toothWidget.getToothImage().getAbsoluteLeft();
int top = toothWidget.getVPanel().getAbsoluteTop();//toothWidget.getToothImage().getAbsoluteTop();
Image im = new Image();
im.setUrl(GWT.getHostPageBaseURL()+"/images/"+menuItem.getImg());
System.out.println(GWT.getHostPageBaseURL()+"/images/"+menuItem.getImg());
int offx = left;
int offy = top;
final PopupPanel popup1 = new PopupPanel(true);
popup1.setStylePrimaryName("transparent");
popup1.setPopupPosition(Math.max(offx, 0),Math.max(offy, 0));
//popup.add(im);
ToothWidget wgt = new ToothWidget(toothWidget.getToothNumber(),menuItem.getImg(), toothWidget.getTeeth());
toothWidget.getTeeth().getMap().get(toothWidget.getToothNumber()).put(menuItem.getName(), wgt);
wgt.setMenu(toothWidget.getMenu());
wgt.setPanel(popup1);
popup1.add(wgt);
popup1.show();
}
else
{
ToothWidget wgt = toothWidget.getTeeth().getMap().get(toothWidget.getToothNumber()).remove(menuItem.getName());
wgt.getPanel().hide();
}
}
});
}
Plus the images/ folder must be inside the war forlder (though i think you already know that having developed this site)
Also check what menuItem.getImg() returns. It might return only the filename but not the extension or something else entirely.

SWT: remove the invisible component space in composite

I put three composite(1,2,3) inside one composite0, so they all set their layout based on the composite0.setLayout(new FormLayout()). The problem I have now is, I make the composite3 invisible: composite3.setVisible(false); (I dont want to delete the data, still need that component, but just doesn't want it shows on the UI), and there's a big gap after componite2 now. How to remove the big gap(which use to put the composite2)? thank you in advanced!
Snippet 313 of the official SWT examples should help you with that. You basically set a different FormData on composite3 depending on whether you want to show or hide it.
I have a databinding observable for that, but it assumes the controls to be within a GridLayout. I use it to show and hide composites and widgets within a wizard page, depending on the selection state of a checkbox.
To use it, set it up with something like this:
DataBindingContext dbc = new DataBindingContext();
Button button = new Button(composite, SWT.CHECK);
IObservableValue target = SWTObservables.observeSelection(button);
dbc.bindValue(target, new HideControlObservable(someControl));
Here is the observable:
/**
* Observable to control the presence (visibility and size) of any control
* within a grid layout.
* <p>
* Changing the value of this observable will do two things:
* <ol>
* <li>Set the visibility of the control</li>
* <li>Set the size of the control to zero when the control is invisible.</li>
* </ol>
* So, when using this observable, the control will not only be invisible,
* but it will be gone, completely. Normally, when setting the visibility of
* a control to <code>false</code>, the control will not be displayed but
* will still take all the space on the screen.
* </p>
* <p>
* <strong>Note:</strong> this observable works for controls within a
* <strong>GridLayout only</strong>.
* </p>
*/
public class HideControlObservable extends WritableValue implements IValueChangeListener {
private final DataBindingContext dbc = new DataBindingContext();
private final ISWTObservableValue sizeObservable;
private final Point size = new Point(0, 0);
private final Control control;
public HideControlObservable(Control control) {
super(control.getVisible(), Boolean.class);
this.control = control;
UpdateValueStrategy never = new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER);
dbc.bindValue(SWTObservables.observeVisible(control), this, never, null);
sizeObservable = SWTObservables.observeSize(control);
sizeObservable.addValueChangeListener(this);
if (!control.isVisible()) {
GridData gd = (GridData) control.getLayoutData();
if (gd == null) {
gd = new GridData();
}
gd.exclude = true;
control.setLayoutData(gd);
control.setSize(new Point(0, 0));
}
}
#Override
public void doSetValue(Object value) {
super.doSetValue(value);
Boolean bool = (Boolean) value;
if (bool) {
GridData gd = (GridData) control.getLayoutData();
if (gd == null) {
gd = new GridData();
}
gd.exclude = false;
control.setLayoutData(gd);
control.setSize(size);
control.getParent().layout();
} else {
GridData gd = (GridData) control.getLayoutData();
if (gd == null) {
gd = new GridData();
}
gd.exclude = true;
control.setLayoutData(gd);
control.setSize(new Point(0, 0));
control.getParent().layout();
}
}
#Override
public synchronized void dispose() {
sizeObservable.dispose();
super.dispose();
}
#Override
public void handleValueChange(ValueChangeEvent event) {
Point newSize = (Point) event.getObservableValue().getValue();
if (newSize.x > size.x) {
size.x = newSize.x;
}
if (newSize.y > size.y) {
size.y = newSize.y;
}
}
}
FormData data = new FormData();
data.left = new FormAttachment(0, 100, EditorPanel.SPACING);
data.top = new FormAttachment(section1, EditorPanel.SPACING);
data.height = 0;
data.width = 0;
addSectionFormData(a, b, c);
a.setLayoutData(data);
b.setLayoutData(data);
this solve the problem! :)

Monitoring BATTERY_CHANGED with BroadcastReceiver and displaying with level-list not working

Hello everyone I've been stick with this problem, and I can't see my mistake. I had used before basicly for having different drawable bind to a specific level, nevertheless I am trying to use it within a BroadcastReceiver wich monitor battery changes, the problem is that I don't get any UI update when I called the setImageLevel change?
The Broadcast Receiver goes like this
public class BatteryReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(LOG, "Fired Changed");
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
int percent = (level * 100) / scale;
imageBattery = (ImageView) findViewById(R.id.imageBatery);
imageBattery.setImageLevel(percent);
Log.d(LOG, "On UI running I am");
// imageBattery.getDrawable().mutate();
// imageBattery.invalidate();
// Log.d(LOG,"DRawable: "+((LevelListDrawable)imageBattery.getDrawable()).getCurrent());
}
}
The Log gets displayed but it does not change my ImageView if you can point me out in the right direction, or you have any insight on this issue?
Little bit of more info
Here is my Registration and unregistration both on the same activity as the BroadcastReceiver
#Override
public void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.BATTERY_CHANGED");
registerReceiver(receiver, filter);
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
How do I instatiate the ImageView Drawable:
<ImageView
android:id="#+id/imageBatery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/battery_status" />
And also battery_status.xml is a drawable (I removed some of the drawable item because you get the idea I have from 0-100)
<item
android:drawable="#drawable/stat_sys_battery_100"
android:maxLevel="100"/>
<item
android:drawable="#drawable/stat_sys_battery_90"
android:maxLevel="90"/>
<item
android:drawable="#drawable/stat_sys_battery_80"
android:maxLevel="80"/>
Do You have your BroadcastReceiver inlined in Your Activity? If so, use 'MyActivity.this.runOnUiThread()` method to change Your views.
your problem is in images
LevelListDrawable doesn't append new image when level changed, it just shows the image for level you've set
try differen images and you'll see what I mean
try this in your onCreate:
imageBattery = (ImageView) findViewById(R.id.imageBatery);
for (int i = 0; i < 10; i++) {
imageBattery.setImageLevel(i * 10);
}
is smth changed ?