lottie动画效果使用简例

lottie开源库的诞生为我们动画的设置可谓提供了很大的便利,我们可以直接使用设计师用AE产生的json格式动画坐标,进行操作,简单快捷……

20170221222116162.gif

1、 引入Lottie

dependencies {  
  compile 'com.airbnb.android:lottie:1.0.3'
}   

2、在MainActivity中创建4中效果页面

package cn.hnshangyu.lottie;

import android.os.Bundle;
import android.os.SystemClock;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;

import java.util.ArrayList;

import butterknife.Bind;
import butterknife.ButterKnife;
import cn.hnshangyu.lottie.adapter.ViewPagerAdapter;
import cn.hnshangyu.lottie.fragment.PageFourFragment;
import cn.hnshangyu.lottie.fragment.PageOneFragment;
import cn.hnshangyu.lottie.fragment.PageThreeFragment;
import cn.hnshangyu.lottie.fragment.PageTwoFragment;

public class MainActivity extends AppCompatActivity {

    @Bind(R.id.toolbar)
    Toolbar toolbar;
    @Bind(R.id.toolbar_tab)
    TabLayout toolbarTab;
    @Bind(R.id.appbar_layout)
    AppBarLayout appbarLayout;
    @Bind(R.id.viewpager)
    ViewPager viewpager;
    private Snackbar snackbar;
    private static ArrayList<Fragment> fragmentList = new ArrayList<>();
    private ViewPagerAdapter viewPagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        // 用toolBar替换ActionBar
        setToolBarReplaceActionBar();
        //创建fragment
        createFragment();

        // 给viewpager设置适配器
        setViewPagerAdapter();

        //tablayout和viewpager建立联系
        setTabBindViewPager();
    }


    /**
     * 用toolBar替换ActionBar
     */
    private void setToolBarReplaceActionBar() {
        setSupportActionBar(toolbar);
        //显示系统返回箭头
        // getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        toolbar.setNavigationIcon(R.drawable.ic_back);
        //去除系统标题
        getSupportActionBar().setDisplayShowTitleEnabled(false);
        toolbar.setTitle(" 黄晓果");
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                snackbar = Snackbar.make(view, "确定要退出程序吗?", Snackbar.LENGTH_INDEFINITE);
                snackbar.setAction("退出", new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        MainActivity.this.finish();

                    }
                }).show();
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        SystemClock.sleep(3000);
                        if (snackbar != null && snackbar.isShown())
                            snackbar.dismiss();
                    }
                }).start();
            }
        });
    }

    /**
     * 创建fragment
     */
    private void createFragment() {
        fragmentList.add(PageOneFragment.newInstance("方式一"));
        fragmentList.add(PageTwoFragment.newInstance("方式二"));
        fragmentList.add(PageThreeFragment.newInstance("方式三"));
        fragmentList.add(PageFourFragment.newInstance("方式四"));
    }

    /**
     * 给viewpager设置适配器
     */
    private void setViewPagerAdapter() {
        viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(), fragmentList);
        viewpager.setAdapter(viewPagerAdapter);
    }

    /**
     * tablayout和viewpager建立联系
     */
    private void setTabBindViewPager() {
        //tablayout和viewpager建立联系方式一:tab与viewpager之间的相互绑定
//         viewpager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(toolbarTab));
//         toolbarTab.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewpager));


        //tablayout和viewpager建立联系方式二: 使用此方法Tablayout中的TabItem设置icon无效
        // (android:icon="@drawable/tab_selector" )只能使用 android:text="分享"
        //并且在ViewPagerAdapter中必须重写getPageTitle方法,不然无效
        toolbarTab.setupWithViewPager(viewpager);
    }

}

3、资产目录如下所示:(主要放置。json文件)

20170221224933651.png

效果一、lottie简单动画实现

