2 * Copyright 2018 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 package org.skia.skottie;
10 import android.app.Activity;
11 import android.content.Intent;
12 import android.graphics.Color;
13 import android.graphics.Point;
14 import android.net.Uri;
15 import android.os.Bundle;
16 import android.view.View;
17 import android.view.ViewGroup;
18 import android.widget.Button;
19 import android.widget.GridLayout;
21 import java.io.FileNotFoundException;
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.concurrent.CountDownLatch;
25 import java.util.concurrent.TimeUnit;
26 import java.util.concurrent.TimeoutException;
28 import static java.lang.Math.ceil;
29 import static java.lang.Math.sqrt;
31 public class SkottieActivity extends Activity implements View.OnClickListener {
33 private final static long TIME_OUT_MS = 10000;
35 private CountDownLatch mEnterAnimationFence = new CountDownLatch(1);
37 private GridLayout mGrid;
38 private int mRowCount = 0;
39 private int mColumnCount = 0;
40 private int mCellWidth = 0;
41 private int mCellHeight = 0;
43 private List<SkottieView> mAnimations;
44 static private List<Uri> mAnimationFiles = new ArrayList<Uri>();
46 private void populateGrid() {
49 mAnimations = new ArrayList<SkottieView>();
54 R.raw.star, R.raw.movie_loading, R.raw.uk, R.raw.white_material_wave_loading
57 for (int resId : rawAssets) {
58 SkottieView view = new SkottieView(this);
59 view.setSource(resId);
60 mAnimations.add(view);
63 for (Uri uri : mAnimationFiles) {
65 SkottieView view = new SkottieView(this);
66 view.setSource(this, uri);
67 mAnimations.add(view);
68 } catch (FileNotFoundException e) {
73 Point size = new Point();
74 getWindowManager().getDefaultDisplay().getSize(size);
75 int screenWidth = size.x;
76 int screenHeight = (int)(size.y / 1.3f);
78 double unit = sqrt(mAnimations.size() / 6.0f);
79 mRowCount = (int)ceil(3 * unit);
80 mColumnCount = (int)ceil(2 * unit);
81 mGrid.setColumnCount(mColumnCount);
82 mGrid.setRowCount(mRowCount);
83 mCellWidth = screenWidth / mColumnCount;
84 mCellHeight = screenHeight / mRowCount;
90 for (SkottieView view : mAnimations) {
91 view.setOnClickListener(new View.OnClickListener(){
92 public void onClick(View view){
93 inflateView((SkottieView)view);
98 if (mInflatedIndex >= 0) {
99 SkottieView view = mAnimations.get(mInflatedIndex);
105 static int mInflatedIndex = -1;
107 private void inflateView(SkottieView view) {
108 if (mInflatedIndex >= 0) {
109 //deflate active view
110 SkottieView oldView = mAnimations.get(mInflatedIndex);
111 if (oldView != null) {
112 int row = mInflatedIndex / mColumnCount, column = mInflatedIndex % mColumnCount;
113 addView(oldView, row, column, false);
116 //start and show animations that were in the background
117 for (SkottieView anyView : mAnimations) {
118 if (anyView != oldView) {
120 anyView.setVisibility(View.VISIBLE);
126 //stop and hide animations in the background
127 for (SkottieView anyView : mAnimations) {
128 if (anyView != view) {
130 anyView.setVisibility(View.INVISIBLE);
134 mInflatedIndex = mAnimations.indexOf(view);
136 GridLayout.Spec rowSpec = GridLayout.spec(0, mRowCount, GridLayout.CENTER);
137 GridLayout.Spec colSpec = GridLayout.spec(0, mColumnCount, GridLayout.CENTER);
138 GridLayout.LayoutParams params = new GridLayout.LayoutParams(rowSpec, colSpec);
139 params.width = ViewGroup.LayoutParams.MATCH_PARENT;
140 params.height = ViewGroup.LayoutParams.MATCH_PARENT;
142 mGrid.updateViewLayout(view, params);
145 private void refreshGrid() {
146 mGrid.removeAllViews();
148 int row = 0, column = 0;
149 for (SkottieView view : mAnimations) {
150 addView(view, row, column, true);
152 if (column >= mColumnCount) {
159 private void addView(SkottieView view, int row , int column, boolean addView) {
160 GridLayout.Spec rowSpec = GridLayout.spec(row, 1, GridLayout.CENTER);
161 GridLayout.Spec colSpec = GridLayout.spec(column, 1, GridLayout.CENTER);
162 GridLayout.LayoutParams params = new GridLayout.LayoutParams(rowSpec, colSpec);
163 params.width = mCellWidth;
164 params.height = mCellHeight;
166 mGrid.addView(view, params);
168 mGrid.updateViewLayout(view, params);
172 private void startAnimation() {
173 for (SkottieView view : mAnimations) {
178 private void stopAnimation() {
179 for (SkottieView view : mAnimations) {
184 private void addLottie(Uri uri) throws FileNotFoundException {
185 int animations = mAnimations.size();
186 if (animations < mRowCount * mColumnCount) {
187 SkottieView view = new SkottieView(this);
188 view.setSource(this, uri);
189 int row = animations / mColumnCount, column = animations % mColumnCount;
190 mAnimations.add(view);
191 mAnimationFiles.add(uri);
192 view.setOnClickListener(new View.OnClickListener(){
193 public void onClick(View view){
194 inflateView((SkottieView)view);
197 addView(view, row, column, true);
201 mAnimationFiles.add(uri);
209 public void onEnterAnimationComplete() {
210 super.onEnterAnimationComplete();
211 mEnterAnimationFence.countDown();
214 public void waitForEnterAnimationComplete() throws TimeoutException, InterruptedException {
215 if (!mEnterAnimationFence.await(TIME_OUT_MS, TimeUnit.MILLISECONDS)) {
216 throw new TimeoutException();
220 private void createLayout() {
221 setContentView(R.layout.main_layout);
222 Button open = (Button)findViewById(R.id.open_lottie);
223 open.setOnClickListener(this);
225 Button play = (Button)findViewById(R.id.play);
226 play.setOnClickListener(this);
227 Button pause = (Button)findViewById(R.id.pause);
228 pause.setOnClickListener(this);
229 Button reset = (Button)findViewById(R.id.reset);
230 reset.setOnClickListener(this);
232 mGrid = (GridLayout)findViewById(R.id.grid_lotties);
233 mGrid.setBackgroundColor(Color.LTGRAY);
239 protected void onCreate(Bundle savedInstanceState) {
240 super.onCreate(savedInstanceState);
246 protected void onDestroy() {
250 static final int PICK_FILE_REQUEST = 2;
253 public void onClick(View view) {
254 switch(view.getId()) {
255 case R.id.open_lottie:
256 Intent intent = new Intent();
257 intent.setType("application/json");
258 Intent i = Intent.createChooser(intent, "View Default File Manager");
259 startActivityForResult(i, PICK_FILE_REQUEST);
262 for (SkottieView anim : mAnimations) {
267 for (SkottieView anim : mAnimations) {
272 for (SkottieView anim : mAnimations) {
281 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
282 super.onActivityResult(requestCode, resultCode, data);
283 if (resultCode == Activity.RESULT_OK) {
284 if (requestCode == PICK_FILE_REQUEST) if (data != null) {
286 Uri uri = data.getData();
290 } catch (FileNotFoundException e) {