blob: 874fe2790241ac235871322a912cb05088f64368 [file] [log] [blame]
package com.airbnb.lottie.samples;
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.LottieComposition;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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 LottieFontViewGroup.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 LottieFontViewGroup.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;
}
}