A. 布局如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary">

    <com.airbnb.lottie.LottieAnimationView
        android:id="@+id/animation_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center" />
    <!--添加播放源,注意资源在assets中-->
    <!--app:lottie_fileName="Logo/LogoSmall.json"-->

    <!--是否循环播放-->
    <!-- app:lottie_loop="true"-->

    <!--自动播放-->
    <!--app:lottie_autoPlay="true"-->
</FrameLayout>

B. 实现动画播放:

package cn.hnshangyu.lottie.fragment;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.airbnb.lottie.LottieAnimationView;

import butterknife.Bind;
import butterknife.ButterKnife;
import cn.hnshangyu.lottie.R;

public class PageOneFragment extends Fragment {
    public static final String ARG_PAGE = "MESSAGE";
    @Bind(R.id.animation_view)
    LottieAnimationView animationView;

    private String mPage;

    public static PageOneFragment newInstance(String message) {
        Bundle args = new Bundle();
        args.putString(ARG_PAGE, message);
        PageOneFragment pageFragment = new PageOneFragment();
        pageFragment.setArguments(args);
        return pageFragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPage = getArguments().getString(ARG_PAGE);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
            savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_one_page, null);
        ButterKnife.bind(this, view);

        return view;
    }

    /**
     * 播放动画
     */
    @Override
    public void onResume() {
        super.onResume();
        animationView.setProgress(0f);

        //添加播放源  或app:lottie_fileName="Logo/LogoSmall.json"
        animationView.setAnimation("Logo/LogoSmall.json");

        //是否循环播放 或app:lottie_loop="true"
        animationView.loop(true);

        //开始播放 或app:lottie_autoPlay="true"
        animationView.playAnimation();
    }

    /**
     * 停止动画
     */
    @Override
    public void onPause() {
        super.onPause();
        animationView.cancelAnimation();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        ButterKnife.unbind(this);
    }
}

效果二、动画播放的监听

A.布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.airbnb.lottie.LottieAnimationView
        android:id="@+id/animation_view"
        android:layout_width="200dp"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp"
        android:layout_height="200dp" />

    <Button
        android:id="@+id/start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="start" />
    <Button
        android:id="@+id/stop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_below="@id/start"
        android:layout_centerInParent="true"
        android:text="stop" />
</RelativeLayout>

B.实现监听接口:

package cn.hnshangyu.lottie.fragment;

import android.animation.Animator;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import com.airbnb.lottie.LottieAnimationView;

import butterknife.Bind;
import butterknife.ButterKnife;
import cn.hnshangyu.lottie.R;

public class PageTwoFragment extends Fragment {
    public static final String ARG_PAGE = "MESSAGE";
    @Bind(R.id.animation_view)
    LottieAnimationView animationView;
    @Bind(R.id.start)
    Button start;
    @Bind(R.id.stop)
    Button stop;

    private String mPage;
    private String[] JsonList = new String[]{"Mobilo/A.json", "Mobilo/B.json", "Mobilo/C.json", "Mobilo/D.json",
            "Mobilo/E.json", "Mobilo/F.json", "Mobilo/G.json", "Mobilo/F.json", "Mobilo/I.json", "Mobilo/J.json", "Mobilo/K.json",
            "Mobilo/L.json", "Mobilo/M.json", "Mobilo/N.json", "Mobilo/O.json", "Mobilo/P.json", "Mobilo/Q.json", "Mobilo/R.json",
            "Mobilo/S.json", "Mobilo/T.json", "Mobilo/U.json", "Mobilo/V.json", "Mobilo/W.json", "Mobilo/X.json", "Mobilo/Y.json", "Mobilo/Z.json"};

    public static PageTwoFragment newInstance(String message) {
        Bundle args = new Bundle();
        args.putString(ARG_PAGE, message);
        PageTwoFragment pageFragment = new PageTwoFragment();
        pageFragment.setArguments(args);
        return pageFragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPage = getArguments().getString(ARG_PAGE);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
            savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_two_page, null);

