lottie动画效果使用简例

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

  • 那么首先我们来看看效果:

  • 引入Lottie
dependencies {  
  compile 'com.airbnb.android:lottie:1.0.3'
}
  • 在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 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);
    }

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

lottie动画效果使用简例_第1张图片

效果一、lottie简单动画实现

 1. 布局如下:

<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" />
    
    

    
    

    
    
FrameLayout>
 2. 实现动画播放:
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);
    }
}

效果二、动画播放的监听

1.布局文件

<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>
2.实现监听接口:
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);
    }
}

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

  • 布局文件

<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>
  • 实现代码
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);
    }
}
  • 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 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);
    }
}
  • 获取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 getJsonAssets(Context context, String path) throws IOException {
        String[] assetList = context.getAssets().list(path);
        List files = new ArrayList<>();
        for (String asset : assetList) {
            if (asset.toLowerCase().endsWith(".json")) {
                files.add(asset);
            }
        }
        return files;
    }
}

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

  • 布局

<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>
  • 自定义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 compositionMap = new HashMap<>();
  private final List 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;
  }
}
  • 实现代码:
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

你可能感兴趣的:(android学习)