ListCell Animation in ListView

JavaFX 动画 ListView

After a long time I am back again with new stuffs. I have seen that JavaFX has got so many demand nowadays. Lots of people are requesting for something new something wow effect. In the same way one of my colleagues told me what if we have listview got some effects on scrolling the list. I got some dig around JavaFX Animation API and did some animation with ListCell but I thought it would be great if I share my works to you guys.

First We got to revamp what is the Listcell. ListCell are designed for making user to display text content in list format. But we can override these and make our own like displaying images,shapes and other controls as well.

ListCell inherits the character of Labeled so in default ListCell only displays the text content.If you want some control in your listcell other than label then there are some bunch of cellfactory in javafx.scene.control.cell package.

Every ListCell are being rendered according to the cellFactory implementation so you are free to implement your own cellFactory to make the listcell even more customizable. I had posted about TableCell customization which utilizes use of cellFactory (TableView Cell Modify)

Lets roll with the ListCell customization.

——————————————————————————————————————————————————————

public class AnimatedListCell<T> extends AbstractAnimatedListCell<T> {

    //... other codes ...     
    /**
     * Get cellfactory of AbstractAnimatedListCell for ListView
     *
     * @param type
     * @return
     */
    public static Callback<ListView<String>, ListCell<String>> forListView(final AnimationType... type) {
        return new Callback<ListView<String>, ListCell<String>>() {
            @Override
            public ListCell<String> call(
                    ListView<String> p) {
                return new AnimatedListCell<>(new DefaultStringConverter(), type);
            }
        };
    }

    /**
     * Get cellfactory of AbstractAnimatedListCell for ListView with StringConverter
     *
     * @param <T>
     * @param sc
     * @param type
     * @return
     */
    public static <T extends Object> Callback<ListView<T>, ListCell<T>> forListView(
            final StringConverter<T> sc, final AnimationType... type) {
        return new Callback<ListView<T>, ListCell<T>>() {
            @Override
            public ListCell<T> call(
                    ListView<T> p) {
                return new AnimatedListCell<>(sc, type);
            }
        };


    }

    /**
     * For getting the KeyFrames of specific AnimationType
     *
     * @param types
     * @return
     */
    @Override
    protected KeyFrame[] getKeyFrames(AnimationType[] types) {
        if (types == null) {
            return null;
        }
        KeyFrame[] frames = null;
        for (AnimationType type : types) {
            switch (type) {
                case FADE_OUT:
                    frames = anim.getFadeOut(frames);
                    break;
                case FLAP_RIGHT:
                    frames = anim.getFlapRight(frames);
                    break;
                case FLATTERN_OUT:
                    frames = anim.getFlatternOut(frames);
                    break;
                case FLY_FROM_DOWN:
                    frames = anim.getFlyFromDown(frames);
                    break;
                case FLY_FROM_UP:
                    frames = anim.getFlyFromUp(frames);
                    break;
                case ROTATE_RIGHT:
                    frames = anim.getRotateYRight(frames);
                    break;
                case SPEED_LEFT:
                    frames = anim.getSpeedLeft(frames);
                    break;
                case SPEED_RIGHT:
                    frames = anim.getSpeedRight(frames);
                    break;
                case TRANSITION_DOWN:
                    frames = anim.getTransitionDown(frames);
                    break;
                case TRANSITION_LEFT:
                    frames = anim.getTransitionLeft(frames);
                    break;
                case TRANSITION_RIGHT:
                    frames = anim.getTransitionRight(frames);
                    break;
                case TRANSITION_TOP:
                    frames = anim.getTransitionTop(frames);
                    break;
                case ZOOM_IN:
                    frames = anim.getZoomIn(0, frames);
                    break;
                case POP_OUT:
                    frames = anim.getPopOut(frames);
                    break;

            }
        }
        return frames;

    }

    @Override
    protected void updateItem(T t, boolean bln) {
        //overriding the super interface
        super.updateItem(t, bln);

    }
}

Above Class is subclass of AbstractAnimatedListCell so you can implement this in your cellFactory. Currently AbstractAnimatedListCell is subclass of ListCell which helps to make the animation possible. Now Lets directly move to the animation implementation.

/**
 *
 * @author Narayan G. Maharjan <me@ngopal.com.np>
 */
public class ListViewAnimation extends Application {
    ObservableList list = FXCollections.observableArrayList();

    ListView<String> listView;

    ComboBox<AnimationType> box;

    HBox hbox;

    AnchorPane root;

    Button btn;

    /**
     * For initializing Containers
     */
    public void initContainers() {
        root = new AnchorPane();
        hbox = new HBox(10);

        AnchorPane.setBottomAnchor(listView, 50d);
        AnchorPane.setTopAnchor(listView, 10d);
        AnchorPane.setLeftAnchor(listView, 10d);
        AnchorPane.setRightAnchor(listView, 10d);
        AnchorPane.setBottomAnchor(hbox, 10d);
        AnchorPane.setLeftAnchor(hbox, 10d);
    }

    /**
     * For initializing controls
     */
    public void initControls() {
        listView = new ListView<>();
        listView.setCellFactory(AnimatedListCell.forListView(AnimationType.ROTATE_RIGHT, AnimationType.FADE_OUT));


        box = new ComboBox<>();
        box.valueProperty().addListener(new ChangeListener<AnimationType>() {
            @Override
            public void changed(
                    ObservableValue<? extends AnimationType> ov, AnimationType t, AnimationType t1) {
                if (!t1.equals(t)) {
                    listView.setCellFactory(AnimatedListCell.forListView(t1));
                }
            }
        });

        btn = new Button("Add New");
        btn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                list.add("Added New");
            }
        });


    }

    @Override
    public void start(Stage stage) throws Exception {
        //Loading custom fonts
        Font.loadFont(getClass().getResource("fonts/segoesc.ttf").toExternalForm(), 12);

        //adding values to list
        for (int i = 0; i < 10; i++) {
            list.add("" + i);
        }

        //Initializing Controls
        initControls();
        initContainers();

        //Adding Values
        listView.setItems(list);
        box.getItems().addAll(AnimationType.values());

        //Adding controls to container
        hbox.getChildren().addAll(new Label("Animation Type:"), box, btn);
        root.getChildren().addAll(listView, hbox);

        Scene scene = new Scene(root);
        scene.getStylesheets().add(getClass().getResource("css/style.css").toExternalForm());
        scene.setCamera(new PerspectiveCamera());
        stage.setTitle("List Animation!");
        stage.setScene(scene);
        stage.show();

    }

    public static void main(String[] args) {
        launch(args);
    }
}

Well after implementing those Animation you can get animation instantly on list cell update . However I have added some few styling to make it even more better.

If you want to try out yourself . Grab the source code from here:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值