        ButterKnife.bind(this, view);
        initListener();
        return view;
    }

    private void initListener() {
        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                animationView.removeAnimatorListener(myAnimatorListener);
                animationPosition = 0;
                startAnimation();
            }
        });
        stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                animationPosition = JsonList.length + 1;
                animationView.cancelAnimation();
            }
        });
    }

    private int animationPosition = 0;

    /**
     * 播放动画
     */
    private void startAnimation() {
        animationView.setProgress(0f);
        //添加播放源
        animationView.setAnimation(JsonList[animationPosition]);
        //是否循环播放
        animationView.loop(false);
        //开始播放
        animationView.playAnimation();
        animationView.addAnimatorListener(myAnimatorListener);
    }

    private Animator.AnimatorListener myAnimatorListener = new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animator) {
            Log.e("huangxiaoguo", "onAnimationStart");
            //开始
            animationPosition = animationPosition + 1;
        }

        @Override
        public void onAnimationEnd(Animator animator) {
            Log.e("huangxiaoguo", "onAnimationEnd");
            //结束
            if (animationPosition < JsonList.length) {
                //添加播放源
                animationView.setAnimation(JsonList[animationPosition]);
                //是否循环播放
                animationView.loop(false);
                //开始播放
                animationView.playAnimation();
            } else if (animationPosition == JsonList.length) {
                animationPosition = 0;
                //添加播放源
                animationView.setAnimation(JsonList[animationPosition]);
                //是否循环播放
                animationView.loop(false);
                //开始播放
                animationView.playAnimation();
            }

        }

        @Override
        public void onAnimationCancel(Animator animator) {
            Log.e("huangxiaoguo", "onAnimationCancel");
            //取消
        }

        @Override
        public void onAnimationRepeat(Animator animator) {
            Log.e("huangxiaoguo", "onAnimationRepeat");
            //重复
        }
    };

    /**
     * 停止动画
     */
    @Override
    public void onPause() {
        super.onPause();
        animationPosition = JsonList.length + 1;
        animationView.cancelAnimation();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        ButterKnife.unbind(this);
    }
}

效果三、动画播放暂停,重新播放、循环播放等一系列设置

A、布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <com.airbnb.lottie.LottieAnimationView
            android:id="@+id/animation_view"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:duplicateParentState="true" />
        <android.support.v7.widget.AppCompatSeekBar
            android:id="@+id/seek_bar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="64dp"
            android:layout_marginRight="64dp" />
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:orientation="horizontal">

            <ImageButton
                android:id="@+id/restart"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="1"
                android:background="?selectableItemBackgroundBorderless"
                android:src="@drawable/ic_restart" />

            <ImageButton
                android:id="@+id/play_button"
                android:layout_width="48dp"
                android:layout_height="48dp"
                android:layout_gravity="center_vertical"
                android:layout_marginBottom="12dp"
                android:layout_marginLeft="12dp"
                android:layout_marginRight="12dp"
                android:layout_marginTop="12dp"
                android:background="@drawable/play_button_background"
                android:src="@drawable/ic_play_pause" />


            <ImageButton
                android:id="@+id/loop"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="1"
                android:background="?selectableItemBackgroundBorderless"
                android:src="@drawable/ic_loop" />

        </LinearLayout>

    </LinearLayout>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_margin="20dp"
        android:src="@drawable/ic_assets" />
</RelativeLayout>

B、实现代码

package cn.hnshangyu.lottie.fragment;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v7.widget.AppCompatSeekBar;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.SeekBar;

import com.airbnb.lottie.LottieAnimationView;
import com.airbnb.lottie.model.LottieComposition;

import butterknife.Bind;
import butterknife.ButterKnife;
import cn.hnshangyu.lottie.R;

