补充注释及移除部分未用到代码
This commit is contained in:
parent
d2bb4e4375
commit
1e98de9931
@ -17,8 +17,10 @@ import com.faceunity.core.callback.OperateCallback;
|
|||||||
import com.faceunity.core.entity.FURenderOutputData;
|
import com.faceunity.core.entity.FURenderOutputData;
|
||||||
import com.faceunity.core.enumeration.CameraFacingEnum;
|
import com.faceunity.core.enumeration.CameraFacingEnum;
|
||||||
import com.faceunity.core.enumeration.FUAIProcessorEnum;
|
import com.faceunity.core.enumeration.FUAIProcessorEnum;
|
||||||
|
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||||||
import com.faceunity.core.enumeration.FUInputTextureEnum;
|
import com.faceunity.core.enumeration.FUInputTextureEnum;
|
||||||
import com.faceunity.core.enumeration.FUTransformMatrixEnum;
|
import com.faceunity.core.enumeration.FUTransformMatrixEnum;
|
||||||
|
import com.faceunity.core.faceunity.FUAIKit;
|
||||||
import com.faceunity.core.faceunity.FURenderManager;
|
import com.faceunity.core.faceunity.FURenderManager;
|
||||||
import com.faceunity.core.utils.CameraUtils;
|
import com.faceunity.core.utils.CameraUtils;
|
||||||
import com.faceunity.core.utils.FULogger;
|
import com.faceunity.core.utils.FULogger;
|
||||||
@ -41,7 +43,7 @@ import cn.rongcloud.rtc.api.callback.IRCRTCVideoOutputFrameListener;
|
|||||||
import cn.rongcloud.rtc.base.RCRTCVideoFrame;
|
import cn.rongcloud.rtc.base.RCRTCVideoFrame;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 美颜模块管理类,接入测试中
|
* 美颜模块管理类
|
||||||
*/
|
*/
|
||||||
public class FaceManager implements SensorEventListener {
|
public class FaceManager implements SensorEventListener {
|
||||||
private static boolean isInit = false;
|
private static boolean isInit = false;
|
||||||
@ -75,7 +77,6 @@ public class FaceManager implements SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private FURenderer mFURenderer;
|
private FURenderer mFURenderer;
|
||||||
private FaceUnityView faceUnityView;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 配置美颜SDK
|
* 配置美颜SDK
|
||||||
@ -98,13 +99,8 @@ public class FaceManager implements SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绑定控制view
|
* 监听人脸识别个数
|
||||||
*/
|
*/
|
||||||
public void bindControlView(FaceUnityView view) {
|
|
||||||
this.faceUnityView = view;
|
|
||||||
faceUnityView.bindDataFactory(mFaceUnityDataFactory);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFaceStatusChanged(FaceStatusChanged faceStatusChanged) {
|
public void setFaceStatusChanged(FaceStatusChanged faceStatusChanged) {
|
||||||
this.faceStatusChanged = faceStatusChanged;
|
this.faceStatusChanged = faceStatusChanged;
|
||||||
}
|
}
|
||||||
@ -220,6 +216,21 @@ public class FaceManager implements SensorEventListener {
|
|||||||
RCRTCEngine.getInstance().getDefaultVideoStream().setVideoFrameListener(null);
|
RCRTCEngine.getInstance().getDefaultVideoStream().setVideoFrameListener(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 释放资源
|
||||||
|
*/
|
||||||
|
public void release() {
|
||||||
|
mFURenderer.release();
|
||||||
|
try {
|
||||||
|
for (FUAITypeEnum value : FUAITypeEnum.values()) {
|
||||||
|
FUAIKit.getInstance().releaseAIProcessor(value);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public interface FaceStatusChanged {
|
public interface FaceStatusChanged {
|
||||||
void onFaceChanged(int num);
|
void onFaceChanged(int num);
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,9 @@ import com.yunbao.faceunity.utils.FaceSPUtils;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 美颜配置适配器
|
||||||
|
*/
|
||||||
public class ContainerRecyclerAdapter extends RecyclerView.Adapter<BaseViewHolder> {
|
public class ContainerRecyclerAdapter extends RecyclerView.Adapter<BaseViewHolder> {
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
@ -223,18 +226,30 @@ public class ContainerRecyclerAdapter extends RecyclerView.Adapter<BaseViewHolde
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存配置
|
||||||
|
*/
|
||||||
public void save(String key, String data) {
|
public void save(String key, String data) {
|
||||||
FaceSPUtils.getInstance().saveString(key, data);
|
FaceSPUtils.getInstance().saveString(key, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取配置
|
||||||
|
*/
|
||||||
public String getString(String key) {
|
public String getString(String key) {
|
||||||
return FaceSPUtils.getInstance().getString(key);
|
return FaceSPUtils.getInstance().getString(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除配置
|
||||||
|
*/
|
||||||
public void del(String key) {
|
public void del(String key) {
|
||||||
FaceSPUtils.getInstance().del(key);
|
FaceSPUtils.getInstance().del(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 恢复默认设置
|
||||||
|
*/
|
||||||
public void reset() {
|
public void reset() {
|
||||||
if (vh != null) {
|
if (vh != null) {
|
||||||
vh.reset(list);
|
vh.reset(list);
|
||||||
|
@ -16,6 +16,9 @@ import com.yunbao.faceunity.entity.MenuGroupBean;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主菜单适配器
|
||||||
|
*/
|
||||||
public class MenuGroupRecyclerAdapter extends RecyclerView.Adapter<MenuGroupRecyclerAdapter.Vh> {
|
public class MenuGroupRecyclerAdapter extends RecyclerView.Adapter<MenuGroupRecyclerAdapter.Vh> {
|
||||||
private Context context;
|
private Context context;
|
||||||
private List<MenuGroupBean> list;
|
private List<MenuGroupBean> list;
|
||||||
|
@ -33,8 +33,20 @@ public abstract class BaseViewHolder extends RecyclerView.ViewHolder {
|
|||||||
|
|
||||||
public abstract void setData(BaseBean data);
|
public abstract void setData(BaseBean data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取配置
|
||||||
|
* @return 是否有保存的配置
|
||||||
|
*/
|
||||||
public abstract boolean loadData();
|
public abstract boolean loadData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存配置
|
||||||
|
*/
|
||||||
public abstract void saveData();
|
public abstract void saveData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 恢复默认配置
|
||||||
|
*/
|
||||||
public abstract void reset(List<? extends BaseBean> list);
|
public abstract void reset(List<? extends BaseBean> list);
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,57 +0,0 @@
|
|||||||
package com.yunbao.faceunity.base;
|
|
||||||
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DESC:RecycleView 通用业务调用
|
|
||||||
* Created on 2021/4/26
|
|
||||||
*/
|
|
||||||
public abstract class BaseDelegate<T> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据页面以及数据内容返回Item的布局index,默认返回第一个布局
|
|
||||||
*
|
|
||||||
* @param data
|
|
||||||
* @param position
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public int getItemViewType(T data, int position) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为ViewHolder绑定数据item
|
|
||||||
*
|
|
||||||
* @param viewType
|
|
||||||
* @param helper
|
|
||||||
* @param data
|
|
||||||
* @param position
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public abstract void convert(int viewType, BaseViewHolder helper, T data, int position);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 绑定单击事件
|
|
||||||
*
|
|
||||||
* @param view
|
|
||||||
* @param data
|
|
||||||
* @param position
|
|
||||||
*/
|
|
||||||
public void onItemClickListener(View view, T data, int position) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 绑定长按事件
|
|
||||||
*
|
|
||||||
* @param view
|
|
||||||
* @param data
|
|
||||||
* @param position
|
|
||||||
*/
|
|
||||||
public boolean onItemLongClickListener(View view, T data, int position) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,101 +0,0 @@
|
|||||||
package com.yunbao.faceunity.base;
|
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import com.yunbao.faceunity.listener.OnMultiClickListener;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DESC:RecycleView 通用适配器
|
|
||||||
* Created on 2021/4/26
|
|
||||||
*/
|
|
||||||
public class BaseListAdapter<T> extends RecyclerView.Adapter<BaseViewHolder> {
|
|
||||||
private ArrayList<T> data;
|
|
||||||
private BaseDelegate<T> viewHolderDelegate;
|
|
||||||
private int[] mLayouts;
|
|
||||||
private HashMap<Integer, BaseViewHolder> mViewHolder = new HashMap<>();
|
|
||||||
|
|
||||||
public BaseListAdapter(ArrayList<T> data, BaseDelegate<T> viewHolderDelegate, int... resLayouts) {
|
|
||||||
mLayouts = resLayouts;
|
|
||||||
this.data = data;
|
|
||||||
this.viewHolderDelegate = viewHolderDelegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
|
|
||||||
View view = LayoutInflater.from(viewGroup.getContext()).inflate(getLayoutId(viewType), viewGroup, false);
|
|
||||||
return new BaseViewHolder(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull BaseViewHolder holder, int position) {
|
|
||||||
mViewHolder.put(position, holder);
|
|
||||||
viewHolderDelegate.convert(getItemViewType(position), holder, data.get(position), position);
|
|
||||||
bindViewClickListener(holder, position);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount() {
|
|
||||||
return data.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setData(ArrayList<T> items) {
|
|
||||||
data.clear();
|
|
||||||
data.addAll(items);
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public T getData(int position) {
|
|
||||||
return data.get(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public BaseViewHolder getViewHolderByPosition(int position) {
|
|
||||||
if (!mViewHolder.containsKey(position)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return mViewHolder.get(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
public View getViewByPosition(int position) {
|
|
||||||
if (mViewHolder.get(position) == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return mViewHolder.get(position).itemView;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void bindViewClickListener(BaseViewHolder holder, int position) {
|
|
||||||
View view = holder.itemView;
|
|
||||||
view.setOnClickListener(new OnMultiClickListener() {
|
|
||||||
@Override
|
|
||||||
protected void onMultiClick(@Nullable View v) {
|
|
||||||
viewHolderDelegate.onItemClickListener(view, data.get(position), position);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
view.setOnLongClickListener(v -> viewHolderDelegate.onItemLongClickListener(view, data.get(position), position));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemViewType(int position) {
|
|
||||||
return viewHolderDelegate.getItemViewType(data.get(position), position);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getLayoutId(int viewType) {
|
|
||||||
return mLayouts[viewType];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,361 +0,0 @@
|
|||||||
package com.yunbao.faceunity.base;
|
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.Typeface;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.text.util.Linkify;
|
|
||||||
import android.util.SparseArray;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.animation.AlphaAnimation;
|
|
||||||
import android.widget.Checkable;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.ProgressBar;
|
|
||||||
import android.widget.RatingBar;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.annotation.ColorInt;
|
|
||||||
import androidx.annotation.DrawableRes;
|
|
||||||
import androidx.annotation.IdRes;
|
|
||||||
import androidx.annotation.StringRes;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DESC:DESC:控件布局绑定
|
|
||||||
* Created on 2021/4/26
|
|
||||||
*/
|
|
||||||
public class BaseViewHolder extends RecyclerView.ViewHolder {
|
|
||||||
|
|
||||||
private SparseArray views;
|
|
||||||
/**
|
|
||||||
* use itemView instead
|
|
||||||
*/
|
|
||||||
private View convertView;
|
|
||||||
|
|
||||||
public BaseViewHolder(final View itemView) {
|
|
||||||
super(itemView);
|
|
||||||
this.views = new SparseArray<>();
|
|
||||||
convertView = itemView;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* use itemView instead
|
|
||||||
*
|
|
||||||
* @return the ViewHolder root view
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public View getConvertView() {
|
|
||||||
return convertView;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Will set the text of a TextView.
|
|
||||||
*
|
|
||||||
* @param viewId The view id.
|
|
||||||
* @param value The text to put in the text view.
|
|
||||||
* @return The BaseViewHolder for chaining.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setText(@IdRes int viewId, CharSequence value) {
|
|
||||||
TextView view = getView(viewId);
|
|
||||||
view.setText(value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaseViewHolder setText(@IdRes int viewId, @StringRes int strId) {
|
|
||||||
TextView view = getView(viewId);
|
|
||||||
view.setText(strId);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Will set the image of an ImageView from a resource id.
|
|
||||||
*
|
|
||||||
* @param viewId The view id.
|
|
||||||
* @param imageResId The image resource id.
|
|
||||||
* @return The BaseViewHolder for chaining.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setImageResource(@IdRes int viewId, @DrawableRes int imageResId) {
|
|
||||||
ImageView view = getView(viewId);
|
|
||||||
view.setImageResource(imageResId);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Will set background color of a view.
|
|
||||||
*
|
|
||||||
* @param viewId The view id.
|
|
||||||
* @param color A color, not a resource id.
|
|
||||||
* @return The BaseViewHolder for chaining.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setBackgroundColor(@IdRes int viewId, @ColorInt int color) {
|
|
||||||
View view = getView(viewId);
|
|
||||||
view.setBackgroundColor(color);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Will set background of a view.
|
|
||||||
*
|
|
||||||
* @param viewId The view id.
|
|
||||||
* @param backgroundRes A resource to use as a background.
|
|
||||||
* @return The BaseViewHolder for chaining.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setBackgroundRes(@IdRes int viewId, @DrawableRes int backgroundRes) {
|
|
||||||
View view = getView(viewId);
|
|
||||||
view.setBackgroundResource(backgroundRes);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Will set text color of a TextView.
|
|
||||||
*
|
|
||||||
* @param viewId The view id.
|
|
||||||
* @param textColor The text color (not a resource id).
|
|
||||||
* @return The BaseViewHolder for chaining.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setTextColor(@IdRes int viewId, @ColorInt int textColor) {
|
|
||||||
TextView view = getView(viewId);
|
|
||||||
view.setTextColor(textColor);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Will set the image of an ImageView from a drawable.
|
|
||||||
*
|
|
||||||
* @param viewId The view id.
|
|
||||||
* @param drawable The image drawable.
|
|
||||||
* @return The BaseViewHolder for chaining.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setImageDrawable(@IdRes int viewId, Drawable drawable) {
|
|
||||||
ImageView view = getView(viewId);
|
|
||||||
view.setImageDrawable(drawable);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an action to set the image of an image view. Can be called multiple times.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setImageBitmap(@IdRes int viewId, Bitmap bitmap) {
|
|
||||||
ImageView view = getView(viewId);
|
|
||||||
view.setImageBitmap(bitmap);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an action to set the alpha of a view. Can be called multiple times.
|
|
||||||
* Alpha between 0-1.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setAlpha(@IdRes int viewId, float value) {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
|
||||||
getView(viewId).setAlpha(value);
|
|
||||||
} else {
|
|
||||||
// Pre-honeycomb hack to set Alpha value
|
|
||||||
AlphaAnimation alpha = new AlphaAnimation(value, value);
|
|
||||||
alpha.setDuration(0);
|
|
||||||
alpha.setFillAfter(true);
|
|
||||||
getView(viewId).startAnimation(alpha);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a view visibility to VISIBLE (true) or GONE (false).
|
|
||||||
*
|
|
||||||
* @param viewId The view id.
|
|
||||||
* @param visible True for VISIBLE, false for GONE.
|
|
||||||
* @return The BaseViewHolder for chaining.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setGone(@IdRes int viewId, boolean visible) {
|
|
||||||
View view = getView(viewId);
|
|
||||||
view.setVisibility(visible ? View.VISIBLE : View.GONE);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a view visibility to VISIBLE (true) or INVISIBLE (false).
|
|
||||||
*
|
|
||||||
* @param viewId The view id.
|
|
||||||
* @param visible True for VISIBLE, false for INVISIBLE.
|
|
||||||
* @return The BaseViewHolder for chaining.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setVisible(@IdRes int viewId, boolean visible) {
|
|
||||||
View view = getView(viewId);
|
|
||||||
view.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add links into a TextView.
|
|
||||||
*
|
|
||||||
* @param viewId The id of the TextView to linkify.
|
|
||||||
* @return The BaseViewHolder for chaining.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder linkify(@IdRes int viewId) {
|
|
||||||
TextView view = getView(viewId);
|
|
||||||
Linkify.addLinks(view, Linkify.ALL);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply the typeface to the given viewId, and enable subpixel rendering.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setTypeface(@IdRes int viewId, Typeface typeface) {
|
|
||||||
TextView view = getView(viewId);
|
|
||||||
view.setTypeface(typeface);
|
|
||||||
view.setPaintFlags(view.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply the typeface to all the given viewIds, and enable subpixel rendering.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setTypeface(Typeface typeface, int... viewIds) {
|
|
||||||
for (int viewId : viewIds) {
|
|
||||||
TextView view = getView(viewId);
|
|
||||||
view.setTypeface(typeface);
|
|
||||||
view.setPaintFlags(view.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the progress of a ProgressBar.
|
|
||||||
*
|
|
||||||
* @param viewId The view id.
|
|
||||||
* @param progress The progress.
|
|
||||||
* @return The BaseViewHolder for chaining.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setProgress(@IdRes int viewId, int progress) {
|
|
||||||
ProgressBar view = getView(viewId);
|
|
||||||
view.setProgress(progress);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the progress and max of a ProgressBar.
|
|
||||||
*
|
|
||||||
* @param viewId The view id.
|
|
||||||
* @param progress The progress.
|
|
||||||
* @param max The max value of a ProgressBar.
|
|
||||||
* @return The BaseViewHolder for chaining.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setProgress(@IdRes int viewId, int progress, int max) {
|
|
||||||
ProgressBar view = getView(viewId);
|
|
||||||
view.setMax(max);
|
|
||||||
view.setProgress(progress);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the range of a ProgressBar to 0...max.
|
|
||||||
*
|
|
||||||
* @param viewId The view id.
|
|
||||||
* @param max The max value of a ProgressBar.
|
|
||||||
* @return The BaseViewHolder for chaining.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setMax(@IdRes int viewId, int max) {
|
|
||||||
ProgressBar view = getView(viewId);
|
|
||||||
view.setMax(max);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the rating (the number of stars filled) of a RatingBar.
|
|
||||||
*
|
|
||||||
* @param viewId The view id.
|
|
||||||
* @param rating The rating.
|
|
||||||
* @return The BaseViewHolder for chaining.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setRating(@IdRes int viewId, float rating) {
|
|
||||||
RatingBar view = getView(viewId);
|
|
||||||
view.setRating(rating);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the rating (the number of stars filled) and max of a RatingBar.
|
|
||||||
*
|
|
||||||
* @param viewId The view id.
|
|
||||||
* @param rating The rating.
|
|
||||||
* @param max The range of the RatingBar to 0...max.
|
|
||||||
* @return The BaseViewHolder for chaining.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setRating(@IdRes int viewId, float rating, int max) {
|
|
||||||
RatingBar view = getView(viewId);
|
|
||||||
view.setMax(max);
|
|
||||||
view.setRating(rating);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the tag of the view.
|
|
||||||
*
|
|
||||||
* @param viewId The view id.
|
|
||||||
* @param tag The tag;
|
|
||||||
* @return The BaseViewHolder for chaining.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setTag(@IdRes int viewId, Object tag) {
|
|
||||||
View view = getView(viewId);
|
|
||||||
view.setTag(tag);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the tag of the view.
|
|
||||||
*
|
|
||||||
* @param viewId The view id.
|
|
||||||
* @param key The key of tag;
|
|
||||||
* @param tag The tag;
|
|
||||||
* @return The BaseViewHolder for chaining.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setTag(@IdRes int viewId, int key, Object tag) {
|
|
||||||
View view = getView(viewId);
|
|
||||||
view.setTag(key, tag);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the checked status of a checkable.
|
|
||||||
*
|
|
||||||
* @param viewId The view id.
|
|
||||||
* @param checked The checked status;
|
|
||||||
* @return The BaseViewHolder for chaining.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setChecked(@IdRes int viewId, boolean checked) {
|
|
||||||
View view = getView(viewId);
|
|
||||||
// View unable cast to Checkable
|
|
||||||
if (view instanceof Checkable) {
|
|
||||||
((Checkable) view).setChecked(checked);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the enabled state of this view.
|
|
||||||
*
|
|
||||||
* @param viewId The view id.
|
|
||||||
* @param enable The checked status;
|
|
||||||
* @return The BaseViewHolder for chaining.
|
|
||||||
*/
|
|
||||||
public BaseViewHolder setEnabled(@IdRes int viewId, boolean enable) {
|
|
||||||
View view = getView(viewId);
|
|
||||||
view.setEnabled(enable);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public <T extends View> T getView(int viewId) {
|
|
||||||
View view = (View) views.get(viewId);
|
|
||||||
if (view == null) {
|
|
||||||
view = itemView.findViewById(viewId);
|
|
||||||
views.put(viewId, view);
|
|
||||||
}
|
|
||||||
return (T) view;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,149 +0,0 @@
|
|||||||
package com.yunbao.faceunity.control
|
|
||||||
|
|
||||||
import android.animation.ValueAnimator
|
|
||||||
import android.content.Context
|
|
||||||
import android.util.AttributeSet
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import com.yunbao.faceunity.R
|
|
||||||
import com.yunbao.faceunity.base.BaseDelegate
|
|
||||||
import com.yunbao.faceunity.base.BaseListAdapter
|
|
||||||
import com.yunbao.faceunity.base.BaseViewHolder
|
|
||||||
import com.yunbao.faceunity.entity.AnimationFilterBean
|
|
||||||
import com.yunbao.faceunity.entity.AnimojiBean
|
|
||||||
import com.yunbao.faceunity.infe.AbstractAnimojiDataFactory
|
|
||||||
import kotlinx.android.synthetic.main.layout_animo_control.view.*
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* DESC:
|
|
||||||
* Created on 2020/12/10
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class AnimojiControlView @JvmOverloads constructor(private val mContext: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
|
|
||||||
BaseControlView(mContext, attrs, defStyleAttr) {
|
|
||||||
|
|
||||||
|
|
||||||
private lateinit var mDataFactory: AbstractAnimojiDataFactory
|
|
||||||
|
|
||||||
private lateinit var mAnimojiAdapter: BaseListAdapter<AnimojiBean>
|
|
||||||
private lateinit var mAnimationFilterAdapter: BaseListAdapter<AnimationFilterBean>
|
|
||||||
|
|
||||||
|
|
||||||
// region init
|
|
||||||
init {
|
|
||||||
LayoutInflater.from(context).inflate(R.layout.layout_animo_control, this)
|
|
||||||
initView()
|
|
||||||
initAdapter()
|
|
||||||
bindListener()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 给控制绑定AnimojiController,数据工厂
|
|
||||||
*/
|
|
||||||
fun bindDataFactory(dataFactory: AbstractAnimojiDataFactory) {
|
|
||||||
mDataFactory = dataFactory
|
|
||||||
mAnimojiAdapter.setData(dataFactory.animojis)
|
|
||||||
mAnimationFilterAdapter.setData(dataFactory.filters)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 收回菜单栏
|
|
||||||
*/
|
|
||||||
fun hideControlView() {
|
|
||||||
rg_anim.check(View.NO_ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun initView() {
|
|
||||||
isBottomShow = true
|
|
||||||
initHorizontalRecycleView(recycler_view)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initAdapter() {
|
|
||||||
mAnimojiAdapter = BaseListAdapter(ArrayList(), object : BaseDelegate<AnimojiBean>() {
|
|
||||||
override fun convert(viewType: Int, helper: BaseViewHolder, data: AnimojiBean, position: Int) {
|
|
||||||
helper.setImageResource(R.id.iv_control, data.iconId)
|
|
||||||
helper.itemView.isSelected = position == mDataFactory.currentAnimojiIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemClickListener(view: View, data: AnimojiBean, position: Int) {
|
|
||||||
if (mDataFactory.currentAnimojiIndex != position) {
|
|
||||||
changeAdapterSelected(mAnimojiAdapter, mDataFactory.currentAnimojiIndex, position)
|
|
||||||
mDataFactory.currentAnimojiIndex = position
|
|
||||||
mDataFactory.onAnimojiSelected(data)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, R.layout.list_item_control_image_circle)
|
|
||||||
recycler_view.adapter = mAnimojiAdapter
|
|
||||||
|
|
||||||
mAnimationFilterAdapter = BaseListAdapter(ArrayList(), object : BaseDelegate<AnimationFilterBean>() {
|
|
||||||
override fun convert(viewType: Int, helper: BaseViewHolder, data: AnimationFilterBean, position: Int) {
|
|
||||||
helper.setImageResource(R.id.iv_control, data.iconId)
|
|
||||||
helper.itemView.isSelected = position == mDataFactory.currentFilterIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemClickListener(view: View, data: AnimationFilterBean, position: Int) {
|
|
||||||
if (mDataFactory.currentFilterIndex != position) {
|
|
||||||
changeAdapterSelected(mAnimationFilterAdapter, mDataFactory.currentFilterIndex, position)
|
|
||||||
mDataFactory.currentFilterIndex = position
|
|
||||||
mDataFactory.onFilterSelected(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, R.layout.list_item_control_image_circle)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun bindListener() {
|
|
||||||
rg_anim.setOnCheckedChangeListener { _, checkedId ->
|
|
||||||
when (checkedId) {
|
|
||||||
R.id.cb_animoji -> {
|
|
||||||
changeBottomLayoutAnimator(true)
|
|
||||||
recycler_view.adapter = mAnimojiAdapter
|
|
||||||
}
|
|
||||||
R.id.cb_filter -> {
|
|
||||||
changeBottomLayoutAnimator(true)
|
|
||||||
recycler_view.adapter = mAnimationFilterAdapter
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
changeBottomLayoutAnimator(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// endregion
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 底部动画处理
|
|
||||||
* @param isOpen Boolean
|
|
||||||
*/
|
|
||||||
private fun changeBottomLayoutAnimator(isOpen: Boolean) {
|
|
||||||
if (isOpen == isBottomShow) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val start = if (isOpen) resources.getDimensionPixelSize(R.dimen.x98) else resources.getDimensionPixelSize(R.dimen.x266)
|
|
||||||
val end = if (isOpen) resources.getDimensionPixelSize(R.dimen.x266) else resources.getDimensionPixelSize(R.dimen.x98)
|
|
||||||
|
|
||||||
if (bottomLayoutAnimator != null && bottomLayoutAnimator!!.isRunning) {
|
|
||||||
bottomLayoutAnimator!!.end()
|
|
||||||
}
|
|
||||||
bottomLayoutAnimator = ValueAnimator.ofInt(start, end).setDuration(150)
|
|
||||||
bottomLayoutAnimator!!.addUpdateListener { animation ->
|
|
||||||
val height = animation.animatedValue as Int
|
|
||||||
val params = lyt_bottom.layoutParams as ViewGroup.LayoutParams
|
|
||||||
params.height = height
|
|
||||||
lyt_bottom.layoutParams = params
|
|
||||||
if (onBottomAnimatorChangeListener != null) {
|
|
||||||
val showRate = 1.0f * (height - start) / (end - start)
|
|
||||||
onBottomAnimatorChangeListener?.onBottomAnimatorChangeListener(if (!isOpen) 1 - showRate else showRate)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bottomLayoutAnimator!!.start()
|
|
||||||
isBottomShow = isOpen
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
package com.yunbao.faceunity.control;
|
|
||||||
|
|
||||||
import android.animation.ValueAnimator;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.widget.FrameLayout;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.fragment.app.FragmentActivity;
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
|
||||||
|
|
||||||
import com.yunbao.faceunity.base.BaseListAdapter;
|
|
||||||
import com.yunbao.faceunity.dialog.BaseDialogFragment;
|
|
||||||
import com.yunbao.faceunity.dialog.ConfirmDialogFragment;
|
|
||||||
import com.yunbao.faceunity.listener.OnBottomAnimatorChangeListener;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DESC:自定义菜单Base类
|
|
||||||
* Created on 2021/4/26
|
|
||||||
*/
|
|
||||||
public abstract class BaseControlView extends FrameLayout {
|
|
||||||
|
|
||||||
protected Context mContext;
|
|
||||||
|
|
||||||
public BaseControlView(@NonNull Context context) {
|
|
||||||
super(context);
|
|
||||||
mContext = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaseControlView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
mContext = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaseControlView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
|
||||||
super(context, attrs, defStyleAttr);
|
|
||||||
mContext = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* adapter单项点击,选中状态变更
|
|
||||||
*
|
|
||||||
* @param adapter BaseListAdapter<T>
|
|
||||||
* @param old nt
|
|
||||||
* @param position Int
|
|
||||||
*/
|
|
||||||
protected <T> void changeAdapterSelected(BaseListAdapter<T> adapter, int old, int position) {
|
|
||||||
if (old >= 0 && adapter.getViewByPosition(old) != null) {
|
|
||||||
adapter.getViewByPosition(old).setSelected(false);
|
|
||||||
}
|
|
||||||
if (position >= 0 && adapter.getViewByPosition(position) != null) {
|
|
||||||
adapter.getViewByPosition(position).setSelected(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示弹框
|
|
||||||
*
|
|
||||||
* @param tip
|
|
||||||
* @param runnable
|
|
||||||
*/
|
|
||||||
protected void showDialog(String tip, Runnable runnable) {
|
|
||||||
ConfirmDialogFragment confirmDialogFragment = ConfirmDialogFragment.newInstance(tip, new BaseDialogFragment.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onConfirm() {
|
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCancel() {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
confirmDialogFragment.show(((FragmentActivity) mContext).getSupportFragmentManager(), "ConfirmDialogFragmentReset");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected void initHorizontalRecycleView(RecyclerView recyclerView) {
|
|
||||||
recyclerView.setHasFixedSize(true);
|
|
||||||
recyclerView.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false));
|
|
||||||
((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************菜单动画*****************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
protected boolean isBottomShow;
|
|
||||||
protected ValueAnimator bottomLayoutAnimator = null;
|
|
||||||
protected OnBottomAnimatorChangeListener onBottomAnimatorChangeListener = null;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,205 +0,0 @@
|
|||||||
package com.yunbao.faceunity.control
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.util.AttributeSet
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import com.faceunity.core.utils.DecimalUtils
|
|
||||||
import com.yunbao.faceunity.R
|
|
||||||
import com.yunbao.faceunity.base.BaseDelegate
|
|
||||||
import com.yunbao.faceunity.base.BaseListAdapter
|
|
||||||
import com.yunbao.faceunity.base.BaseViewHolder
|
|
||||||
import com.yunbao.faceunity.entity.BodyBeautyBean
|
|
||||||
import com.yunbao.faceunity.entity.ModelAttributeData
|
|
||||||
import com.yunbao.faceunity.infe.AbstractBodyBeautyDataFactory
|
|
||||||
import com.yunbao.faceunity.seekbar.DiscreteSeekBar
|
|
||||||
|
|
||||||
import kotlinx.android.synthetic.main.layout_body_beauty_control.view.*
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* DESC:美体
|
|
||||||
* Created on 2020/12/11
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class BodyBeautyControlView @JvmOverloads constructor(private val mContext: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
|
|
||||||
BaseControlView(mContext, attrs, defStyleAttr) {
|
|
||||||
private lateinit var mDataFactory: AbstractBodyBeautyDataFactory
|
|
||||||
private lateinit var mModelAttributeRange: HashMap<String, ModelAttributeData>
|
|
||||||
private lateinit var mBodyBeautyBeans: ArrayList<BodyBeautyBean>
|
|
||||||
private lateinit var mBodyAdapter: BaseListAdapter<BodyBeautyBean>
|
|
||||||
private var mBodyIndex = 0
|
|
||||||
|
|
||||||
// region init
|
|
||||||
|
|
||||||
init {
|
|
||||||
LayoutInflater.from(context).inflate(R.layout.layout_body_beauty_control, this)
|
|
||||||
initView()
|
|
||||||
initAdapter()
|
|
||||||
bindListener()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun bindDataFactory(dataFactory: AbstractBodyBeautyDataFactory) {
|
|
||||||
mDataFactory = dataFactory
|
|
||||||
mBodyBeautyBeans = mDataFactory.bodyBeautyParam
|
|
||||||
mBodyAdapter.setData(mBodyBeautyBeans)
|
|
||||||
mModelAttributeRange = mDataFactory.modelAttributeRange
|
|
||||||
val data = mBodyBeautyBeans[mBodyIndex]
|
|
||||||
val value = mDataFactory.getParamIntensity(data.key)
|
|
||||||
val stand = mModelAttributeRange[data.key]!!.stand
|
|
||||||
val maxRange = mModelAttributeRange[data.key]!!.maxRange
|
|
||||||
seekToSeekBar(value, stand, maxRange)
|
|
||||||
setRecoverEnable(checkParamsChanged())
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initView() {
|
|
||||||
initHorizontalRecycleView(recycler_view)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun initAdapter() {
|
|
||||||
mBodyAdapter = BaseListAdapter(ArrayList(), object : BaseDelegate<BodyBeautyBean>() {
|
|
||||||
override fun convert(viewType: Int, helper: BaseViewHolder, data: BodyBeautyBean, position: Int) {
|
|
||||||
helper.setText(R.id.tv_control, data.desRes)
|
|
||||||
val value = mDataFactory.getParamIntensity(data.key)
|
|
||||||
val stand = mModelAttributeRange[data.key]!!.stand
|
|
||||||
if (DecimalUtils.doubleEquals(value, stand)) {
|
|
||||||
helper.setImageResource(R.id.iv_control, data.closeRes)
|
|
||||||
} else {
|
|
||||||
helper.setImageResource(R.id.iv_control, data.openRes)
|
|
||||||
}
|
|
||||||
helper.itemView.isSelected = position == mBodyIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemClickListener(view: View, data: BodyBeautyBean, position: Int) {
|
|
||||||
if (mBodyIndex != position) {
|
|
||||||
changeAdapterSelected(mBodyAdapter, mBodyIndex, position)
|
|
||||||
mBodyIndex = position
|
|
||||||
val value = mDataFactory.getParamIntensity(data.key)
|
|
||||||
val stand = mModelAttributeRange[data.key]!!.stand
|
|
||||||
val maxRange = mModelAttributeRange[data.key]!!.maxRange
|
|
||||||
seekToSeekBar(value, stand, maxRange)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}, R.layout.list_item_control_title_image_circle)
|
|
||||||
recycler_view.adapter = mBodyAdapter
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun bindListener() {
|
|
||||||
cyt_main.setOnTouchListener { _, _ -> true }
|
|
||||||
beauty_seek_bar.setOnProgressChangeListener(object : DiscreteSeekBar.OnSimpleProgressChangeListener() {
|
|
||||||
override fun onProgressChanged(seekBar: DiscreteSeekBar?, value: Int, fromUser: Boolean) {
|
|
||||||
if (!fromUser) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val valueF = 1.0 * (value - seekBar!!.min) / 100
|
|
||||||
val data = mBodyBeautyBeans[mBodyIndex]
|
|
||||||
val value = mDataFactory.getParamIntensity(data.key)
|
|
||||||
val range = mModelAttributeRange[data.key]!!.maxRange
|
|
||||||
val res = valueF * range
|
|
||||||
if (!DecimalUtils.doubleEquals(res, value)) {
|
|
||||||
mDataFactory.updateParamIntensity(data.key, res)
|
|
||||||
setRecoverEnable(checkParamsChanged())
|
|
||||||
updateBeautyItemUI(mBodyAdapter.getViewHolderByPosition(mBodyIndex), data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
lyt_beauty_recover.setOnClickListener {
|
|
||||||
showDialog(mContext.getString(R.string.dialog_reset_avatar_model)) {
|
|
||||||
recoverData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置滚动条数值
|
|
||||||
*/
|
|
||||||
private fun seekToSeekBar(value: Double, stand: Double, range: Double) {
|
|
||||||
if (stand == 0.5) {
|
|
||||||
beauty_seek_bar.min = -50
|
|
||||||
beauty_seek_bar.max = 50
|
|
||||||
beauty_seek_bar.progress = (value * 100 / range - 50).toInt()
|
|
||||||
} else {
|
|
||||||
beauty_seek_bar.min = 0
|
|
||||||
beauty_seek_bar.max = 100
|
|
||||||
beauty_seek_bar.progress = (value * 100 / range).toInt()
|
|
||||||
}
|
|
||||||
beauty_seek_bar.visibility = View.VISIBLE
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// endregion
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新单项是否为基准值显示
|
|
||||||
*/
|
|
||||||
private fun updateBeautyItemUI(viewHolder: BaseViewHolder?, data: BodyBeautyBean) {
|
|
||||||
val value = mDataFactory.getParamIntensity(data.key)
|
|
||||||
val stand = mModelAttributeRange[data.key]!!.stand
|
|
||||||
if (DecimalUtils.doubleEquals(value, stand)) {
|
|
||||||
viewHolder?.setImageResource(R.id.iv_control, data.closeRes)
|
|
||||||
} else {
|
|
||||||
viewHolder?.setImageResource(R.id.iv_control, data.openRes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun recoverData() {
|
|
||||||
mBodyBeautyBeans.forEach {
|
|
||||||
val default = mModelAttributeRange[it.key]!!.default
|
|
||||||
mDataFactory.updateParamIntensity(it.key, default)
|
|
||||||
}
|
|
||||||
val data = mBodyBeautyBeans[mBodyIndex]
|
|
||||||
val value = mDataFactory.getParamIntensity(data.key)
|
|
||||||
val stand = mModelAttributeRange[data.key]!!.stand
|
|
||||||
val maxRange = mModelAttributeRange[data.key]!!.maxRange
|
|
||||||
seekToSeekBar(value, stand, maxRange)
|
|
||||||
mBodyAdapter.notifyDataSetChanged()
|
|
||||||
setRecoverEnable(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 遍历数据确认还原按钮是否可以点击
|
|
||||||
* @return Boolean
|
|
||||||
*/
|
|
||||||
private fun checkParamsChanged(): Boolean {
|
|
||||||
var item = mBodyBeautyBeans[mBodyIndex]
|
|
||||||
var value = mDataFactory.getParamIntensity(item.key)
|
|
||||||
var default = mModelAttributeRange[item.key]!!.default
|
|
||||||
if (!DecimalUtils.doubleEquals(value, default)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
mBodyBeautyBeans.forEach {
|
|
||||||
value = mDataFactory.getParamIntensity(it.key)
|
|
||||||
default = mModelAttributeRange[it.key]!!.default
|
|
||||||
if (!DecimalUtils.doubleEquals(value, default)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重置还原按钮状态
|
|
||||||
* @param enable Boolean
|
|
||||||
*/
|
|
||||||
private fun setRecoverEnable(enable: Boolean) {
|
|
||||||
if (enable) {
|
|
||||||
tv_beauty_recover.alpha = 1f
|
|
||||||
iv_beauty_recover.alpha = 1f
|
|
||||||
} else {
|
|
||||||
tv_beauty_recover.alpha = 0.6f
|
|
||||||
iv_beauty_recover.alpha = 0.6f
|
|
||||||
}
|
|
||||||
lyt_beauty_recover.isEnabled = enable
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,826 +0,0 @@
|
|||||||
package com.yunbao.faceunity.control
|
|
||||||
|
|
||||||
import android.animation.ValueAnimator
|
|
||||||
import android.content.Context
|
|
||||||
import android.util.AttributeSet
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.MotionEvent
|
|
||||||
import android.view.View
|
|
||||||
import android.view.animation.AlphaAnimation
|
|
||||||
import android.view.animation.Animation
|
|
||||||
import android.view.animation.AnimationSet
|
|
||||||
import android.view.animation.TranslateAnimation
|
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.LinearLayout
|
|
||||||
import com.faceunity.core.utils.DecimalUtils
|
|
||||||
import com.yunbao.faceunity.R
|
|
||||||
import com.yunbao.faceunity.base.BaseDelegate
|
|
||||||
import com.yunbao.faceunity.base.BaseListAdapter
|
|
||||||
import com.yunbao.faceunity.base.BaseViewHolder
|
|
||||||
import com.yunbao.faceunity.dialog.ToastHelper
|
|
||||||
import com.yunbao.faceunity.entity.FaceBeautyBean
|
|
||||||
import com.yunbao.faceunity.entity.FaceBeautyFilterBean
|
|
||||||
import com.yunbao.faceunity.entity.FaceBeautyStyleBean
|
|
||||||
import com.yunbao.faceunity.entity.ModelAttributeData
|
|
||||||
import com.yunbao.faceunity.infe.AbstractFaceBeautyDataFactory
|
|
||||||
import com.yunbao.faceunity.seekbar.DiscreteSeekBar
|
|
||||||
import kotlinx.android.synthetic.main.layout_face_beauty_control.view.*
|
|
||||||
import kotlin.collections.set
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* DESC:美颜
|
|
||||||
* Created on 2020/11/17
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class FaceBeautyControlView @JvmOverloads constructor(private val mContext: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
|
|
||||||
BaseControlView(mContext, attrs, defStyleAttr) {
|
|
||||||
|
|
||||||
private lateinit var mDataFactory: AbstractFaceBeautyDataFactory
|
|
||||||
|
|
||||||
/* 美颜、美型 */
|
|
||||||
private lateinit var mModelAttributeRange: HashMap<String, ModelAttributeData>
|
|
||||||
private var mSkinBeauty = ArrayList<FaceBeautyBean>()
|
|
||||||
private var mShapeBeauty = ArrayList<FaceBeautyBean>()
|
|
||||||
private var mShapeBeautySubItem = ArrayList<FaceBeautyBean>()
|
|
||||||
private var mSubItemUIValueCache: HashMap<String,Double> = HashMap()//美型子项脸型的UI缓存值
|
|
||||||
private var mSkinIndex = 0
|
|
||||||
private var mShapeIndex = 1
|
|
||||||
private var mIsOnBeautyShapeMain = true//美型是否在主项上
|
|
||||||
|
|
||||||
private lateinit var mBeautyAdapter: BaseListAdapter<FaceBeautyBean>
|
|
||||||
|
|
||||||
/* 滤镜 */
|
|
||||||
private var mFilters = ArrayList<FaceBeautyFilterBean>()
|
|
||||||
private lateinit var mFiltersAdapter: BaseListAdapter<FaceBeautyFilterBean>
|
|
||||||
|
|
||||||
/* 风格 */
|
|
||||||
private var mStyles = ArrayList<FaceBeautyStyleBean>()
|
|
||||||
private lateinit var mStylesAdapter: BaseListAdapter<FaceBeautyStyleBean>
|
|
||||||
private var mEnableBottomRationClick = true
|
|
||||||
// region init
|
|
||||||
|
|
||||||
init {
|
|
||||||
LayoutInflater.from(context).inflate(R.layout.layout_face_beauty_control, this)
|
|
||||||
initView()
|
|
||||||
initAdapter()
|
|
||||||
bindListener()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 给控制绑定FaceBeautyController,数据工厂
|
|
||||||
* @param dataFactory IFaceBeautyDataFactory
|
|
||||||
*/
|
|
||||||
fun bindDataFactory(dataFactory: AbstractFaceBeautyDataFactory) {
|
|
||||||
mDataFactory = dataFactory
|
|
||||||
mModelAttributeRange = dataFactory.modelAttributeRange
|
|
||||||
mSkinBeauty = dataFactory.skinBeauty
|
|
||||||
mShapeBeauty = dataFactory.shapeBeauty
|
|
||||||
mShapeBeautySubItem = dataFactory.shapeBeautySubItem
|
|
||||||
mFilters = dataFactory.beautyFilters
|
|
||||||
mStyles = dataFactory.beautyStyles
|
|
||||||
mFiltersAdapter.setData(mFilters)
|
|
||||||
mStylesAdapter.setData(mStyles)
|
|
||||||
if (dataFactory.currentStyleIndex > -1) {
|
|
||||||
lyt_style_recover.isSelected = false
|
|
||||||
setBottomCheckRatioEnable(false)
|
|
||||||
var data = mStyles[dataFactory.currentStyleIndex]
|
|
||||||
mDataFactory.onStyleSelected(data.key)
|
|
||||||
} else {
|
|
||||||
lyt_style_recover.isSelected = true
|
|
||||||
setBottomCheckRatioEnable(true)
|
|
||||||
}
|
|
||||||
beauty_radio_group.check(View.NO_ID)
|
|
||||||
|
|
||||||
//恢复上一次脸型选项的UI值
|
|
||||||
mSubItemUIValueCache = mDataFactory.getCurrentFaceShapeUIValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 收回菜单栏
|
|
||||||
*/
|
|
||||||
fun hideControlView() {
|
|
||||||
beauty_radio_group.check(View.NO_ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* View初始化
|
|
||||||
*/
|
|
||||||
private fun initView() {
|
|
||||||
initHorizontalRecycleView(recycler_view)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造Adapter
|
|
||||||
*/
|
|
||||||
private fun initAdapter() {
|
|
||||||
mStylesAdapter = BaseListAdapter(
|
|
||||||
ArrayList(), object : BaseDelegate<FaceBeautyStyleBean>() {
|
|
||||||
override fun convert(viewType: Int, helper: BaseViewHolder, data: FaceBeautyStyleBean, position: Int) {
|
|
||||||
helper.setText(R.id.tv_control, data.desRes)
|
|
||||||
helper.setImageResource(R.id.iv_control, data.imageRes)
|
|
||||||
helper.itemView.isSelected = mDataFactory.currentStyleIndex == position
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemClickListener(view: View, data: FaceBeautyStyleBean, position: Int) {
|
|
||||||
super.onItemClickListener(view, data, position)
|
|
||||||
if (mDataFactory.currentStyleIndex != position) {
|
|
||||||
lyt_style_recover.isSelected = false
|
|
||||||
setBottomCheckRatioEnable(false)
|
|
||||||
changeAdapterSelected(mStylesAdapter, mDataFactory.currentStyleIndex, position)
|
|
||||||
mDataFactory.currentStyleIndex = position
|
|
||||||
mDataFactory.onStyleSelected(data.key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, R.layout.list_item_control_title_image_circle
|
|
||||||
)
|
|
||||||
|
|
||||||
mFiltersAdapter = BaseListAdapter(
|
|
||||||
ArrayList(), object : BaseDelegate<FaceBeautyFilterBean>() {
|
|
||||||
override fun convert(viewType: Int, helper: BaseViewHolder, data: FaceBeautyFilterBean, position: Int) {
|
|
||||||
helper.setText(R.id.tv_control, data.desRes)
|
|
||||||
helper.setImageResource(R.id.iv_control, data.imageRes)
|
|
||||||
helper.itemView.isSelected = mDataFactory.currentFilterIndex == position
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemClickListener(view: View, data: FaceBeautyFilterBean, position: Int) {
|
|
||||||
super.onItemClickListener(view, data, position)
|
|
||||||
if (mDataFactory.currentFilterIndex != position) {
|
|
||||||
changeAdapterSelected(mFiltersAdapter, mDataFactory.currentFilterIndex, position)
|
|
||||||
mDataFactory.currentFilterIndex = position
|
|
||||||
mDataFactory.onFilterSelected(data.key, data.intensity, data.desRes)
|
|
||||||
if (position == 0) {
|
|
||||||
beauty_seek_bar.visibility = View.INVISIBLE
|
|
||||||
} else {
|
|
||||||
seekToSeekBar(data.intensity, 0.0, 1.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, R.layout.list_item_control_title_image_square
|
|
||||||
)
|
|
||||||
|
|
||||||
mBeautyAdapter = BaseListAdapter(ArrayList(), object : BaseDelegate<FaceBeautyBean>() {
|
|
||||||
override fun convert(viewType: Int, helper: BaseViewHolder, data: FaceBeautyBean, position: Int) {
|
|
||||||
val isShinSelected = beauty_radio_group.checkedCheckBoxId == R.id.beauty_radio_skin_beauty
|
|
||||||
helper.itemView.isSelected = if (isShinSelected) mSkinIndex == position else mShapeIndex == position
|
|
||||||
helper.setText(R.id.tv_control, data.desRes)
|
|
||||||
//主项的时候才需要显示
|
|
||||||
// helper.setVisible(R.id.iv_oval_spot, !isShinSelected && mIsOnBeautyShapeMain && position ==0)
|
|
||||||
val value = mDataFactory.getParamIntensity(data.key)
|
|
||||||
when (data.buttonType) {
|
|
||||||
FaceBeautyBean.ButtonType.BACK_BUTTON -> {
|
|
||||||
helper.setImageResource(R.id.iv_control, data.closeRes)
|
|
||||||
}
|
|
||||||
FaceBeautyBean.ButtonType.SUB_ITEM_BUTTON -> {
|
|
||||||
//判断当前UI值 和 真实值是否全是空的如果是空的则不选中
|
|
||||||
//先过UI值
|
|
||||||
var choose = false
|
|
||||||
run outside@{
|
|
||||||
mSubItemUIValueCache.forEach {
|
|
||||||
if (it.value > 0) {
|
|
||||||
choose = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mShapeBeautySubItem.forEach {
|
|
||||||
if (it.buttonType == FaceBeautyBean.ButtonType.NORMAL_BUTTON) {
|
|
||||||
if (mDataFactory.getParamIntensity(it.key) > 0) {
|
|
||||||
choose = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
helper.setImageResource(R.id.iv_control, if (choose) data.openRes else data.closeRes)
|
|
||||||
}
|
|
||||||
//普通按钮
|
|
||||||
else -> {
|
|
||||||
val stand = mModelAttributeRange[data.key]!!.stand
|
|
||||||
if (DecimalUtils.doubleEquals(value, stand)) {
|
|
||||||
helper.setImageResource(R.id.iv_control, data.closeRes)
|
|
||||||
} else {
|
|
||||||
helper.setImageResource(R.id.iv_control, data.openRes)
|
|
||||||
}
|
|
||||||
if (!data.canUseFunction) {
|
|
||||||
val ivControl = helper.getView<ImageView>(R.id.iv_control)
|
|
||||||
ivControl?.imageAlpha = 154
|
|
||||||
} else {
|
|
||||||
val ivControl = helper.getView<ImageView>(R.id.iv_control)
|
|
||||||
ivControl?.imageAlpha = 255
|
|
||||||
}
|
|
||||||
|
|
||||||
if (openEnterAnimation && needEnterAnimation && position != 0) {
|
|
||||||
enterAnimation(helper.itemView)
|
|
||||||
if (position >=4 || (mBeautyAdapter.itemCount < 5 && position == mBeautyAdapter.itemCount - 1)) {
|
|
||||||
needEnterAnimation = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemClickListener(view: View, data: FaceBeautyBean, position: Int) {
|
|
||||||
val isShinSelected = beauty_radio_group.checkedCheckBoxId == R.id.beauty_radio_skin_beauty
|
|
||||||
if ((isShinSelected && position == mSkinIndex) || (!isShinSelected && position == mShapeIndex)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (!data.canUseFunction) {
|
|
||||||
ToastHelper.showNormalToast(mContext,data.toastDesRes)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (isShinSelected) {
|
|
||||||
changeAdapterSelected(mBeautyAdapter, mSkinIndex, position)
|
|
||||||
val value = mDataFactory.getParamIntensity(data.key)
|
|
||||||
val stand = mModelAttributeRange[data.key]!!.stand
|
|
||||||
val maxRange = mModelAttributeRange[data.key]!!.maxRange
|
|
||||||
seekToSeekBar(value, stand, maxRange)
|
|
||||||
mSkinIndex = position
|
|
||||||
} else {
|
|
||||||
when (data.buttonType) {
|
|
||||||
FaceBeautyBean.ButtonType.BACK_BUTTON -> {
|
|
||||||
//返回按钮
|
|
||||||
mBeautyAdapter.setData(mShapeBeauty)
|
|
||||||
//没有按钮被选中,需要隐藏进度条
|
|
||||||
beauty_seek_bar.visibility = View.INVISIBLE
|
|
||||||
changeAdapterSelected(mBeautyAdapter, mShapeIndex, -1)
|
|
||||||
mShapeIndex = -1
|
|
||||||
mIsOnBeautyShapeMain = true
|
|
||||||
needEnterAnimation = true
|
|
||||||
}
|
|
||||||
FaceBeautyBean.ButtonType.SUB_ITEM_BUTTON -> {
|
|
||||||
//子项按钮
|
|
||||||
//选中的是哪一个子项 -> 在FaceBeauty中有记录
|
|
||||||
run outside@{
|
|
||||||
mShapeBeautySubItem.forEachIndexed{ index, value ->
|
|
||||||
if (mDataFactory.getCurrentOneHotFaceShape() == value.key) {//获取当前作用的脸型
|
|
||||||
mShapeIndex = index
|
|
||||||
return@outside
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mBeautyAdapter.setData(mShapeBeautySubItem)
|
|
||||||
if (mShapeBeautySubItem.size >= 1) {
|
|
||||||
beauty_seek_bar.visibility = View.VISIBLE
|
|
||||||
val faceBeautyBean = mShapeBeautySubItem[mShapeIndex]
|
|
||||||
if (faceBeautyBean.buttonType == FaceBeautyBean.ButtonType.NORMAL_BUTTON) {
|
|
||||||
val value = mDataFactory.getParamIntensity(faceBeautyBean.key)
|
|
||||||
val stand = mModelAttributeRange[faceBeautyBean.key]!!.stand
|
|
||||||
val maxRange = mModelAttributeRange[faceBeautyBean.key]!!.maxRange
|
|
||||||
seekToSeekBar(value, stand, maxRange)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mIsOnBeautyShapeMain = false
|
|
||||||
needEnterAnimation = true
|
|
||||||
}
|
|
||||||
//普通按钮
|
|
||||||
else -> {
|
|
||||||
//点击的是子项普通按钮还是主项普通按钮1.子项普通之间按钮效果One Hot 2.主项普通按钮之间效果可叠加
|
|
||||||
beauty_seek_bar.visibility = View.VISIBLE
|
|
||||||
changeAdapterSelected(mBeautyAdapter, mShapeIndex, position)
|
|
||||||
//判断一下是子项还是主项,1.主项直接设置改点击对象的值,2.子项需要获取之前的缓存如果存在缓存设置回之前的值,然后还要将上一个点击过的子项sdk值设置为零,UI值进行缓存
|
|
||||||
var value:Double
|
|
||||||
if (mIsOnBeautyShapeMain) {
|
|
||||||
value = mDataFactory.getParamIntensity(data.key)
|
|
||||||
} else {
|
|
||||||
//子项 one hot + 如果有UI值显示UI值 -> 并将UI缓存值设置到SDK
|
|
||||||
value = if (mSubItemUIValueCache.contains(data.key)) {
|
|
||||||
var value = mSubItemUIValueCache[data.key]!!
|
|
||||||
mDataFactory.updateParamIntensity(data.key, value)
|
|
||||||
mSubItemUIValueCache.remove(data.key)!!
|
|
||||||
} else
|
|
||||||
mDataFactory.getParamIntensity(data.key)
|
|
||||||
//将上一个点击的有效项设置为空
|
|
||||||
if (mShapeIndex >= 0) {
|
|
||||||
var beforeData = mBeautyAdapter.getData(mShapeIndex)
|
|
||||||
when (beforeData.buttonType) {
|
|
||||||
FaceBeautyBean.ButtonType.NORMAL_BUTTON -> {
|
|
||||||
//算法值要设置为零,但是点击回来的时候需要根据UI值(缓存值)重新设置回算法值
|
|
||||||
mSubItemUIValueCache[beforeData.key] = mDataFactory.getParamIntensity(beforeData.key)
|
|
||||||
mDataFactory.updateParamIntensity(beforeData.key,0.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mDataFactory.setCurrentOneHotFaceShape(data.key)
|
|
||||||
mBeautyAdapter.notifyItemChanged(mShapeIndex)
|
|
||||||
mBeautyAdapter.notifyItemChanged(position)
|
|
||||||
}
|
|
||||||
|
|
||||||
//设置当前点击bean的进度值
|
|
||||||
val stand = mModelAttributeRange[data.key]!!.stand
|
|
||||||
val maxRange = mModelAttributeRange[data.key]!!.maxRange
|
|
||||||
seekToSeekBar(value, stand, maxRange)
|
|
||||||
mShapeIndex = position
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}, R.layout.list_item_control_title_image_circle)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 绑定监听事件
|
|
||||||
*/
|
|
||||||
private fun bindListener() {
|
|
||||||
/*拦截触碰事件*/
|
|
||||||
fyt_bottom_view.setOnTouchListener { _, _ -> true }
|
|
||||||
/*菜单控制*/
|
|
||||||
bindBottomRadioListener()
|
|
||||||
/*滑动条控制*/
|
|
||||||
bindSeekBarListener()
|
|
||||||
/*比对开关*/
|
|
||||||
iv_compare.setOnTouchStateListener { v, event ->
|
|
||||||
val action = event.action
|
|
||||||
if (action == MotionEvent.ACTION_DOWN) {
|
|
||||||
v.alpha = 0.7f
|
|
||||||
mDataFactory.enableFaceBeauty(false)
|
|
||||||
} else if (action == MotionEvent.ACTION_UP) {
|
|
||||||
v.alpha = 1f
|
|
||||||
mDataFactory.enableFaceBeauty(true)
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
/*还原数据*/
|
|
||||||
lyt_beauty_recover.setOnClickListener {
|
|
||||||
showDialog(mContext.getString(R.string.dialog_reset_avatar_model)) { recoverData() }
|
|
||||||
|
|
||||||
}
|
|
||||||
lyt_style_recover.setOnClickListener {
|
|
||||||
if (it.isSelected) {
|
|
||||||
return@setOnClickListener
|
|
||||||
}
|
|
||||||
changeAdapterSelected(mStylesAdapter, mDataFactory.currentStyleIndex, -1)
|
|
||||||
mDataFactory.currentStyleIndex = -1
|
|
||||||
it.isSelected = true
|
|
||||||
setBottomCheckRatioEnable(true)
|
|
||||||
mDataFactory.onStyleSelected(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
iv_reset.setOnClickListener {
|
|
||||||
mDataFactory.resetParamIntensity()
|
|
||||||
var item:FaceBeautyBean? = null
|
|
||||||
when (beauty_radio_group.checkedCheckBoxId) {
|
|
||||||
R.id.beauty_radio_skin_beauty -> {
|
|
||||||
mBeautyAdapter.notifyDataSetChanged()
|
|
||||||
item = mSkinBeauty[mSkinIndex]
|
|
||||||
setRecoverFaceSkinEnable(true)
|
|
||||||
}
|
|
||||||
R.id.beauty_radio_face_shape -> {
|
|
||||||
mBeautyAdapter.notifyDataSetChanged()
|
|
||||||
item = mShapeBeauty[mShapeIndex]
|
|
||||||
setRecoverFaceSkinEnable(true)
|
|
||||||
}
|
|
||||||
R.id.beauty_radio_filter -> {
|
|
||||||
mFiltersAdapter.notifyDataSetChanged()
|
|
||||||
beauty_seek_bar.visibility = View.INVISIBLE
|
|
||||||
}
|
|
||||||
R.id.beauty_radio_style -> {
|
|
||||||
mStylesAdapter.notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
item?.let {
|
|
||||||
val value = mDataFactory.getParamIntensity(it.key)
|
|
||||||
val stand = mModelAttributeRange[it.key]!!.stand
|
|
||||||
val maxRange = mModelAttributeRange[it.key]!!.maxRange
|
|
||||||
seekToSeekBar(value, stand, maxRange)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 滚动条绑定事件
|
|
||||||
*/
|
|
||||||
private fun bindSeekBarListener() {
|
|
||||||
beauty_seek_bar.setOnProgressChangeListener(object : DiscreteSeekBar.OnSimpleProgressChangeListener() {
|
|
||||||
override fun onProgressChanged(seekBar: DiscreteSeekBar?, value: Int, fromUser: Boolean) {
|
|
||||||
if (!fromUser) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val valueF = 1.0 * (value - seekBar!!.min) / 100
|
|
||||||
when (beauty_radio_group.checkedCheckBoxId) {
|
|
||||||
R.id.beauty_radio_skin_beauty -> {
|
|
||||||
val bean = mSkinBeauty[mSkinIndex]
|
|
||||||
val range = mModelAttributeRange[bean.key]!!.maxRange
|
|
||||||
val res = valueF * range
|
|
||||||
val value = mDataFactory.getParamIntensity(bean.key)
|
|
||||||
if (!DecimalUtils.doubleEquals(res, value)) {
|
|
||||||
mDataFactory.updateParamIntensity(bean.key, res)
|
|
||||||
setRecoverFaceSkinEnable(checkFaceSkinChanged())
|
|
||||||
updateBeautyItemUI(mBeautyAdapter.getViewHolderByPosition(mSkinIndex), bean)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
R.id.beauty_radio_face_shape -> {
|
|
||||||
if (mShapeIndex < 0) return
|
|
||||||
val bean = mBeautyAdapter.getData(mShapeIndex)
|
|
||||||
when (bean.buttonType) {
|
|
||||||
FaceBeautyBean.ButtonType.NORMAL_BUTTON -> {
|
|
||||||
//判断一下这个按钮的类型
|
|
||||||
val range = mModelAttributeRange[bean.key]!!.maxRange
|
|
||||||
val res = valueF * range
|
|
||||||
val value = mDataFactory.getParamIntensity(bean.key)
|
|
||||||
if (!DecimalUtils.doubleEquals(res, value)) {
|
|
||||||
mDataFactory.updateParamIntensity(bean.key, res)
|
|
||||||
setRecoverFaceSkinEnable(checkFaceShapeChanged())
|
|
||||||
updateBeautyItemUI(mBeautyAdapter.getViewHolderByPosition(mShapeIndex), bean)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
R.id.beauty_radio_filter -> {
|
|
||||||
val bean = mFilters[mDataFactory.currentFilterIndex]
|
|
||||||
if (!DecimalUtils.doubleEquals(bean.intensity, valueF)) {
|
|
||||||
bean.intensity = valueF
|
|
||||||
mDataFactory.updateFilterIntensity(valueF)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 底部导航栏绑定监听事件,处理RecycleView等相关布局变更
|
|
||||||
*/
|
|
||||||
private fun bindBottomRadioListener() {
|
|
||||||
beauty_radio_group.setOnDispatchActionUpListener { x ->
|
|
||||||
if (!mEnableBottomRationClick) {
|
|
||||||
val width = beauty_radio_group.measuredWidth
|
|
||||||
when {
|
|
||||||
x < width * 0.25 -> {
|
|
||||||
val toastStr = mContext.getString(R.string.beauty_face_style_toast, mContext.getString(R.string.beauty_radio_skin_beauty))
|
|
||||||
ToastHelper.showNormalToast(mContext, toastStr)
|
|
||||||
}
|
|
||||||
x < width * 0.5 -> {
|
|
||||||
val toastStr = mContext.getString(R.string.beauty_face_style_toast, mContext.getString(R.string.beauty_radio_face_shape))
|
|
||||||
ToastHelper.showNormalToast(mContext, toastStr)
|
|
||||||
}
|
|
||||||
x < width * 0.75f -> {
|
|
||||||
val toastStr = mContext.getString(R.string.beauty_face_style_toast, mContext.getString(R.string.beauty_radio_filter))
|
|
||||||
ToastHelper.showNormalToast(mContext, toastStr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
beauty_radio_group.setOnCheckedChangeListener { _, checkedId ->
|
|
||||||
//视图变化
|
|
||||||
when (checkedId) {
|
|
||||||
R.id.beauty_radio_skin_beauty, R.id.beauty_radio_face_shape -> {
|
|
||||||
iv_compare.visibility = View.VISIBLE
|
|
||||||
beauty_seek_bar.visibility = View.VISIBLE
|
|
||||||
lyt_style_recover.visibility = View.GONE
|
|
||||||
lyt_beauty_recover.visibility = View.VISIBLE
|
|
||||||
iv_line.visibility = View.VISIBLE
|
|
||||||
}
|
|
||||||
R.id.beauty_radio_filter -> {
|
|
||||||
iv_compare.visibility = View.VISIBLE
|
|
||||||
beauty_seek_bar.visibility = if (mDataFactory.currentFilterIndex == 0) View.INVISIBLE else View.VISIBLE
|
|
||||||
lyt_style_recover.visibility = View.GONE
|
|
||||||
lyt_beauty_recover.visibility = View.GONE
|
|
||||||
iv_line.visibility = View.GONE
|
|
||||||
}
|
|
||||||
R.id.beauty_radio_style -> {
|
|
||||||
iv_compare.visibility = View.VISIBLE
|
|
||||||
beauty_seek_bar.visibility = View.INVISIBLE
|
|
||||||
lyt_beauty_recover.visibility = View.GONE
|
|
||||||
lyt_style_recover.visibility = View.VISIBLE
|
|
||||||
iv_line.visibility = View.VISIBLE
|
|
||||||
}
|
|
||||||
View.NO_ID -> {
|
|
||||||
iv_compare.visibility = View.INVISIBLE
|
|
||||||
mDataFactory.enableFaceBeauty(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//数据变化
|
|
||||||
when (checkedId) {
|
|
||||||
R.id.beauty_radio_skin_beauty -> {
|
|
||||||
mBeautyAdapter.setData(mSkinBeauty)
|
|
||||||
recycler_view.adapter = mBeautyAdapter
|
|
||||||
val item = mSkinBeauty[mSkinIndex]
|
|
||||||
val value = mDataFactory.getParamIntensity(item.key)
|
|
||||||
val stand = mModelAttributeRange[item.key]!!.stand
|
|
||||||
val maxRange = mModelAttributeRange[item.key]!!.maxRange
|
|
||||||
seekToSeekBar(value, stand, maxRange)
|
|
||||||
setRecoverFaceSkinEnable(checkFaceSkinChanged())
|
|
||||||
changeBottomLayoutAnimator(true)
|
|
||||||
}
|
|
||||||
R.id.beauty_radio_face_shape -> {
|
|
||||||
mBeautyAdapter.setData(mShapeBeauty)
|
|
||||||
recycler_view.adapter = mBeautyAdapter
|
|
||||||
if (mShapeIndex >= 0) {
|
|
||||||
val item = mShapeBeauty[mShapeIndex]
|
|
||||||
val value = mDataFactory.getParamIntensity(item.key)
|
|
||||||
val stand = mModelAttributeRange[item.key]!!.stand
|
|
||||||
val maxRange = mModelAttributeRange[item.key]!!.maxRange
|
|
||||||
seekToSeekBar(value, stand, maxRange)
|
|
||||||
setRecoverFaceSkinEnable(checkFaceShapeChanged())
|
|
||||||
changeBottomLayoutAnimator(true)
|
|
||||||
} else {
|
|
||||||
beauty_seek_bar.visibility = View.INVISIBLE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
R.id.beauty_radio_filter -> {
|
|
||||||
recycler_view.adapter = mFiltersAdapter
|
|
||||||
recycler_view.scrollToPosition(mDataFactory.currentFilterIndex)
|
|
||||||
if (mDataFactory.currentFilterIndex == 0) {
|
|
||||||
beauty_seek_bar.visibility = View.INVISIBLE
|
|
||||||
} else {
|
|
||||||
seekToSeekBar(mFilters[mDataFactory.currentFilterIndex].intensity, 0.0, 1.0)
|
|
||||||
}
|
|
||||||
changeBottomLayoutAnimator(true)
|
|
||||||
}
|
|
||||||
R.id.beauty_radio_style -> {
|
|
||||||
recycler_view.adapter = mStylesAdapter
|
|
||||||
if (mDataFactory.currentStyleIndex > -1) {
|
|
||||||
recycler_view.scrollToPosition(mDataFactory.currentStyleIndex)
|
|
||||||
lyt_style_recover.isSelected = false
|
|
||||||
} else {
|
|
||||||
lyt_style_recover.isSelected = true
|
|
||||||
}
|
|
||||||
changeBottomLayoutAnimator(true)
|
|
||||||
}
|
|
||||||
View.NO_ID -> {
|
|
||||||
changeBottomLayoutAnimator(false)
|
|
||||||
mDataFactory.enableFaceBeauty(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun setBottomCheckRatioEnable(enable: Boolean) {
|
|
||||||
mEnableBottomRationClick = enable
|
|
||||||
var i = 0
|
|
||||||
val childCount: Int = beauty_radio_group.getChildCount()
|
|
||||||
while (i < childCount) {
|
|
||||||
val view: View = beauty_radio_group.getChildAt(i)
|
|
||||||
if (view.id != R.id.beauty_radio_style) {
|
|
||||||
view.alpha = if (enable) 1f else 0.6f
|
|
||||||
view.isEnabled = enable
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// endregion
|
|
||||||
// region 业务处理
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置滚动条数值
|
|
||||||
* @param value Double 结果值
|
|
||||||
* @param stand Double 标准值
|
|
||||||
* @param range Double 范围区间
|
|
||||||
*/
|
|
||||||
private fun seekToSeekBar(value: Double, stand: Double, range: Double) {
|
|
||||||
if (stand == 0.5) {
|
|
||||||
beauty_seek_bar.min = -50
|
|
||||||
beauty_seek_bar.max = 50
|
|
||||||
beauty_seek_bar.progress = (value * 100 / range - 50).toInt()
|
|
||||||
} else {
|
|
||||||
beauty_seek_bar.min = 0
|
|
||||||
beauty_seek_bar.max = 100
|
|
||||||
beauty_seek_bar.progress = (value * 100 / range).toInt()
|
|
||||||
}
|
|
||||||
beauty_seek_bar.visibility = View.VISIBLE
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新单项是否为基准值显示
|
|
||||||
*/
|
|
||||||
private fun updateBeautyItemUI(viewHolder: BaseViewHolder?, item: FaceBeautyBean) {
|
|
||||||
val value = mDataFactory.getParamIntensity(item.key)
|
|
||||||
val stand = mModelAttributeRange[item.key]!!.stand
|
|
||||||
if (DecimalUtils.doubleEquals(value, stand)) {
|
|
||||||
viewHolder?.setImageResource(R.id.iv_control, item.closeRes)
|
|
||||||
} else {
|
|
||||||
viewHolder?.setImageResource(R.id.iv_control, item.openRes)
|
|
||||||
}
|
|
||||||
mBeautyAdapter.notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重置还原按钮状态
|
|
||||||
*/
|
|
||||||
private fun setRecoverFaceSkinEnable(enable: Boolean) {
|
|
||||||
if (enable) {
|
|
||||||
tv_beauty_recover.alpha = 1f
|
|
||||||
iv_beauty_recover.alpha = 1f
|
|
||||||
} else {
|
|
||||||
tv_beauty_recover.alpha = 0.6f
|
|
||||||
iv_beauty_recover.alpha = 0.6f
|
|
||||||
}
|
|
||||||
lyt_beauty_recover.isEnabled = enable
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 遍历美肤数据确认还原按钮是否可以点击
|
|
||||||
*/
|
|
||||||
private fun checkFaceSkinChanged(): Boolean {
|
|
||||||
val item = mSkinBeauty[mSkinIndex]
|
|
||||||
var value = mDataFactory.getParamIntensity(item.key)
|
|
||||||
var default = mModelAttributeRange[item.key]!!.default
|
|
||||||
if (!DecimalUtils.doubleEquals(value, default)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
mSkinBeauty.forEach {
|
|
||||||
value = mDataFactory.getParamIntensity(it.key)
|
|
||||||
default = mModelAttributeRange[it.key]!!.default
|
|
||||||
if (!DecimalUtils.doubleEquals(value, default)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 遍历美型数据确认还原按钮是否可以点击
|
|
||||||
*/
|
|
||||||
private fun checkFaceShapeChanged(): Boolean {
|
|
||||||
if (checkFaceShapeChanged(mShapeBeauty) || checkFaceShapeChanged(mShapeBeautySubItem))
|
|
||||||
return true
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 遍历美型数据确认还原按钮是否可以点击
|
|
||||||
*/
|
|
||||||
private fun checkFaceShapeChanged(shapeBeauty: ArrayList<FaceBeautyBean>): Boolean {
|
|
||||||
var value: Double
|
|
||||||
var default: Double
|
|
||||||
if (shapeBeauty.size > mShapeIndex) {
|
|
||||||
var item = shapeBeauty[mShapeIndex]
|
|
||||||
item?.let {
|
|
||||||
value = mDataFactory.getParamIntensity(item.key)
|
|
||||||
default = mModelAttributeRange[item.key]!!.default
|
|
||||||
if (!DecimalUtils.doubleEquals(value, default)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shapeBeauty.forEach {
|
|
||||||
when (it.buttonType) {
|
|
||||||
FaceBeautyBean.ButtonType.NORMAL_BUTTON -> {
|
|
||||||
value = mDataFactory.getParamIntensity(it.key)
|
|
||||||
default = mModelAttributeRange[it.key]!!.default
|
|
||||||
if (!DecimalUtils.doubleEquals(value, default)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 还原 美型、美肤数据
|
|
||||||
*/
|
|
||||||
private fun recoverData() {
|
|
||||||
when (beauty_radio_group.checkedCheckBoxId) {
|
|
||||||
R.id.beauty_radio_skin_beauty -> {
|
|
||||||
mSkinBeauty.forEach {
|
|
||||||
val default = mModelAttributeRange[it.key]!!.default
|
|
||||||
mDataFactory.updateParamIntensity(it.key, default)
|
|
||||||
}
|
|
||||||
val item = mSkinBeauty[mSkinIndex]
|
|
||||||
val value = mDataFactory.getParamIntensity(item.key)
|
|
||||||
val stand = mModelAttributeRange[item.key]!!.stand
|
|
||||||
val maxRange = mModelAttributeRange[item.key]!!.maxRange
|
|
||||||
seekToSeekBar(value, stand, maxRange)
|
|
||||||
mBeautyAdapter.notifyDataSetChanged()
|
|
||||||
setRecoverFaceSkinEnable(false)
|
|
||||||
}
|
|
||||||
R.id.beauty_radio_face_shape -> {
|
|
||||||
//还原主项和子项
|
|
||||||
mShapeBeauty.forEach {
|
|
||||||
when (it.buttonType) {
|
|
||||||
FaceBeautyBean.ButtonType.NORMAL_BUTTON -> {
|
|
||||||
val default = mModelAttributeRange[it.key]!!.default
|
|
||||||
mDataFactory.updateParamIntensity(it.key, default)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//还原子项
|
|
||||||
mShapeBeautySubItem.forEach {
|
|
||||||
when (it.buttonType) {
|
|
||||||
FaceBeautyBean.ButtonType.NORMAL_BUTTON -> {
|
|
||||||
val default = mModelAttributeRange[it.key]!!.default
|
|
||||||
mDataFactory.updateParamIntensity(it.key, default)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取当前shapeAdapter中被选中的项
|
|
||||||
var value = 0.0
|
|
||||||
var stand = 0.0
|
|
||||||
var maxRange = 1.0
|
|
||||||
if (mShapeIndex > 0) {
|
|
||||||
val item = mBeautyAdapter.getData(mShapeIndex)
|
|
||||||
when (item.buttonType) {
|
|
||||||
FaceBeautyBean.ButtonType.NORMAL_BUTTON -> {
|
|
||||||
value = mDataFactory.getParamIntensity(item.key)
|
|
||||||
stand = mModelAttributeRange[item.key]!!.stand
|
|
||||||
maxRange = mModelAttributeRange[item.key]!!.maxRange
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
seekToSeekBar(value, stand, maxRange)
|
|
||||||
mBeautyAdapter.notifyDataSetChanged()
|
|
||||||
setRecoverFaceSkinEnable(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 底部动画处理
|
|
||||||
* @param isOpen Boolean
|
|
||||||
*/
|
|
||||||
private fun changeBottomLayoutAnimator(isOpen: Boolean) {
|
|
||||||
if (isBottomShow == isOpen) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val start = if (isOpen) resources.getDimension(R.dimen.x1).toInt() else resources.getDimension(R.dimen.x268).toInt()
|
|
||||||
val end = if (isOpen) resources.getDimension(R.dimen.x268).toInt() else resources.getDimension(R.dimen.x1).toInt()
|
|
||||||
|
|
||||||
if (bottomLayoutAnimator != null && bottomLayoutAnimator!!.isRunning) {
|
|
||||||
bottomLayoutAnimator!!.end()
|
|
||||||
}
|
|
||||||
bottomLayoutAnimator = ValueAnimator.ofInt(start, end).setDuration(150)
|
|
||||||
bottomLayoutAnimator!!.addUpdateListener { animation ->
|
|
||||||
val height = animation.animatedValue as Int
|
|
||||||
val params = fyt_bottom_view.layoutParams as LinearLayout.LayoutParams
|
|
||||||
params.height = height
|
|
||||||
fyt_bottom_view.layoutParams = params
|
|
||||||
if (onBottomAnimatorChangeListener != null) {
|
|
||||||
val showRate = 1.0f * (height - start) / (end - start)
|
|
||||||
onBottomAnimatorChangeListener?.onBottomAnimatorChangeListener(if (!isOpen) 1 - showRate else showRate)
|
|
||||||
}
|
|
||||||
if (DecimalUtils.floatEquals(animation.animatedFraction, 1.0f) && isOpen) {
|
|
||||||
iv_compare.visibility = View.VISIBLE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bottomLayoutAnimator!!.start()
|
|
||||||
isBottomShow = isOpen
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDetachedFromWindow() {
|
|
||||||
//被销毁前,记录此时的UI值,用于下一次启动的时候恢复
|
|
||||||
mSubItemUIValueCache.forEach {
|
|
||||||
//应该要将UI值保存用于后续恢复
|
|
||||||
|
|
||||||
}
|
|
||||||
super.onDetachedFromWindow()
|
|
||||||
}
|
|
||||||
|
|
||||||
/* item入场动画总开关 */
|
|
||||||
val openEnterAnimation = false
|
|
||||||
|
|
||||||
/* 是否需要对该子项进行入场动画 */
|
|
||||||
var needEnterAnimation = false
|
|
||||||
|
|
||||||
/**
|
|
||||||
* recycleView ITEM 子项入场动画
|
|
||||||
*/
|
|
||||||
fun enterAnimation(view:View){
|
|
||||||
//动画集合
|
|
||||||
val animSet = AnimationSet(false)
|
|
||||||
//位移动画
|
|
||||||
val translateAnim = TranslateAnimation(
|
|
||||||
Animation.ABSOLUTE, 0f, Animation.ABSOLUTE, 0f,
|
|
||||||
Animation.ABSOLUTE, 100f, Animation.ABSOLUTE, 0f)
|
|
||||||
//渐变动画
|
|
||||||
val alphaAnim = AlphaAnimation(0.0f, 1.0f)
|
|
||||||
animSet.addAnimation(translateAnim)
|
|
||||||
animSet.addAnimation(alphaAnim)
|
|
||||||
animSet.duration = 300
|
|
||||||
animSet.fillAfter = true
|
|
||||||
animSet.addAnimation(alphaAnim)
|
|
||||||
view.startAnimation(animSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否展示还原按钮
|
|
||||||
*/
|
|
||||||
fun setResetButton(isVisible:Boolean) {
|
|
||||||
if (isVisible)
|
|
||||||
iv_reset.visibility = View.VISIBLE
|
|
||||||
else
|
|
||||||
iv_reset.visibility = View.GONE
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,102 +0,0 @@
|
|||||||
package com.yunbao.faceunity.control;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
|
|
||||||
import com.yunbao.faceunity.R;
|
|
||||||
import com.yunbao.faceunity.base.BaseDelegate;
|
|
||||||
import com.yunbao.faceunity.base.BaseListAdapter;
|
|
||||||
import com.yunbao.faceunity.base.BaseViewHolder;
|
|
||||||
import com.yunbao.faceunity.entity.PropBean;
|
|
||||||
import com.yunbao.faceunity.infe.AbstractPropDataFactory;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DESC:贴图、AR面具
|
|
||||||
* Created on 2021/4/26
|
|
||||||
*/
|
|
||||||
public class PropControlView extends BaseControlView {
|
|
||||||
|
|
||||||
private AbstractPropDataFactory mDataFactory;
|
|
||||||
private BaseListAdapter<PropBean> mPropAdapter;
|
|
||||||
|
|
||||||
private RecyclerView recyclerView;
|
|
||||||
|
|
||||||
public PropControlView(@NonNull Context context) {
|
|
||||||
super(context);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropControlView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropControlView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
|
||||||
super(context, attrs, defStyleAttr);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// region init
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
LayoutInflater.from(mContext).inflate(R.layout.layout_effect_control, this);
|
|
||||||
initView();
|
|
||||||
initAdapter();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 给控制绑定 EffectController,数据工厂
|
|
||||||
*
|
|
||||||
* @param dataFactory IFaceBeautyDataFactory
|
|
||||||
*/
|
|
||||||
public void bindDataFactory(AbstractPropDataFactory dataFactory) {
|
|
||||||
mDataFactory = dataFactory;
|
|
||||||
mPropAdapter.setData(dataFactory.getPropBeans());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* View初始化
|
|
||||||
*/
|
|
||||||
private void initView() {
|
|
||||||
recyclerView = findViewById(R.id.recycler_view);
|
|
||||||
initHorizontalRecycleView(recyclerView);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapter初始化
|
|
||||||
*/
|
|
||||||
private void initAdapter() {
|
|
||||||
mPropAdapter = new BaseListAdapter<>(new ArrayList<>(), new BaseDelegate<PropBean>() {
|
|
||||||
@Override
|
|
||||||
public void convert(int viewType, BaseViewHolder helper, PropBean data, int position) {
|
|
||||||
helper.setImageResource(R.id.iv_control, data.getIconId());
|
|
||||||
helper.itemView.setSelected(position == mDataFactory.getCurrentPropIndex());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemClickListener(View view, PropBean data, int position) {
|
|
||||||
if (mDataFactory.getCurrentPropIndex() != position) {
|
|
||||||
changeAdapterSelected(mPropAdapter, mDataFactory.getCurrentPropIndex(), position);
|
|
||||||
mDataFactory.setCurrentPropIndex(position);
|
|
||||||
mDataFactory.onItemSelected(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}, R.layout.list_item_control_image_circle);
|
|
||||||
recyclerView.setAdapter(mPropAdapter);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// endregion
|
|
||||||
}
|
|
@ -29,6 +29,6 @@ public class FaceParam {
|
|||||||
// 占位符,以下均未使用
|
// 占位符,以下均未使用
|
||||||
public static final int FACE_ANIM_AR_MASK=900;
|
public static final int FACE_ANIM_AR_MASK=900;
|
||||||
public static final int FACE_EXPRESSION_RECOGNITION=1000;
|
public static final int FACE_EXPRESSION_RECOGNITION=1000;
|
||||||
public static final int FACE_FACE_WARP=1000;
|
public static final int FACE_FACE_WARP=1100;
|
||||||
public static final int FACE_GESTURE_RECOGNITION=1100;
|
public static final int FACE_GESTURE_RECOGNITION=1200;
|
||||||
}
|
}
|
||||||
|
@ -1,94 +0,0 @@
|
|||||||
package com.yunbao.faceunity.dialog;
|
|
||||||
|
|
||||||
import android.app.Dialog;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.Window;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.fragment.app.DialogFragment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Richie on 2018.09.19
|
|
||||||
*/
|
|
||||||
public abstract class BaseDialogFragment extends DialogFragment {
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
|
|
||||||
View dialogView = createDialogView(inflater, container);
|
|
||||||
getDialog().setCanceledOnTouchOutside(false);//点击屏幕不消失
|
|
||||||
getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() {//点击返回键不消失
|
|
||||||
@Override
|
|
||||||
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
|
||||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
initWindowParams();
|
|
||||||
return dialogView;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建 dialog view
|
|
||||||
*
|
|
||||||
* @param inflater
|
|
||||||
* @param container
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
protected abstract View createDialogView(LayoutInflater inflater, @Nullable ViewGroup container);
|
|
||||||
|
|
||||||
protected int getDialogWidth() {
|
|
||||||
return WindowManager.LayoutParams.WRAP_CONTENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected int getDialogHeight() {
|
|
||||||
return WindowManager.LayoutParams.WRAP_CONTENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initWindowParams() {
|
|
||||||
Dialog dialog = getDialog();
|
|
||||||
if (dialog != null) {
|
|
||||||
|
|
||||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
|
||||||
Window window = dialog.getWindow();
|
|
||||||
if (window != null) {
|
|
||||||
window.getDecorView().setPadding(0, 0, 0, 0);
|
|
||||||
window.setBackgroundDrawableResource(android.R.color.transparent);
|
|
||||||
WindowManager.LayoutParams windowAttributes = window.getAttributes();
|
|
||||||
windowAttributes.gravity = Gravity.CENTER;
|
|
||||||
windowAttributes.width = getDialogWidth();
|
|
||||||
windowAttributes.height = getDialogHeight();
|
|
||||||
window.setAttributes(windowAttributes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface OnClickListener {
|
|
||||||
/**
|
|
||||||
* 确认
|
|
||||||
*/
|
|
||||||
void onConfirm();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 取消
|
|
||||||
*/
|
|
||||||
void onCancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface OnDismissListener {
|
|
||||||
/**
|
|
||||||
* 消失
|
|
||||||
*/
|
|
||||||
void onDismiss();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,105 +0,0 @@
|
|||||||
package com.yunbao.faceunity.dialog;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.yunbao.faceunity.R;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 确认对话框
|
|
||||||
*
|
|
||||||
* @author Richie on 2018.08.28
|
|
||||||
*/
|
|
||||||
public class ConfirmDialogFragment extends BaseDialogFragment {
|
|
||||||
private static final String TITLE = "content";
|
|
||||||
private static final String CONFIRM = "confirm";
|
|
||||||
private static final String CANCEL = "cancel";
|
|
||||||
private OnClickListener mOnClickListener;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建对话框
|
|
||||||
*
|
|
||||||
* @param title
|
|
||||||
* @param onClickListener
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static ConfirmDialogFragment newInstance(@NonNull String title, @NonNull OnClickListener onClickListener) {
|
|
||||||
ConfirmDialogFragment fragment = new ConfirmDialogFragment();
|
|
||||||
fragment.mOnClickListener = onClickListener;
|
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.putString(TITLE, title);
|
|
||||||
fragment.setArguments(bundle);
|
|
||||||
return fragment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ConfirmDialogFragment newInstance(@NonNull String title, @NonNull String confirmText,
|
|
||||||
@NonNull String cancelText, @NonNull OnClickListener onClickListener) {
|
|
||||||
ConfirmDialogFragment fragment = new ConfirmDialogFragment();
|
|
||||||
fragment.mOnClickListener = onClickListener;
|
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.putString(TITLE, title);
|
|
||||||
bundle.putString(CONFIRM, confirmText);
|
|
||||||
bundle.putString(CANCEL, cancelText);
|
|
||||||
fragment.setArguments(bundle);
|
|
||||||
return fragment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected View createDialogView(LayoutInflater inflater, @Nullable ViewGroup container) {
|
|
||||||
View view = inflater.inflate(R.layout.dialog_confirm, container, false);
|
|
||||||
View.OnClickListener onClickListener = new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
dismiss();
|
|
||||||
int id = v.getId();
|
|
||||||
if (id == R.id.tv_confirm) {
|
|
||||||
if (mOnClickListener != null) {
|
|
||||||
mOnClickListener.onConfirm();
|
|
||||||
}
|
|
||||||
} else if (id == R.id.tv_cancel) {
|
|
||||||
if (mOnClickListener != null) {
|
|
||||||
mOnClickListener.onCancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
String confirmTxt = getArguments().getString(CONFIRM);
|
|
||||||
TextView tvConfirm = view.findViewById(R.id.tv_confirm);
|
|
||||||
if (!TextUtils.isEmpty(confirmTxt)) {
|
|
||||||
tvConfirm.setText(confirmTxt);
|
|
||||||
}
|
|
||||||
String cancelTxt = getArguments().getString(CANCEL);
|
|
||||||
TextView tvCancel = view.findViewById(R.id.tv_cancel);
|
|
||||||
if (!TextUtils.isEmpty(cancelTxt)) {
|
|
||||||
tvCancel.setText(cancelTxt);
|
|
||||||
}
|
|
||||||
tvConfirm.setOnClickListener(onClickListener);
|
|
||||||
tvCancel.setOnClickListener(onClickListener);
|
|
||||||
String title = getArguments().getString(TITLE);
|
|
||||||
((TextView) view.findViewById(R.id.tv_content)).setText(title);
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getDialogWidth() {
|
|
||||||
return getResources().getDimensionPixelSize(R.dimen.x562);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getDialogHeight() {
|
|
||||||
return getResources().getDimensionPixelSize(R.dimen.x294);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnClickListener(OnClickListener onClickListener) {
|
|
||||||
mOnClickListener = onClickListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,117 +0,0 @@
|
|||||||
package com.yunbao.faceunity.dialog;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.util.TypedValue;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import androidx.annotation.StringRes;
|
|
||||||
|
|
||||||
|
|
||||||
import com.yunbao.faceunity.R;
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by tujh on 2018/6/28.
|
|
||||||
*/
|
|
||||||
public final class ToastHelper {
|
|
||||||
private static Toast sNormalToast;
|
|
||||||
private static Toast sWhiteTextToast;
|
|
||||||
private static WeakReference<Context> mWeakContext;
|
|
||||||
|
|
||||||
public static void showToast(Context context, String str) {
|
|
||||||
Toast toast = Toast.makeText(context, str, Toast.LENGTH_SHORT);
|
|
||||||
toast.setGravity(Gravity.CENTER, 0, 0);
|
|
||||||
toast.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void showToast(Context context, @StringRes int strId) {
|
|
||||||
showToast(context, context.getString(strId));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void showWhiteTextToast(Context context, @StringRes int strId) {
|
|
||||||
showWhiteTextToast(context, context.getString(strId));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void showNormalToast(Context context, @StringRes int strId) {
|
|
||||||
showNormalToast(context, context.getString(strId));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void dismissToast() {
|
|
||||||
dismissWhiteTextToast();
|
|
||||||
dismissNormalToast();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void dismissWhiteTextToast() {
|
|
||||||
if (sWhiteTextToast != null) {
|
|
||||||
sWhiteTextToast.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void dismissNormalToast() {
|
|
||||||
if (sNormalToast != null) {
|
|
||||||
sNormalToast.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void showWhiteTextToast(Context context, String text) {
|
|
||||||
if (mWeakContext != null && mWeakContext.get() == context && sWhiteTextToast != null) {
|
|
||||||
TextView view = (TextView) sWhiteTextToast.getView();
|
|
||||||
view.setText(text);
|
|
||||||
if (!view.isShown()) {
|
|
||||||
sWhiteTextToast.show();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mWeakContext = new WeakReference<>(context);
|
|
||||||
Resources resources = context.getResources();
|
|
||||||
TextView textView = new TextView(context);
|
|
||||||
textView.setTextColor(resources.getColor(R.color.colorWhite));
|
|
||||||
textView.setGravity(Gravity.CENTER);
|
|
||||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, resources.getDimension(R.dimen.x64));
|
|
||||||
textView.setText(text);
|
|
||||||
sWhiteTextToast = new Toast(context);
|
|
||||||
sWhiteTextToast.setView(textView);
|
|
||||||
sWhiteTextToast.setDuration(Toast.LENGTH_SHORT);
|
|
||||||
int yOffset = context.getResources().getDimensionPixelSize(R.dimen.x560);
|
|
||||||
sWhiteTextToast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP, 0, yOffset);
|
|
||||||
sWhiteTextToast.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void showNormalToast(Context context, String text) {
|
|
||||||
if (mWeakContext != null && mWeakContext.get() == context && sNormalToast != null) {
|
|
||||||
TextView view = (TextView) sNormalToast.getView();
|
|
||||||
view.setText(text);
|
|
||||||
if (!view.isShown()) {
|
|
||||||
sNormalToast.show();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mWeakContext = new WeakReference<>(context);
|
|
||||||
Resources resources = context.getResources();
|
|
||||||
TextView textView = new TextView(context);
|
|
||||||
textView.setTextColor(resources.getColor(R.color.colorWhite));
|
|
||||||
textView.setGravity(Gravity.CENTER);
|
|
||||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, resources.getDimension(R.dimen.x26));
|
|
||||||
textView.setBackgroundResource(R.drawable.bg_toast_more);
|
|
||||||
int hPadding = resources.getDimensionPixelSize(R.dimen.x28);
|
|
||||||
int vPadding = resources.getDimensionPixelSize(R.dimen.x16);
|
|
||||||
textView.setPadding(hPadding, vPadding, hPadding, vPadding);
|
|
||||||
textView.setText(text);
|
|
||||||
sNormalToast = new Toast(context);
|
|
||||||
sNormalToast.setView(textView);
|
|
||||||
sNormalToast.setDuration(Toast.LENGTH_SHORT);
|
|
||||||
int yOffset = context.getResources().getDimensionPixelSize(R.dimen.x182);
|
|
||||||
sNormalToast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP, 0, yOffset);
|
|
||||||
sNormalToast.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
package com.yunbao.faceunity.listener;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DESC:底部菜单动画回调
|
|
||||||
* Created on 2021/4/26
|
|
||||||
*/
|
|
||||||
public interface OnBottomAnimatorChangeListener {
|
|
||||||
void onBottomAnimatorChangeListener(float showRate);
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package com.yunbao.faceunity.listener;
|
|
||||||
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DESC:
|
|
||||||
* Created on 2021/4/26
|
|
||||||
*/
|
|
||||||
public abstract class OnMultiClickListener implements OnClickListener {
|
|
||||||
private long mLastClickTime = 0L;
|
|
||||||
private int mViewId = View.NO_ID;
|
|
||||||
private static long MIN_CLICK_DELAY_TIME = 500L;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
long curClickTime = System.currentTimeMillis();
|
|
||||||
int viewId = v.getId();
|
|
||||||
if (mViewId == viewId) {
|
|
||||||
if (curClickTime - mLastClickTime >= MIN_CLICK_DELAY_TIME) {
|
|
||||||
mLastClickTime = curClickTime;
|
|
||||||
onMultiClick(v);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mViewId = viewId;
|
|
||||||
mLastClickTime = curClickTime;
|
|
||||||
onMultiClick(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理后的点击事件
|
|
||||||
*
|
|
||||||
* @param v
|
|
||||||
*/
|
|
||||||
protected abstract void onMultiClick(View v);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
package com.yunbao.faceunity.model;
|
|
||||||
|
|
||||||
|
|
||||||
import com.faceunity.core.entity.FUBundleData;
|
|
||||||
import com.faceunity.core.faceunity.FURenderKit;
|
|
||||||
import com.faceunity.core.model.facebeauty.FaceBeauty;
|
|
||||||
import com.yunbao.faceunity.listener.IFaceModel;
|
|
||||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 美颜模块
|
|
||||||
*/
|
|
||||||
public class FaceBeautyModel extends IFaceModel<FaceBeauty> {
|
|
||||||
|
|
||||||
private FaceBeauty beauty;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造美颜模块
|
|
||||||
* 参考配置:https://gitee.com/hangzhou_xiangxin_1/FULiveDemoDroid/blob/master/doc/4.%E7%BE%8E%E9%A2%9C.md
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public FaceBeauty Builder() {
|
|
||||||
beauty = new FaceBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_BEAUTIFICATION));
|
|
||||||
return beauty;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 应用美颜
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void apply() {
|
|
||||||
super.apply();
|
|
||||||
FURenderKit kit = FURenderKit.getInstance();
|
|
||||||
kit.setFaceBeauty(beauty);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setEnable(boolean enable) {
|
|
||||||
beauty.setEnable(enable);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
package com.yunbao.faceunity.repo;
|
|
||||||
|
|
||||||
public class FineStickerSource {
|
|
||||||
|
|
||||||
}
|
|
@ -77,19 +77,9 @@ public class FaceUnityView extends LinearLayout implements StickerDownloadHelper
|
|||||||
private void init() {
|
private void init() {
|
||||||
LayoutInflater.from(mContext).inflate(R.layout.layout_faceunity, this);
|
LayoutInflater.from(mContext).inflate(R.layout.layout_faceunity, this);
|
||||||
initView();
|
initView();
|
||||||
bindBottomView();
|
|
||||||
FineStickerDataFactory.getInstance().addCallback(this);
|
FineStickerDataFactory.getInstance().addCallback(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 绑定数据工厂
|
|
||||||
*
|
|
||||||
* @param dataFactory FaceUnityDataFactory
|
|
||||||
*/
|
|
||||||
public void bindDataFactory(FaceUnityDataFactory dataFactory) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化View
|
* 初始化View
|
||||||
*/
|
*/
|
||||||
@ -111,6 +101,9 @@ public class FaceUnityView extends LinearLayout implements StickerDownloadHelper
|
|||||||
initViewClick();
|
initViewClick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化配置点击事件
|
||||||
|
*/
|
||||||
private void initViewClick() {
|
private void initViewClick() {
|
||||||
menu2Back.setOnClickListener(v -> {
|
menu2Back.setOnClickListener(v -> {
|
||||||
Object tag = menu2Back.getTag();
|
Object tag = menu2Back.getTag();
|
||||||
@ -138,6 +131,9 @@ public class FaceUnityView extends LinearLayout implements StickerDownloadHelper
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回到默认界面
|
||||||
|
*/
|
||||||
private void goBackMainMenu() {
|
private void goBackMainMenu() {
|
||||||
setContainerRecycler(new ArrayList<>());
|
setContainerRecycler(new ArrayList<>());
|
||||||
title.setText("美顏特效選擇");
|
title.setText("美顏特效選擇");
|
||||||
@ -147,23 +143,9 @@ public class FaceUnityView extends LinearLayout implements StickerDownloadHelper
|
|||||||
menuDiy.setVisibility(GONE);
|
menuDiy.setVisibility(GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 底部功能菜单切换
|
* 配置主菜单
|
||||||
*/
|
*/
|
||||||
private void bindBottomView() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UI菜单显示控制
|
|
||||||
*
|
|
||||||
* @param index Int
|
|
||||||
*/
|
|
||||||
private void showFunction(int index) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initMenuGroup() {
|
private void initMenuGroup() {
|
||||||
MenuGroupRecyclerAdapter adapter = new MenuGroupRecyclerAdapter(mContext);
|
MenuGroupRecyclerAdapter adapter = new MenuGroupRecyclerAdapter(mContext);
|
||||||
menuGroup.setLayoutManager(new GridLayoutManager(mContext, 4));
|
menuGroup.setLayoutManager(new GridLayoutManager(mContext, 4));
|
||||||
@ -228,6 +210,9 @@ public class FaceUnityView extends LinearLayout implements StickerDownloadHelper
|
|||||||
menuGroup.setAdapter(adapter);
|
menuGroup.setAdapter(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建Tab
|
||||||
|
*/
|
||||||
private List<TabLayout.Tab> createTabs(Map<Integer, Integer> map) {
|
private List<TabLayout.Tab> createTabs(Map<Integer, Integer> map) {
|
||||||
List<TabLayout.Tab> list = new ArrayList<>();
|
List<TabLayout.Tab> list = new ArrayList<>();
|
||||||
for (Integer key : map.keySet()) {
|
for (Integer key : map.keySet()) {
|
||||||
@ -238,6 +223,9 @@ public class FaceUnityView extends LinearLayout implements StickerDownloadHelper
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建菜单
|
||||||
|
*/
|
||||||
private List<TabLayout.Tab> createTabs(List<FineStickerTagEntity> tags) {
|
private List<TabLayout.Tab> createTabs(List<FineStickerTagEntity> tags) {
|
||||||
List<TabLayout.Tab> list = new ArrayList<>();
|
List<TabLayout.Tab> list = new ArrayList<>();
|
||||||
for (FineStickerTagEntity tag : tags) {
|
for (FineStickerTagEntity tag : tags) {
|
||||||
@ -253,6 +241,9 @@ public class FaceUnityView extends LinearLayout implements StickerDownloadHelper
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建菜单
|
||||||
|
*/
|
||||||
private List<TabLayout.Tab> createTabs(ArrayList<MakeupCustomClassBean> tags) {
|
private List<TabLayout.Tab> createTabs(ArrayList<MakeupCustomClassBean> tags) {
|
||||||
List<TabLayout.Tab> list = new ArrayList<>();
|
List<TabLayout.Tab> list = new ArrayList<>();
|
||||||
for (MakeupCustomClassBean tag : tags) {
|
for (MakeupCustomClassBean tag : tags) {
|
||||||
@ -264,6 +255,9 @@ public class FaceUnityView extends LinearLayout implements StickerDownloadHelper
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置菜单
|
||||||
|
*/
|
||||||
private void setTab(List<TabLayout.Tab> tabs) {
|
private void setTab(List<TabLayout.Tab> tabs) {
|
||||||
tabLayout.removeAllTabs();
|
tabLayout.removeAllTabs();
|
||||||
for (TabLayout.Tab tab : tabs) {
|
for (TabLayout.Tab tab : tabs) {
|
||||||
@ -367,10 +361,18 @@ public class FaceUnityView extends LinearLayout implements StickerDownloadHelper
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置美颜选项配置行数,图标为5个,拖动条为2个
|
||||||
|
* @param count
|
||||||
|
*/
|
||||||
private void changeRecyclerItemCount(int count) {
|
private void changeRecyclerItemCount(int count) {
|
||||||
containerRecycler.setLayoutManager(new GridLayoutManager(mContext, count));
|
containerRecycler.setLayoutManager(new GridLayoutManager(mContext, count));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置美颜Recycler内容
|
||||||
|
* @param list
|
||||||
|
*/
|
||||||
private void setContainerRecycler(ArrayList<? extends BaseBean> list) {
|
private void setContainerRecycler(ArrayList<? extends BaseBean> list) {
|
||||||
if (containerAdapter == null) {
|
if (containerAdapter == null) {
|
||||||
containerAdapter = new ContainerRecyclerAdapter(mContext);
|
containerAdapter = new ContainerRecyclerAdapter(mContext);
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
package com.yunbao.faceunity.utils;
|
|
||||||
|
|
||||||
import com.faceunity.core.entity.FUCameraConfig;
|
|
||||||
|
|
||||||
public class FaceCameraConfig {
|
|
||||||
/**
|
|
||||||
* 默认相机配置
|
|
||||||
*/
|
|
||||||
public static FUCameraConfig getDefFUCameraConfig(){
|
|
||||||
return new FUCameraConfig();
|
|
||||||
}
|
|
||||||
}
|
|
@ -23,6 +23,10 @@ class SeekBarUtils {
|
|||||||
}
|
}
|
||||||
bar.visibility = View.VISIBLE
|
bar.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换成滚动条的值
|
||||||
|
*/
|
||||||
fun seekToValue(range:Double,value:Int,seekBarMin:Int):Double{
|
fun seekToValue(range:Double,value:Int,seekBarMin:Int):Double{
|
||||||
val valueF: Double = 1.0 * (value - seekBarMin) / 100
|
val valueF: Double = 1.0 * (value - seekBarMin) / 100
|
||||||
return range*valueF;
|
return range*valueF;
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package com.shayu.phonelive.activity;
|
package com.shayu.phonelive.activity;
|
||||||
|
|
||||||
|
import static com.yunbao.common.CommonAppContext.logger;
|
||||||
|
import static com.yunbao.common.CommonAppContext.mFirebaseAnalytics;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@ -32,17 +35,14 @@ import com.tencent.rtmp.ui.TXCloudVideoView;
|
|||||||
import com.tencent.ugc.TXUGCBase;
|
import com.tencent.ugc.TXUGCBase;
|
||||||
import com.yunbao.common.CommonAppConfig;
|
import com.yunbao.common.CommonAppConfig;
|
||||||
import com.yunbao.common.Constants;
|
import com.yunbao.common.Constants;
|
||||||
import com.yunbao.common.activity.WebViewActivity;
|
|
||||||
import com.yunbao.common.bean.AdBean;
|
import com.yunbao.common.bean.AdBean;
|
||||||
import com.yunbao.common.bean.ConfigBean;
|
import com.yunbao.common.bean.ConfigBean;
|
||||||
import com.yunbao.common.bean.IMLoginModel;
|
import com.yunbao.common.bean.IMLoginModel;
|
||||||
import com.yunbao.common.bean.UserBean;
|
|
||||||
import com.yunbao.common.custom.CircleProgress;
|
import com.yunbao.common.custom.CircleProgress;
|
||||||
import com.yunbao.common.event.DataUserInfoEvent;
|
import com.yunbao.common.event.DataUserInfoEvent;
|
||||||
import com.yunbao.common.glide.ImgLoader;
|
import com.yunbao.common.glide.ImgLoader;
|
||||||
import com.yunbao.common.http.CommonHttpConsts;
|
import com.yunbao.common.http.CommonHttpConsts;
|
||||||
import com.yunbao.common.http.CommonHttpUtil;
|
import com.yunbao.common.http.CommonHttpUtil;
|
||||||
import com.yunbao.common.http.HttpCallback;
|
|
||||||
import com.yunbao.common.interfaces.CommonCallback;
|
import com.yunbao.common.interfaces.CommonCallback;
|
||||||
import com.yunbao.common.manager.IMLoginManager;
|
import com.yunbao.common.manager.IMLoginManager;
|
||||||
import com.yunbao.common.manager.imrongcloud.RongcloudIMManager;
|
import com.yunbao.common.manager.imrongcloud.RongcloudIMManager;
|
||||||
@ -53,19 +53,11 @@ import com.yunbao.common.utils.RouteUtil;
|
|||||||
import com.yunbao.common.utils.SpUtil;
|
import com.yunbao.common.utils.SpUtil;
|
||||||
import com.yunbao.common.utils.ToastUtil;
|
import com.yunbao.common.utils.ToastUtil;
|
||||||
import com.yunbao.common.utils.WordUtil;
|
import com.yunbao.common.utils.WordUtil;
|
||||||
import com.yunbao.faceunity.FaceManager;
|
|
||||||
import com.yunbao.live.activity.LiveAudienceActivity;
|
|
||||||
import com.yunbao.live.bean.LiveBean;
|
|
||||||
import com.yunbao.live.dialog.LiveFaceUnityDialogFragment;
|
|
||||||
import com.yunbao.live.http.LiveHttpUtil;
|
|
||||||
import com.yunbao.live.presenter.LiveRoomCheckLivePresenter;
|
|
||||||
import com.yunbao.live.views.LauncherAdViewHolder;
|
import com.yunbao.live.views.LauncherAdViewHolder;
|
||||||
import com.yunbao.main.activity.EntryActivity;
|
import com.yunbao.main.activity.EntryActivity;
|
||||||
import com.yunbao.main.activity.MainActivity;
|
import com.yunbao.main.activity.MainActivity;
|
||||||
import com.yunbao.main.activity.PDLiveConversationListActivity;
|
|
||||||
import com.yunbao.main.http.MainHttpConsts;
|
import com.yunbao.main.http.MainHttpConsts;
|
||||||
import com.yunbao.main.http.MainHttpUtil;
|
import com.yunbao.main.http.MainHttpUtil;
|
||||||
import com.yunbao.main.manager.imrongcloud.ConversationIMListManager;
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
@ -77,9 +69,6 @@ import java.util.List;
|
|||||||
|
|
||||||
import myname.pdlive.shayu.R;
|
import myname.pdlive.shayu.R;
|
||||||
|
|
||||||
import static com.yunbao.common.CommonAppContext.logger;
|
|
||||||
import static com.yunbao.common.CommonAppContext.mFirebaseAnalytics;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by cxf on 2018/9/17.
|
* Created by cxf on 2018/9/17.
|
||||||
*/
|
*/
|
||||||
|
@ -3,7 +3,6 @@ package com.yunbao.live.dialog;
|
|||||||
import android.app.ActionBar;
|
import android.app.ActionBar;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -13,8 +12,6 @@ import android.view.WindowManager;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.yunbao.common.dialog.AbsDialogFragment;
|
import com.yunbao.common.dialog.AbsDialogFragment;
|
||||||
import com.yunbao.common.utils.DpUtil;
|
|
||||||
import com.yunbao.common.utils.ToastUtil;
|
|
||||||
import com.yunbao.faceunity.FaceManager;
|
import com.yunbao.faceunity.FaceManager;
|
||||||
import com.yunbao.faceunity.ui.FaceUnityView;
|
import com.yunbao.faceunity.ui.FaceUnityView;
|
||||||
import com.yunbao.live.R;
|
import com.yunbao.live.R;
|
||||||
@ -63,7 +60,6 @@ public class LiveFaceUnityDialogFragment extends AbsDialogFragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||||
super.onActivityCreated(savedInstanceState);
|
super.onActivityCreated(savedInstanceState);
|
||||||
manager.bindControlView(faceView);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setManager(FaceManager manager) {
|
public void setManager(FaceManager manager) {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.yunbao.live.views;
|
package com.yunbao.live.views;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -35,7 +34,6 @@ import com.yunbao.common.utils.ToastUtil;
|
|||||||
import com.yunbao.common.utils.WordUtil;
|
import com.yunbao.common.utils.WordUtil;
|
||||||
import com.yunbao.common.views.AbsViewHolder;
|
import com.yunbao.common.views.AbsViewHolder;
|
||||||
import com.yunbao.faceunity.FaceManager;
|
import com.yunbao.faceunity.FaceManager;
|
||||||
import com.yunbao.faceunity.ui.FaceUnityView;
|
|
||||||
import com.yunbao.live.R;
|
import com.yunbao.live.R;
|
||||||
import com.yunbao.live.activity.LiveActivity;
|
import com.yunbao.live.activity.LiveActivity;
|
||||||
import com.yunbao.live.activity.LiveRyAnchorActivity;
|
import com.yunbao.live.activity.LiveRyAnchorActivity;
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package com.yunbao.main.activity;
|
package com.yunbao.main.activity;
|
||||||
|
|
||||||
|
import static com.yunbao.common.CommonAppContext.isReady;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
@ -84,11 +86,8 @@ import com.yunbao.common.utils.VersionUtil;
|
|||||||
import com.yunbao.common.utils.WordUtil;
|
import com.yunbao.common.utils.WordUtil;
|
||||||
import com.yunbao.common.views.AbsMainViewHolder;
|
import com.yunbao.common.views.AbsMainViewHolder;
|
||||||
import com.yunbao.common.views.weight.ViewClicksAntiShake;
|
import com.yunbao.common.views.weight.ViewClicksAntiShake;
|
||||||
import com.yunbao.faceunity.FaceManager;
|
|
||||||
import com.yunbao.live.activity.LiveAudienceActivity;
|
import com.yunbao.live.activity.LiveAudienceActivity;
|
||||||
import com.yunbao.live.activity.LiveRyAnchorActivity;
|
|
||||||
import com.yunbao.live.bean.LiveBean;
|
import com.yunbao.live.bean.LiveBean;
|
||||||
import com.yunbao.live.dialog.LiveFaceUnityDialogFragment;
|
|
||||||
import com.yunbao.live.http.LiveHttpConsts;
|
import com.yunbao.live.http.LiveHttpConsts;
|
||||||
import com.yunbao.live.http.LiveHttpUtil;
|
import com.yunbao.live.http.LiveHttpUtil;
|
||||||
import com.yunbao.live.presenter.LiveRoomCheckLivePresenter;
|
import com.yunbao.live.presenter.LiveRoomCheckLivePresenter;
|
||||||
@ -139,8 +138,6 @@ import io.rong.push.PushManager;
|
|||||||
import io.rong.push.PushType;
|
import io.rong.push.PushType;
|
||||||
import kotlin.Unit;
|
import kotlin.Unit;
|
||||||
|
|
||||||
import static com.yunbao.common.CommonAppContext.isReady;
|
|
||||||
|
|
||||||
@Route(path = RouteUtil.PATH_MAIN)
|
@Route(path = RouteUtil.PATH_MAIN)
|
||||||
public class MainActivity extends AbsActivity implements MainAppBarLayoutListener {
|
public class MainActivity extends AbsActivity implements MainAppBarLayoutListener {
|
||||||
|
|
||||||
@ -567,11 +564,6 @@ public class MainActivity extends AbsActivity implements MainAppBarLayoutListene
|
|||||||
// findViewById(R.id.banner_click).setVisibility(View.VISIBLE);
|
// findViewById(R.id.banner_click).setVisibility(View.VISIBLE);
|
||||||
isfloatBannernet = true;
|
isfloatBannernet = true;
|
||||||
initAnchorRecommendBanner();
|
initAnchorRecommendBanner();
|
||||||
FaceManager manager = new FaceManager();
|
|
||||||
manager.initFURender(mContext);
|
|
||||||
LiveFaceUnityDialogFragment fragment = new LiveFaceUnityDialogFragment(mContext);
|
|
||||||
fragment.setManager(manager);
|
|
||||||
fragment.show(((MainActivity) mContext).getSupportFragmentManager(), "FaceUnity");
|
|
||||||
} else {
|
} else {
|
||||||
floatBanner.setVisibility(View.GONE);
|
floatBanner.setVisibility(View.GONE);
|
||||||
findViewById(R.id.banner_click).setVisibility(View.GONE);
|
findViewById(R.id.banner_click).setVisibility(View.GONE);
|
||||||
|
Loading…
Reference in New Issue
Block a user