public class PageThreeFragment extends Fragment implements View.OnClickListener {
    public static final String ARG_PAGE = "MESSAGE";
    public static final int GO_DISLOG = 212;
    public static final String EXTRA_ANIMATION_NAME = "animation_name";
    @Bind(R.id.animation_view)
    LottieAnimationView animationView;
    @Bind(R.id.restart)
    ImageButton restart;
    @Bind(R.id.play_button)
    ImageButton playButton;
    @Bind(R.id.loop)
    ImageButton loop;
    @Bind(R.id.fab)
    FloatingActionButton fab;
    @Bind(R.id.seek_bar)
    AppCompatSeekBar seekBar;

    private String mPage;
    private ChooseAssetDialogFragment chooseAssetDialogFragment;

    public static PageThreeFragment newInstance(String message) {
        Bundle args = new Bundle();
        args.putString(ARG_PAGE, message);
        PageThreeFragment pageFragment = new PageThreeFragment();
        pageFragment.setArguments(args);
        return pageFragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPage = getArguments().getString(ARG_PAGE);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
            savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_three_page, null);
        ButterKnife.bind(this, view);
        isPlaying = true;
        initListener();

        return view;
    }

    private void initListener() {
        fab.setOnClickListener(this);
        restart.setOnClickListener(this);
        playButton.setOnClickListener(this);
        loop.setOnClickListener(this);
        listener();
    }

    /**
     * 动画监听
     */
    private void listener() {
        /**
         * animationView控制seekBar
         */
        animationView.addAnimatorUpdateListener(myAnimatorUpdateListener);
        /**
         * seekBar控制animationView
         */
        seekBar.setOnSeekBarChangeListener(myOnSeekBarChangeListener);
        /**
         * 控制开关按钮状态
         */
        animationView.addAnimatorListener(myAnimatorListener);
    }

    /**
     * animationView控制seekBar
     */
    private ValueAnimator.AnimatorUpdateListener myAnimatorUpdateListener = new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            seekBar.setProgress((int) (valueAnimator.getAnimatedFraction() * 100));
        }
    };
    /**
     * seekBar控制animationView
     */
    private SeekBar.OnSeekBarChangeListener myOnSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            animationView.setProgress(progress / 100f);
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    };
    /**
     * 控制开关按钮状态
     */
    private Animator.AnimatorListener myAnimatorListener = new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animator) {

        }

        @Override
        public void onAnimationEnd(Animator animator) {
            if (isPlaying)
                seekBar.setProgress(0);
            playButton.setActivated(false);
        }

        @Override
        public void onAnimationCancel(Animator animator) {
            if (isPlaying)
                seekBar.setProgress(0);
            playButton.setActivated(false);
        }

        @Override
        public void onAnimationRepeat(Animator animator) {

        }
    };

    private boolean isPlaying = true;

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.fab://跳转到资源选择页面
                animationView.cancelAnimation();
                chooseAssetDialogFragment = ChooseAssetDialogFragment.newInstance();
                chooseAssetDialogFragment.setTargetFragment(this, GO_DISLOG);
                chooseAssetDialogFragment.show(getFragmentManager(), "assets");
                break;
            case R.id.loop://是否循环
                loop.setActivated(!loop.isActivated());
                //    animationView.loop(loopButton.isEnabled());
                animationView.loop(loop.isActivated());
                break;
            case R.id.restart://重新开始
                isPlaying = true;
                boolean restart = animationView.isAnimating();
                animationView.cancelAnimation();
                animationView.setProgress(0f);
                if (restart) {
                    animationView.playAnimation();
                }
                break;
            case R.id.play_button://播放与暂停
                isPlaying = false;
                if (animationView.isAnimating()) {
                    animationView.pauseAnimation();
                    postUpdatePlayButtonText();
                } else {
                    if (animationView.getProgress() == 1f) {
                        animationView.setProgress(0f);
                    }
                    animationView.playAnimation();
                    postUpdatePlayButtonText();
                }
                break;
        }
    }

    /**
     * 改变播放状态
     */
    private void postUpdatePlayButtonText() {
        playButton.setActivated(animationView.isAnimating());
    }

    /**
     * 回调
     *
     * @param requestCode
     * @param resultCode
     * @param data
     */
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != Activity.RESULT_OK) {
            return;
        }
        switch (requestCode) {
            case GO_DISLOG://资源选择回调
                final String assetName = data.getStringExtra(EXTRA_ANIMATION_NAME);
                LottieComposition.fromAssetFileName(getContext(), assetName,
                        new LottieComposition.OnCompositionLoadedListener() {
                            @Override
                            public void onCompositionLoaded(LottieComposition composition) {
                                setComposition(composition, assetName);
                            }
                        });
                break;
        }
    }

    /**
     * 播放动画
     *
     * @param composition
     * @param name
     */
    private void setComposition(LottieComposition composition, String name) {
        seekBar.setProgress(0);
        animationView.setComposition(composition);
        final Snackbar make = Snackbar.make(getView(), name, Snackbar.LENGTH_INDEFINITE);
        make.show();
        new Thread(new Runnable() {
            @Override
            public void run() {
                SystemClock.sleep(2000);
                if (make.isShown()) {
                    make.dismiss();
                }
            }
        }).start();
    }

    @Override
    public void onPause() {
        super.onPause();
        animationView.cancelAnimation();
        /**
         * animationView控制seekBar
         */
        animationView.removeUpdateListener(myAnimatorUpdateListener);
        /**
         * 控制开关按钮状态
         */
        animationView.removeAnimatorListener(myAnimatorListener);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        ButterKnife.unbind(this);
    }
}

C、ChooseAssetDialogFragment

package cn.hnshangyu.lottie.fragment;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.io.IOException;
import java.util.List;

import butterknife.Bind;
import butterknife.ButterKnife;
import cn.hnshangyu.lottie.R;
import cn.hnshangyu.lottie.adapter.MyAdapter;
import cn.hnshangyu.lottie.utils.AssetUtils;

/**
 * 选择资源
 */
public class ChooseAssetDialogFragment extends DialogFragment {

    @Bind(R.id.recycler_view)
    RecyclerView recyclerView;
    private List<String> jsonAssets;
    private MyAdapter mAdapter;
    private Fragment targetFragment;

    public static ChooseAssetDialogFragment newInstance() {
        return new ChooseAssetDialogFragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_choose_asset, container, false);
        ButterKnife.bind(this, view);
        initData();
        initView();
        initListener();
        return view;
    }


    private void initData() {
        getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        targetFragment = getTargetFragment();
        try {
            jsonAssets = AssetUtils.getJsonAssets(getContext(), "");

        } catch (IOException e) {
            e.printStackTrace();
            Snackbar.make(getView(), "未找到资源", Snackbar.LENGTH_LONG).show();
        }
    }

    private void initView() {
        if (jsonAssets != null) {
            mAdapter = new MyAdapter(getContext(), jsonAssets);
            recyclerView.setAdapter(mAdapter);
        }
    }

    private void initListener() {
        if (mAdapter != null) {
            mAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {
                @Override
                public void OnClick(int position) {
                    targetFragment.onActivityResult(getTargetRequestCode(), Activity.RESULT_OK,
                            new Intent().putExtra(PageThreeFragment.EXTRA_ANIMATION_NAME, jsonAssets.get(position)));
                    dismiss();
                }

            });
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        ButterKnife.unbind(this);
    }
}

D、获取Assets的资源

package cn.hnshangyu.lottie.utils;

import android.content.Context;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 获取Assets的资源
 */
public  class AssetUtils {

    public  static List<String> getJsonAssets(Context context, String path) throws IOException {
        String[] assetList = context.getAssets().list(path);
        List<String> files = new ArrayList<>();
        for (String asset : assetList) {
            if (asset.toLowerCase().endsWith(".json")) {
                files.add(asset);
            }
        }
        return files;
    }
}

效果四、 字体输入时效果:

A、布局

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scroll_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:paddingTop="16dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="20dp"
            android:text="请输入字母:"
            android:textColor="@color/colorAccent"
            android:textSize="24sp" />

        <cn.hnshangyu.lottie.view.LottieFontViewGroup
            android:id="@+id/font_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </LinearLayout>
</ScrollView>

B、自定义LottieFontViewGroup

package cn.hnshangyu.lottie.view;

import android.content.Context;
import android.support.annotation.Nullable;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.FrameLayout;

import com.airbnb.lottie.LottieAnimationView;
import com.airbnb.lottie.model.LottieComposition;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.hnshangyu.lottie.R;

public class LottieFontViewGroup extends FrameLayout {
  private final Map<String, LottieComposition> compositionMap = new HashMap<>();
  private final List<View> views = new ArrayList<>();

  @Nullable private LottieAnimationView cursorView;

  public LottieFontViewGroup(Context context) {
    super(context);
    init();
  }

  public LottieFontViewGroup(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
  }

  public LottieFontViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
  }

  private void init() {
    setFocusableInTouchMode(true);
    LottieComposition.fromAssetFileName(getContext(), "Mobilo/BlinkingCursor.json",
        new LottieComposition.OnCompositionLoadedListener() {
          @Override
          public void onCompositionLoaded(LottieComposition composition) {
            cursorView = new LottieAnimationView(getContext());
            cursorView.setLayoutParams(new LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT
            ));
            cursorView.setComposition(composition);
            cursorView.loop(true);
            cursorView.playAnimation();
            addView(cursorView);
          }
        });
  }

  private void addSpace() {
    int index = indexOfChild(cursorView);
    addView(createSpaceView(), index);
  }

  @Override
  public void addView(View child, int index) {
    super.addView(child, index);
    if (index == -1) {
      views.add(child);
    } else {
      views.add(index, child);
    }
  }

  private void removeLastView() {
    if (views.size() > 1) {
      int position = views.size() - 2;
      removeView(views.get(position));
      views.remove(position);
    }
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    if (views.isEmpty()) {
      return;
    }
    int currentX = getPaddingTop();
    int currentY = getPaddingLeft();

    for (int i = 0; i < views.size(); i++) {
      View view = views.get(i);
      if (!fitsOnCurrentLine(currentX, view)) {
        if (view.getTag() != null && view.getTag().equals("Space")) {
          continue;
        }
        currentX = getPaddingLeft();
        currentY += view.getMeasuredHeight();
      }
      currentX += view.getWidth();
    }

    setMeasuredDimension(getMeasuredWidth(),
        currentY + views.get(views.size() - 1).getMeasuredHeight() * 2);
  }

  @Override
  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    if (views.isEmpty()) {
      return;
    }
    int currentX = getPaddingTop();
    int currentY = getPaddingLeft();

    for (int i = 0; i < views.size(); i++) {
      View view = views.get(i);
      if (!fitsOnCurrentLine(currentX, view)) {
        if (view.getTag() != null && view.getTag().equals("Space")) {
          continue;
        }
        currentX = getPaddingLeft();
        currentY += view.getMeasuredHeight();
      }
      view.layout(currentX, currentY, currentX + view.getMeasuredWidth(),
          currentY + view.getMeasuredHeight());
      currentX += view.getWidth();
    }
  }

  @Override
  public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
    BaseInputConnection fic = new BaseInputConnection(this, false);
    outAttrs.actionLabel = null;
    outAttrs.inputType = InputType.TYPE_NULL;
    outAttrs.imeOptions = EditorInfo.IME_ACTION_NEXT;
    return fic;
  }

  @Override
  public boolean onCheckIsTextEditor() {
    return true;
  }

  @Override
  public boolean onKeyUp(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_SPACE) {
      addSpace();
      return true;
    }

    if (keyCode == KeyEvent.KEYCODE_DEL) {
      removeLastView();
      return true;
    }

    if (!isValidKey(event)) {
      return super.onKeyUp(keyCode, event);
    }


    String letter = "" + Character.toUpperCase((char) event.getUnicodeChar());
    // switch (letter) {
    //     case ",":
    //         letter = "Comma";
    //         break;
    //     case "'":
    //         letter = "Apostrophe";
    //         break;
    //     case ";":
    //     case ":":
    //         letter = "Colon";
    //         break;
    // }
    final String fileName = "Mobilo/" + letter + ".json";
    if (compositionMap.containsKey(fileName)) {
      addComposition(compositionMap.get(fileName));
    } else {
      LottieComposition.fromAssetFileName(getContext(), fileName,
          new LottieComposition.OnCompositionLoadedListener() {
            @Override
            public void onCompositionLoaded(LottieComposition composition) {
              compositionMap.put(fileName, composition);
              addComposition(composition);
            }
          });
    }

    return true;
  }

  private boolean isValidKey(KeyEvent event) {
    if (!event.hasNoModifiers()) {
      return false;
    }
    if (event.getKeyCode() >= KeyEvent.KEYCODE_A && event.getKeyCode() <= KeyEvent.KEYCODE_Z) {
      return true;
    }

    // switch (keyCode) {
    //     case KeyEvent.KEYCODE_COMMA:
    //     case KeyEvent.KEYCODE_APOSTROPHE:
    //     case KeyEvent.KEYCODE_SEMICOLON:
    //         return true;
    // }
    return false;
  }

  private void addComposition(LottieComposition composition) {
    LottieAnimationView lottieAnimationView = new LottieAnimationView(getContext());
    lottieAnimationView.setLayoutParams(new LayoutParams(
        ViewGroup.LayoutParams.WRAP_CONTENT,
        ViewGroup.LayoutParams.WRAP_CONTENT
    ));
    lottieAnimationView.setComposition(composition);
    lottieAnimationView.playAnimation();
    if (cursorView == null) {
      addView(lottieAnimationView);
    } else {
      int index = indexOfChild(cursorView);
      addView(lottieAnimationView, index);
    }
  }

  private boolean fitsOnCurrentLine(int currentX, View view) {
    return currentX + view.getMeasuredWidth() < getWidth() - getPaddingRight();
  }

  private View createSpaceView() {
    View spaceView = new View(getContext());
    spaceView.setLayoutParams(new LayoutParams(
        getResources().getDimensionPixelSize(R.dimen.font_space_width),
        ViewGroup.LayoutParams.WRAP_CONTENT
    ));
    spaceView.setTag("Space");
    return spaceView;
  }
}

B、实现代码:

package cn.hnshangyu.lottie.fragment;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.ScrollView;

import butterknife.Bind;
import butterknife.ButterKnife;
import cn.hnshangyu.lottie.R;
import cn.hnshangyu.lottie.view.LottieFontViewGroup;

public class PageFourFragment extends Fragment {
    public static final String ARG_PAGE = "MESSAGE";
    @Bind(R.id.font_view)
    LottieFontViewGroup fontView;
    @Bind(R.id.scroll_view)
    ScrollView scrollView;

    private String mPage;

    public static PageFourFragment newInstance(String message) {
        Bundle args = new Bundle();
        args.putString(ARG_PAGE, message);
        PageFourFragment pageFragment = new PageFourFragment();
        pageFragment.setArguments(args);
        return pageFragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPage = getArguments().getString(ARG_PAGE);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
            savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_four_page, null);
        ButterKnife.bind(this, view);
        fontView.getViewTreeObserver().addOnGlobalLayoutListener(layoutListener);
        return view;
    }

    private ViewTreeObserver.OnGlobalLayoutListener layoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            scrollView.fullScroll(View.FOCUS_DOWN);
        }
    };

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        fontView.getViewTreeObserver().removeOnGlobalLayoutListener(layoutListener);
        ButterKnife.unbind(this);
    }
}

Demo下载地址:http://download.csdn.net/download/huangxiaoguo1/9760109

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352

推荐阅读更多精彩内容